美文网首页
MySQL之JDBC(重点)

MySQL之JDBC(重点)

作者: 小铮冲冲冲 | 来源:发表于2021-02-03 18:36 被阅读0次

    十、JDBC(重点)

    参考链接:https://www.jianshu.com/p/0f015c6ecd07

    1.数据库驱动

    驱动:声卡、显卡以及数据库等都需要驱动。

    image

    程序会通过数据库驱动,和数据库打交道。

    2.JDBC

    SUN公司为了简化开发人员的(对数据库的统一)操作,提供了一个(java操作数据库的)规范,俗称JDBC。
    这些规范的实现由具体的厂商去做。
    对于开发人员来说只需要掌握JDBC接口的即可。

    image

    编写时需要用到两个包:java.sql和javax.sql,在java中默认就有。
    还需要导入一个数据库驱动包:mysql-connector-java-5.1.47.jar。
    mysql-connector-java下载地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java

    image

    3.第一个JDBC程序

    1)创建一个普通项目
    创建测试数据库jdbcstudy和表user并插入数据,可下载使用:https://share.weiyun.com/L8nRqipC,也可以直接复制下方。

    CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
    USE jdbcStudy;
    CREATE TABLE `users`(
      id INT PRIMARY KEY,
      NAME VARCHAR(40),
      PASSWORD VARCHAR(40),
      email VARCHAR(60),
      birthday DATE
    );
    INSERT INTO `users`(id,NAME,PASSWORD,email,birthday)
    VALUES(1,'zhansan','123456','zs@sina.com','1980-12-04'),
    (2,'lisi','123456','lisi@sina.com','1981-12-04'),
    (3,'wangwu','123456','wangwu@sina.com','1979-12-04')
    
    

    打开IDEA——>选择Create New Project——>选择Java——>Next——>Next——>填写项目地址和名称,点击Finish

    image image image image

    2)导入数据库驱动
    ①右击项目,在其下新建一个lib目录。

    image

    ②将jar包拷入到lib目录下。

    image

    ③右击lib——>选择Add as Library…——>OK

    image

    3)编写测试代码

    package demo;
    import java.sql.*;
    public class Demo {
      public static void main(String[] args) throws ClassNotFoundException,SQLException {
        //1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动
        //2.用户信息和url
        String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&&useSSL=true";
        String username = "root";
        String password = "123456";
        //3.连接成功,连接数据库对象 Connection
        Connection connection = DriverManager.getConnection(url,username,password);
        //4.执行SQL对象 Statement
        Statement statement = connection.createStatement();
        //5.执行SQL可能存在的结果,查看返回的结果
        String sql = "SELECT * FROM user";
        ResultSet resultSet = statement.executeQuery(sql);//返回的结果集,封装了查询出来的全部结果
        while(resultSet.next()) {
          System.out.println("id="+resultSet.getObject("id"));
          System.out.println("name="+resultSet.getObject("NAME"));
          System.out.println("pwd="+resultSet.getObject("PASSWORD"));
          System.out.println("email="+resultSet.getObject("email"));
          System.out.println("birth="+resultSet.getObject("birthday"));
        }
        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();
      }
    }
    
    

    步骤总结:Ⅰ加载驱动。
    Ⅱ连接数据库 DriverManager
    Ⅲ获得执行sql的对象 Statement
    Ⅳ获得返回的结果集。
    Ⅴ释放连接。
    ①DriverManager
    注册驱动的原来写法:

    DriverManager.registerDriver(new com.mysql.jdbc.Driver());
    
    

    但不建议使用,因为注册了两次。
    推荐使用:

    Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动
    
    

    connection 代表数据库

    connection.rollback();//事务回滚
    connection.commit();//事务提交
    connection.setAutoCommit();//事务自动提交
    
    

    ②URL

    //协作://主机地址:端口号/数据库名?参数1&参数2&参数3
    String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&&useSSL=true";
    
    

    mysql的默认端口号是3306,oracle的默认端口号是1521。
    ③Statement执行SQL的对象、PreparedStatement执行SQL的对象

    String sql = "SELECT * FROM user";//正常情况下,前面就编写sql
    
    statement.executeQuery();//查询操作,返回结果集ResultSet
    statement.execute();//执行任何SQL
    statement.executeUpdate();//更新、插入、删除都用这个,返回一个受影响的行数
    
    

    ④ResultSet查询的结果集:封装了所有的查询结果。
    Ⅰ获得指定的数据类型

    resultSet.getObject();//在不知道列类型的情况下使用
    //如果知道列类型就使用指定的类型
    resultSet.getString();
    resultSet.getInt();
    resultSet.getFloat();
    resultSet.getDate();
    …
    
    

    Ⅱ遍历,指针

    resultSet.beforeFirst();//移动到最前面
    resultSet.afterLast();//移动到最后面
    resultSet.next();//移动到下一个数据
    resultSet.previous();//移动到前一行
    resultSet.absolute(row);//移动到指定行
    
    

    ⑤释放资源

    resultSet.close();
    statement.close();
    connection.close();//耗资源,用完关掉
    
    

    4.statement对象

    Jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查的语句即可。
    Statement对象的executeUpdate方法,用于向发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)
    Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet的对象。
    1)CRUD操作-create
    使用executeUpdate(String sql)方法完成数据添加操作。

    Statement st = conn.createStatement();
    String sql = "SELECT INTO user(…) VALUES(…)";
    int num = executeUpdate(sql);
    if(num>0) {
      System.out.println("插入成功");
    }
    
    

    2)CRUD操作-delete
    使用executeUpdate(String sql)方法完成数据删除操作。

    Statement st = conn.createStatement();
    String sql = "DELETE FROM user WHERE id=1";
    int num = executeUpdate(sql);
    if(num>0) {
      System.out.println("删除成功");
    }
    
    

    3)CRUD操作-update
    使用executeUpdate(String sql)方法完成数据修改操作。

    Statement st = conn.createStatement();
    String sql = "UPDATE user SET name = ' ' WHERE name = ' '";
    int num = executeUpdate(sql);
    if(num>0) {
      System.out.println("修改成功");
    }
    
    

    4)CRUD操作-read
    使用executeQuery(String sql)方法完成数据查询操作。

    Statement st = conn.createStatement();
    String sql = "SELECT * FROM user WHERE id=1";
    int num = executeQuery(sql);
    while(rs.next()) {
      //根据获取列的数据类型,分别调用rs的相应方法映射到java对象中
    }
    
    

    5)代码实现
    ①提取工具类
    Ⅰ创建utils包,专注于写sql。
    Ⅱ创建db.properties,把配置类单独放出来(如连接JDBC)。
    db.properties代码:

    driver = com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&&useSSL=true
    username = root
    password = 123456
    
    

    Ⅲ在utils包中创建工具类JbdcUtils.java,读取配置文件。
    JbdcUtils.java代码:

    package demo;
    import java.io.IOException;
    import java.io.InputStream;
    import java.sql.*;
    import java.utils.Properties;
    public class JbdcUtils {
      private static String driver = null;
      private static String url = null;
      private static String username = null;
      private static String password = null;
      static {
        try {
          InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
          Properties properties = new Properties();
          properties.loads(in);
          driver = properties.getProperty("driver");
          url = properties.getProperty("url");
          username = properties.getProperty("username");
          password = properties.getProperty("password");
          //驱动只用加载一次
          Class.forName(driver);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      //获取连接
      public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
      }
      //释放连接资源
      public static void release(Connection conn,Statement st,ResultSet rs) {
        if(rs!=null) {
          try {
            rs.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
        if(st!=null) {
          try {
            st.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
        if(conn!=null) {
          try {
            conn.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
      }
    }
    
    

    ②编写增删改的方法 executeUpdate
    Ⅰ增加

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import jav.sql.Statement;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();//获取数据库连接
          st = conn.createStatement();//获得SQL的执行对象
          String sql = "INSERT INTO user(id,`NAME`,`PASSWORD`,`email`,`birthday`)"+"VALUES(4,'xiaoming','123456','2585801995@qq.com','2020-01-01')";
          int i = st.executeUpdate(sql);
          if(i>0) {
            System.out.println("插入成功");
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,rs);
        }
      }
    }
    
    

    Ⅱ删除

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import jav.sql.Statement;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();//获取数据库连接
          st = conn.createStatement();//获得SQL的执行对象
          String sql = "DELETE FROM users WHERE id=4";
          int i = st.executeUpdate(sql);
          if(i>0) {
            System.out.println("删除成功");
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,rs);
        }
      }
    }
    
    

    Ⅲ修改

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import jav.sql.Statement;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();//获取数据库连接
          st = conn.createStatement();//获得SQL的执行对象
          String sql = "UPDATE users SET `NAME`='xiaoming',`email`='2585801995@qq.com' WHERE id=1";
          int i = st.executeUpdate(sql);
          if(i>0) {
            System.out.println("修改成功");
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,rs);
        }
      }
    }
    
    

    ③查询

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import jav.sql.Statement;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();
          st = conn.createStatement();
          String sql = "SELECT * FROM users WHERE id=1";
          rs = st.executeQuery(sql);//查询完毕返回一个结果集
          while(rs.next()) {
            System.out.println(rs.getString("NAME"));
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,rs);
        }
      }
    }
    
    

    6)SQL注入的问题
    sql存在漏洞,会被攻击导致数据泄露,SQL会被拼接。
    例:登录业务。

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import jav.sql.Statement;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Login("'or '1=1","'or '1=1");
      }
      public static void Login(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();
          st = conn.createStatement();
          String sql = "SELECT * FROM users WHERE `NAME`='"username"' AND `PASSWORD`='"password"'";
          rs = st.executeQuery(sql);
          while(rs.next()) {
            System.out.println(rs.getString("NAME"));
            System.out.println(rs.getString("PASSWORE"));
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,rs);
        }
      }
    }
    
    

    5.PreparedStatement对象

    PreparedStatement可以防止SQL注入,效率更好。
    1)新增

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.Date;
    import jav.sql.Statement;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        try {
          conn = JdbcUtils.getConnection();
          //Statement与PreparedStatement的区别
          //使用?占位符代替参数
          String sql = "SELECT INTO users(id,`NAME`,`PASSWORD`,`email`,`birthday`) VALUES(?,?,?,?,?)";
          st = conn.prepareStatement(sql);//预编译SQL,先写sql然后不执行
          //手动给参数赋值
          st.setInt(1,4);
          st.setString(2,"xiaoming");
          st.setString(3,"123456");
          st.setString(4,"1790283208@qq.com");
          st.setDate(5,new.java.sql.Date(new Date().get Time()));
          //执行
          int i = st.executeUpdate();
          if(i>0) {
            System.out.println("插入成功");
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,null);
        }
      }
    }
    
    

    注意点:sql.Date 数据库 java.sql.Date()
    util.Date Java new java.sql.Date(new Date().getTime())

    2)删除

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.Date;
    import jav.sql.PerparedStatement;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        try {
          conn = JdbcUtils.getConnection();
          //Statement与PreparedStatement的区别
          //使用?占位符代替参数
          String sql = "DELETE FROM users WHERE id=?";
          st = conn.prepareStatement(sql);//预编译SQL,先写sql然后不执行
          //手动给参数赋值
          st.setInt(1,4);
          //执行
          int i = st.executeUpdate();
          if(i>0) {
            System.out.println("删除成功");
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,null);
        }
      }
    }
    
    

    3)更新

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.Date;
    import jav.sql.Statement;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        try {
          conn = JdbcUtils.getConnection();
          //Statement与PreparedStatement的区别
          //使用?占位符代替参数
          String sql = "UPDATE users SET `NAME`=? WHERE id=?";
          st = conn.prepareStatement(sql);//预编译SQL,先写sql然后不执行
          //手动给参数赋值
          st.setString(1,"xiaohong");
          st.setInt(2,1);
          //执行
          int i = st.executeUpdate();
          if(i>0) {
            System.out.println("更新成功");
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,null);
        }
      }
    }
    
    

    4)查询

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import jav.sql.PerparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();
          String sql = "SELECT * FROM users WHERE id=?";
          st = conn.prepareStatement(sql);//预编译
          st.setInt(2,1);//传参赋值
          rs = st.executeQuery();//执行
          if(rs.next()) {
            System.out.pringln(rs.getString("NAME"));
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,null);
        }
      }
    }
    
    

    5)防止SQL注入
    PreparedStatement防止SQL注入的本质:把传递进来的参数当作字符。
    假设其中存在转义字符,比如说'会被直接转义。
    例:修改上述登录业务。

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import jav.sql.Statement;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Login("xiaohong","123456");
      }
      public static void Login(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();
          String sql = "SELECT * FROM users WHERE `NAME`=? AND `PASSWORD`=?";
          st = conn.prepareStatement(sql);
          st.setString(1,username);
          st.setString(2,password);
          rs = st.executeQuery();
          while(rs.next()) {
            System.out.println(rs.getString("NAME"));
            System.out.println(rs.getString("PASSWORE"));
          }
        } catch (SQLException e) {
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,rs);
        }
      }
    }
    
    

    6.使用IDEA连接数据库

    1)IDEA连接数据库:右侧Database——>点击+——>选择Data Source——>选择MySQL——>填写数据库的用户名和密码——>点击Test Connection测试功能——>点击Apply——>OK

    image image

    2)连接成功后,可以选择数据库
    选择设置——>选择Schemas,选择需要选择的数据库——>Apply

    image

    双击数据库或其中的表即可查看。

    image

    更新数据:修改完表后点击带有DB的绿色箭头。

    image

    3)编写SQL
    右侧控制台——>选择console(Default)
    右上角可以切换数据库。

    image

    创建账户测试表account并导入测试数据,可下载使用:https://share.weiyun.com/LYbdjkee,也可以直接复制下方。

    CREATE TABLE account(
        id Int PRIMARY KEY AUTO_INCREMENT,
        NAME VARCHAR(40),
        money FLOAT
    );
    /*插入测试数据*/
    insert into account(name,money) values('A',1000);
    insert into account(name,money) values('B',1000);
    insert into account(name,money) values('B',1000);
    
    

    4)可能遇到的问题
    测试连接失败:①lib下没有导入jar包。
    ②导入后仍然失败:左侧数据库中选择MySQL,查看当前Class和数据库对应的版本SQL。

    image image

    7.事务

    要么都成功,要么都失败!
    ACID原则
    原子性:要么全部完成,要么都不完成。
    一致性:总数不变。
    隔离性:多个进程互不干扰。
    持久性:一旦提交不可逆,持久化到数据库了。
    隔离性的问题
    脏读:一个事务读取了另一个没有提交的事务。
    不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了改变。
    虚读(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来的结果不一致。
    用Java来实现模拟转账。

    package demo;
    import demo.utils.JdbcUtils;
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import jav.sql.ResultSet;
    import java.sql.SQLException;
    public class Demo {
      public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
          conn = JdbcUtils.getConnection();
          //关闭数据库的自动提交,自动会开启事务
          conn.SetAutoCommit(false);//开启事务
          String sql1 = "UPDATE account SET money = money-100 WHERE name='A'";
          st = conn.prepareStatement(sql1);
          st.executeUpdate();
          String sql2 = "UPDATE account SET money = money+100 WHERE name='B'";
          st = conn.prepareStatement(sql2);
          st.executeUpdate();
          //业务完毕,提交事务
          conn.commit();
          System.out.println("成功");
        } catch (SQLException e) {
          //若失败,则默认回滚
          //try {
            //conn.rollback();//如果失败,则回滚事务
          //} catch (SQLException e1) {
            //e1.printStackTrace();
          //}
          e.printStackTrace();
        } finally {
          JdbcUtils.release(conn,st,null);
        }
      }
    }
    
    

    代码实现步骤
    ①开启事务。

    conn.setAutoCommit(false);
    
    

    ②一组事务执行完毕,提交事务
    ③可在catch语句中显示的定义回滚语句,但默认失败就会回滚。

    8.数据库连接池

    数据库——>执行完毕——>释放
    连接——>释放:十分浪费系统资源
    池化技术:准备一些预先的资源,过来就连接预先准备好的。
    最小连接数根据常用连接数来设置。
    最大连接数为业务最高的承载上限,超过就排队等待。
    等待超时,等待超过一定时间。
    编写连接池,实现一个接口DataSource。
    开源数据源实现(拿来就用):
    使用数据库连接池后,在项目开发中就不需要编写连接数据库的代码了。
    ①DBCP
    需要用到的jar包:commons-dbcp-1.4、commons-pool-1.6 导入lib目录下
    创建配置dbcpconfig.properties,可下载使用:https://share.weiyun.com/RNemC1zT,也可以直接复制下方。

    #连接设置
    driverClassName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=true
    username=root
    password=123456
    
    #<!-- 初始化连接 -->
    initialSize=10
    
    #最大连接数量
    maxActive=50
    
    #<!-- 最大空闲连接 -->
    maxIdle=20
    
    #<!-- 最小空闲连接 -->
    minIdle=5
    
    #<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
    maxWait=60000
    #JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
    #注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
    connectionProperties=useUnicode=true;characterEncoding=UTF8
    
    #指定由连接池所创建的连接的自动提交(auto-commit)状态。
    defaultAutoCommit=true
    
    #driver default 指定由连接池所创建的连接的只读(read-only)状态。
    #如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
    defaultReadOnly=
    
    #driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
    #可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
    defaultTransactionIsolation=READ_UNCOMMITTED
    
    

    创建工具类JdbcUtils_DBCP.java,读取配置文件。
    JdbcUtils_DBCP.java代码:

    package demo;
    import org.apache.commons.dbcp.BasicDataSource;
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.sql.*;
    import java.utils.Properties;
    public class JbdcUtils_DBCP {
      private static DataSource dataSource = null;
      static {
        try {
          InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
          Properties properties = new Properties();
          properties.loads(in);
          //创建数据库 工厂模式——>创建
          dataSource = BasicDataSourceFactory.createDataSource(properties);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      //获取连接
      public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
      }
      //释放连接资源
      public static void release(Connection conn,Statement st,ResultSet rs) {
        if(rs!=null) {
          try {
            rs.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
        if(st!=null) {
          try {
            st.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
        if(conn!=null) {
          try {
            conn.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
      }
    }
    
    

    ②C3P0
    需要用到的jar包:c3p0-0.95.5、mchange-commons-java-0.2.19 导入lib目录下
    创建配置c3p0-config.xml,可下载使用:https://share.weiyun.com/ZzjAbPtR,也可以直接复制下方。

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
        <!--c3p0的缺省(默认)配置
    如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource();"这样写就表示使用的是c3p0的缺省(默认)-->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&uesSSL=true&serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>
    
        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>
    
        <!--c3p0的命名配置
    如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource();"这样写就表示使用name="MySQL"的配置-->
    
    <name-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&uesSSL=true&serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>
    
        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </name-config>
    </c3p0-config>
    
    

    注:可单独命名多套配置
    创建工具类JdbcUtils_C3P0.java,读取配置文件。
    JdbcUtils_C3P0.java代码:

    package demo;
    import org.apache.commons.dbcp.BasicDataSource;
    import org.apache.commons.dbcp.BasicDataSourceFactory;
    import javax.sql.DataSource;
    import java.io.InputStream;
    import java.sql.*;
    import java.utils.Properties;
    public class JbdcUtils_DBCP {
      private static ComboPooledDataSource dataSource = null;
      static {
        try {
          //代码版配置,不建议使用
          dataSource.setDriverClass();
          dataSource.setUser();
          dataSource.setPassword();
          dataSource.setJdbcUrl();
          dataSource.setMaxPoolSize();
          dataSource.setMinPoolSize();
          //配置文件写法
          dataSource = new ComboPooledDataSource("MySQL");
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
      //获取连接
      public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
      }
      //释放连接资源
      public static void release(Connection conn,Statement st,ResultSet rs) {
        if(rs!=null) {
          try {
            rs.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
        if(st!=null) {
          try {
            st.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
        if(conn!=null) {
          try {
            conn.close();
          } catch (SQLException e) {
            e.printStackTrace();
          }
        }
      }
    }
    
    

    ③阿里巴巴:Druid
    结论:无论使用什么数据源,本质还是一样的。DataSource接口不会变,方法就不会变。

    相关文章

      网友评论

          本文标题:MySQL之JDBC(重点)

          本文链接:https://www.haomeiwen.com/subject/hqhutltx.html