JDBC教程:JDBC毗连Mysql数据库超具体解说(从入门到纯熟使用) ...

打印 上一主题 下一主题

主题 845|帖子 845|积分 2535

JDBC

1.概念:



  • Java DataBase Connectivity 】,Java数据库毗连
  • 即 ,JDBC的作用是:用Java语言操作数据库
2.本质:



  • 官方定义的一套操作所有关系型数据库的规则/规范( 即接口-- API(Application Programming Interface ))
  • 且由关系型数据库厂商本身写JDBC的实现类,实现这套接口(数据库驱动)
  • 真正实行的代码是驱动jar包中的实现类
3.快速入门

步调


  • 导入驱动jar包

    1.                                    图1--查看MySQL版本
    复制代码

    1.                               图2---到官网下载对应版本的jar包
    复制代码
          https://downloads.mysql.com/archives/c-j/ 是旧版本 页面有所不同
        MySQL :: Download Connector/J 附上最新版下载所在
       

       
    1.                                  图3---直接下载无需登录注册Oracle官网账号
    复制代码

    • 在src中新建libs包
    • 复制mysql-connector-java-8.0.26.jar 到项目libs目次下



      1.                            图4.图5.图6--复制jar包并粘贴
      复制代码
    • 右键—>add as library(添加为库)

      1.                                      图7--添加为库
      复制代码

  • 注册驱动
  1. Class.forName("com.mysql.jdbc.Driver");
复制代码



注:需要抛出非常(如图)
   使用throws Exception取代具体的非常类型(如throws ClassNotFoundException)
  

  • 获取数据库毗连对象 Connection
    1. create database JDBC_study;
    2. use JDBC_study;
    3. create table account
    4. (
    5.     id      int auto_increment primary key ,
    6.     name    varchar(10) null,
    7.     balance double      null
    8. );
    复制代码

    ​ 图8–提前准备的数据表
  1. Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBC_study");
  2. //JDBC_study是我的数据库名
复制代码
  MySQL 8.0 以上版本的数据库毗连:
  

  • com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver
  • jdbc:mysql://localhost:3306/数据库名更换为jdbc:mysql://localhost:3306/数据库名?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
  

  • 定义sql语句
    1. String sql="update account set balance =500 where id=1";
    复制代码
  • 获取实行sql语句的对象 statement
    1. Statement statement =connection.createStatement();
    复制代码
  • 实行sql,接收返回结果
    1. int count=statement.executeUpdate(sql);
    复制代码
  • 处置惩罚结果
    1. System.out.println(count);//
    复制代码
  • 开释资源
    1. statement.close();
    2. connection.close();
    复制代码
   完整代码:
  1. /*JDBC快速入门*/public class jdbcDemo1 { public static void main(String[] args) throws Exception {//        1. 导入驱动jar包(已完成)//        2. 注册驱动     Class.forName("com.mysql.cj.jdbc.Driver");//可省略//        3. 获取数据库毗连对象 Connection                //第二、三个参数是毗连数据库的用户名和密码                          Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", "root", "Hky6600115");//        4. 定义sql语句     String sql="update account set balance =500 where id=1";
  2. //        5. 获取实行sql语句的对象 statement     Statement statement =connection.createStatement();
  3. //        6. 实行sql,接收返回结果     int count=statement.executeUpdate(sql);
  4. //        7. 处置惩罚结果     System.out.println(count);//
  5.         8. 开释资源     statement.close();     connection.close(); }}
复制代码
运行查验:

  1.                                  图9--控制台输出(暂时不解读)
复制代码

  1.                                  图10--刷新数据库可见数据已修改
复制代码

详解各对象

1️⃣.DriverManager 驱动管理对象

【一个类】
功能:


  • 一、注册驱动:告诉程序应当使用哪一个数据库去驱动jar包

    • static void registerDriver(Driver driver) DriverManager 的方法
                 上面快速入门的时候没有注册驱动 ,取而代之的是Class.forName(“com.mysql.jdbc.Driver”)也乐成运行,原因如下:
    • 查看mysql.jdbc.Driver的源码可知
      1. //这是com.mysql.jdbc.Driver的静态代码块,只要使用这个类,就会执行这段代码
      2. //而Class.forName("com.mysql.jdbc.Driver")就正好使用到了这个类
      3. static {
      4.         try {
      5.                 java.sql.DriverManager.registerDriver(new Driver());
      6.         } catch (SQLException E) {
      7.                 throw new RuntimeException("Can't register driver!");
      8.         }
      9. }
      复制代码
      因此,我们是通过给forName指定了MySQL的驱动,它帮助我们注册驱动
    • 注意:MySQL5.0之后可以省略注册驱动的步调
                 在jar包中,存在一个java.sql.Driver设置文件,文件中指定了com.mysql.jdbc.Driver

  • 二、获取数据库毗连

    • 方法:static Connection getConnection(String url, String user, String password); 带三个参数
    • 参数:

      • url:指定毗连的路径

        • 语法:jdbc:mysql://ip所在(域名):端口号/数据库名称【MySQL5.0写法】
        • 语法:jdbc:mysql://ip所在(域名):端口号/JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC【MySQL8.0写法】
                             ip所在(域名)可以找到某一台盘算机
                    端口号可以找到盘算机上安装的MySQL服务器
        • 细节:若毗连的是本机mysql服务器,而且mysql服务默认端口是3306,则url可以简写为jdbc:mysql:///数据库名称【MySQL5.0写法】,即省略 ip所在(域名):端口号

      • user:用户名(本机常为root)
      • password:密码



2️⃣. Connection 数据库毗连对象

功能:


  • 一、获取实行sql的对象

    • 获取普通实行者对象:Statement createStatement();
    • 获取预编译实行者对象:PreparedStatement prepareStatement(String sql);

  • 二、管理事件
           业务操作的多个步调:要么同时乐成,要么同时失败
        数据库可以:开启/提交/回滚事件,针对此有以下三个对应方法:

    • 开启事件:setAutoCommit(boolean autoCommit); 参数为false,则开启事件
    • 提交事件:commit();
    • 回滚事件:rollback();


3️⃣.statement 实行sql的对象⭐

功能:
实行sql对象


  • boolean execute(String sql); 可以实行任意sql语句(相识即可)
  • int executeUpdate(String sql); 实行DML(insert、update、delete)语句以及DDL(create、alert、drop)

    • 返回值:影响的行数
    • eg. 前面运行过的,原先的表格经修改,id=1的balance由1000酿成500,则这一行数据受到影响被改变返回值为1(见图9)
           idnamebalance1zhangsan1000---->5002lisi1000
    • 作用:可以通过这个影响的行数判定DML语句是否实行乐成 返回值>0的则实行乐成;反之,则失败

  • ResultSet executeQuery(String sql); 实行DQL(select)

练习:基础

1.accunt表 添加一条记载
2.account表 修改记载
3.account表 删除一条记载
  1. import java.sql.*;/*1.accunt表 添加一条记载 */public class jdbcDemo2 {    public static void main(String[] args) throws Exception{        Statement statement=null;        Connection connection=null;        try {            //1.注册驱动            Class.forName("com.mysql.cj.jdbc.Driver");            //2.定义sql            String sql="insert into account values(null,'wangwu',3000)";            //3.获取connection对象            connection= DriverManager.getConnection("jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC", "root", "Hky6600115");            //4.获取实行sql的对象statement            statement=connection.createStatement();            //5.实行sql            int count=statement.executeUpdate(sql);
  2. //影响行数【增长一行,应返回1】            //6.处置惩罚结果            System.out.println(count);            if (count>0){                System.out.println("实行乐成");            }else {                System.out.println("实行失败");            }        }catch (ClassNotFoundException e){            e.printStackTrace();        }catch (SQLException e){            e.printStackTrace();            /*            开释但因作用域问题报错-->因此提拔作用域                statement.close();                connection.close();             */        }finally {            //7.开释资源            //制止空指针非常            if(statement!=null){                try {                    statement.close();                }catch (SQLException e){                    e.printStackTrace();                }            }            if(connection!=null){                try {                    connection.close();                }catch (SQLException e){                    e.printStackTrace();                }            }        }    }}
复制代码
  请仿造以上练习1的代码 ,完成练习2以及练习3
  
4️⃣.ResultSet 结果集对象



  • boolean next()

    • 如果有数据返回true,且光标向下移动一行
    • 没有则返回false

  • XXX getXxx(列名/列编号)

    • XXX 表示数据类型 eg.int、String
    • 例如:int getInt(int)可以有 int getInt(1)或者int getInt("id")

代码示例:
  1. import java.sql.*;
  2. public class jdbcDemo5 {
  3.     public static void main(String[] args) {
  4.         Connection connection=null;
  5.         Statement statement=null;
  6.         ResultSet resultSet=null;
  7.         try {
  8.             Class.forName("com.mysql.cj.jdbc.Driver");
  9.             String sql="select * from account";
  10.             connection= DriverManager.getConnection("jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC","root","Hky6600115");
  11.             statement=connection.createStatement();
  12.             resultSet= statement.executeQuery(sql);
  13.             //处理结果
  14.             //1.让光标向下移动一行(默认在列名一行)
  15.             resultSet.next();
  16.             //2.获取数据
  17.             int id=resultSet.getInt("id");
  18.             String name=resultSet.getString("name");
  19.             double balance=resultSet.getDouble("balance");
  20.             //3.打印数据
  21.             System.out.println(id+"---"+name+"---"+balance);
  22.         } catch (ClassNotFoundException e) {
  23.             e.printStackTrace();
  24.         } catch (SQLException e) {
  25.             e.printStackTrace();
  26.         }finally {
  27.             if(resultSet!=null){
  28.                 try {
  29.                     resultSet.close();
  30.                 } catch (SQLException e) {
  31.                     e.printStackTrace();
  32.                 }
  33.             }
  34.             if(statement!=null){
  35.                 try {
  36.                     statement.close();
  37.                 } catch (SQLException e) {
  38.                     e.printStackTrace();
  39.                 }
  40.             }
  41.             if(connection!=null){
  42.                 try {
  43.                     connection.close();
  44.                 } catch (SQLException e) {
  45.                     e.printStackTrace();
  46.                 }
  47.             }
  48.         }
  49.     }
  50. }
复制代码

  1.                                         图--运行结果
复制代码

练习:遍历

案例代码:
   其他步调不变,仅改变数据处置惩罚过程
  1. //处理结果(输出全部数据)
  2. //1.判断游标是否为最后一行末尾
  3. while (resultSet.next()){
  4.         //2.获取数据
  5.         int id=resultSet.getInt("id");
  6.     String name=resultSet.getString("name");
  7.     double balance=resultSet.getDouble("balance");
  8.     //3.打印数据
  9.     System.out.println(id+"---"+name+"---"+balance);
  10. }
复制代码

练习:封装对象

数据准备:
  1. insert into emp VALUES
  2. (1001,'孙悟空',4,1004,'2000-12-17','8000.00',NULL,20),
  3. (1002,'卢俊义',3,1006,'2001-02-20','16000.00','3000.00',30),
  4. (100,'林冲',3,1006,'2001-02-22','12500.00','5000.00',30),
  5. (1004,'唐僧',2,1009,'2001-04-02','29750.00',NULL,20),
  6. (1005,'李逵',4,1006,'2001-09-28','12500.00','14000.00',30),
  7. (1006,'宋江',2,1009, '2001-05-01','28500.00',NULL,30),
  8. (1007,'刘备',2,1009,'2001-09-01','24500.00',NULL,10),
  9. (1008,'猪八戒',4,1004,'2007-04-19','30000.00',NULL,20),
  10. (1009,'罗贯中',1,NULL,'2001-11-17','50000.00',NULL,10),
  11. (1010,'吴用',3,1006,'2001-09-08','15000.00','0.00',30),
  12. (1011,'沙僧',4,1004,'2007-05-23','11000.00',NULL,20),
  13. (1012,'李逵',4,1006,'2001-12-03','9500.00',NULL,30),
  14. (1013,'小白龙',4,1004,'2001-12-03','30000.00',NULL,20),
  15. (1014,'关羽',4,1007,'2002-01-23','13000.00',NULL,10);
复制代码
  要求:定义一个方法,查询emp表中的数据并将其封装为对象,然后装载集合,返回
  步调:
  

  • 定义emp类
  • 定义方法 public List< EMP > findAll(){}
  • 实现方法 select*from emp;
  代码实现:

  • 设置文件jdbc.properties
  1. url="jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC"
  2. user=root
  3. password=Hky6600115'
  4. driver=com.mysql.cj.jdbc.Driver
复制代码

  • JDBCUtils工具类
  1. public class JDBCUtils{
  2.     private static String url;
  3.     private static String user;
  4.     private static
  5. }
复制代码

抽取JDBC工具类(JDBCUtils)



  • 目的:简化书写
  • 分析:

    • 注册驱动
    • 毗连对象

      • 需求:

        • 传递参数❌(太麻烦)
        • 保障工具类的通用性(MySQL5.0/MySQL8.0的url不同)

      • 解决:设置文件jdbc.properties【在src下创建】

                       url=“”
                user=“”
                password=“”
                driver=“”


实现代码:
  1. import java.io.FileReader;
  2. import java.io.IOException;
  3. import java.net.URL;
  4. import java.sql.*;
  5. import java.util.Properties;
  6. /*
  7.     JDBC工具类
  8. */
  9. public class JDBCUtils {
  10.     /*
  11.     文件的读取只需要一次,便可以得到所有值
  12.             利用【静态代码块】
  13.      */
  14.     private static String url;
  15.     private static String user;
  16.     private static String password;
  17.     private static String driver;
  18.     static {
  19.         //读取资源文件,获取值
  20.         try {
  21.             //1.创建properties集合类
  22.             Properties properties=new Properties();
  23.             //获取src路径下的文件的方式--->classLoader 类加载器
  24.             ClassLoader classLoader = JDBCUtils.class.getClassLoader();
  25.             URL resource  = classLoader.getResource("jdbc.properties");
  26.             String path = resource.getPath();
  27.             //System.out.println(path);
  28.             //2.加载文件
  29. //            properties.load(new FileReader("jdbc.properties"));
  30.             properties.load(new FileReader(path));
  31.             //3.获取数据,赋值
  32.             url=properties.getProperty("url");
  33.             user=properties.getProperty("user");
  34.             password=properties.getProperty("password");
  35.             driver=properties.getProperty("driver");
  36.             //4.注册驱动
  37.             Class.forName(driver);
  38.         } catch (IOException e) {
  39.             e.printStackTrace();
  40.         } catch (ClassNotFoundException e) {
  41.             e.printStackTrace();
  42.         }
  43.     }
  44. //    获取连接
  45.     public static Connection getConnection() throws SQLException {
  46.         return DriverManager.getConnection(url, user, password);
  47.     }
  48. //    释放资源
  49.     public static void close(ResultSet resultSet, Statement statement, Connection connection){
  50.         if(resultSet!=null){
  51.             try {
  52.                 resultSet.close();
  53.             } catch (SQLException e) {
  54.                 e.printStackTrace();
  55.             }
  56.         }
  57.         if(statement!=null){
  58.             try {
  59.                 statement.close();
  60.             } catch (SQLException e) {
  61.                 e.printStackTrace();
  62.             }
  63.         }
  64.         if(connection!=null){
  65.             try {
  66.                 connection.close();
  67.             } catch (SQLException e) {
  68.                 e.printStackTrace();
  69.             }
  70.         }
  71.     }
  72.     public static void close(PreparedStatement preparedStatement, Connection connection) {
  73.         if(preparedStatement!=null){
  74.             try {
  75.                 preparedStatement.close();
  76.             } catch (SQLException e) {
  77.                 e.printStackTrace();
  78.             }
  79.         }
  80.         if(connection!=null){
  81.             try {
  82.                 connection.close();
  83.             } catch (SQLException e) {
  84.                 e.printStackTrace();
  85.             }
  86.         }
  87.     }
  88. }
复制代码

工具类练习

   需求:
  

  • 通过键盘录入用户名和密码
  • 判定用户是否登录乐成

    • select * from user where username=““and password =””;
    • 如果该sql语句有查询结果,则表示乐成,反之则失败

    步调:
  

  • 创建数据表user
    1. create table user(
    2.     id int primary key auto_increment,
    3.     username varchar(32),
    4.     password varchar(32)
    5. );
    6. insert into user values (null,'zhangsan','123');
    7. insert into user values (null,'lisi','234');
    复制代码
  • 编写登录方法
  代码实现:
  1. /*
  2.     登录方法
  3.      */
  4.     public boolean logion(String username,String password) {
  5.         if(username==null||password==null){
  6.             return false;
  7.         }
  8.         //连接数据库判断是否登录成功
  9.         Connection connection=null;
  10.         Statement statement=null;
  11.         ResultSet resultSet=null;
  12.         try {
  13.             connection= JDBCUtils.getConnection();
  14.             String sql="select * from user where username='"+username+"'and password='"+password+"' ";
  15.             statement=connection.createStatement();
  16.             resultSet=statement.executeQuery(sql);
  17.             return resultSet.next();
  18.         } catch (SQLException e) {
  19.             e.printStackTrace();
  20.         }finally {
  21.             JDBCUtils.close(resultSet,statement,connection);
  22.         }
  23.         return false;
  24.     }
复制代码

5️⃣.PreparedStatement 实行sql的对象



  • sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题

    • 以上面的练习为例

      • 输入用户名:随机(eg.wangwu)
      • 输入密码:a ’ or ’ a ’ = ’ a

        • sql语句:select * from user where username =‘wangwu’ and password='a’or’a’=‘a’;
        • 原sql语句:“select * from user where username='”+username+“‘and password=’”+password+"’ "
                       仔细对比观察
                


  • 经典例子:



   漫画中,该门生的姓名为“Robert’); DROP TABLE students;–”,导致students表被删除:
  

  • 解决:使用PreparedStatement 对象
  • 预编译sql:参数使用?作为占用符
  • 步调(稍复杂):

    • 导入驱动jar包
    • 注册驱动
    • 获取数据库毗连对象 connection
    • 定义sql

      • sql的参数使用?作为占位符
      • 如:select * from user where username = ? and password = ?;

    • 获取实行sgl语句的对象 PreparedStatement

      • Connection.PreparedStatement (String sql)  需要传参

    • 给?赋值:

      • 方法:setXxx(参数1,参数2)
      • 参数1:?的位置
      • 参数2:?的值

    • 实行sql,接受返回结果 不需要传参
    • 处置惩罚结果
    • 开释资源

代码修改:
  1. /*
  2.     登录方法,使用PreparedStatement 对象
  3.      */
  4.     public boolean logion(String username,String password) {
  5.         if(username==null||password==null){
  6.             return false;
  7.         }
  8.         //连接数据库判断是否登录成功
  9.         Connection connection=null;
  10.         ResultSet resultSet=null;
  11.         PreparedStatement preparedStatement=null;
  12.         try {
  13.             connection= JDBCUtils.getConnection();
  14.             String sql="select * from user where username=?and password=?";
  15.             PreparedStatement=connection.preparedStatement(sql);
  16.             preparedStatement.setString(1,username);
  17.             preparedStatement.setString(2,password);
  18.             resultSet=preparedStatement.executeQuery();
  19.             return resultSet.next();
  20.         } catch (SQLException e) {
  21.             e.printStackTrace();
  22.         }finally {
  23.             JDBCUtils.close(resultSet,preparedStatement,connection);
  24.         }
  25.         return false;
  26.     }
复制代码


  • 注意:后期改用 preparedStatement 来完成增删改查的操作

    • 上风:

      • 防止sql注入
      • 效率更高



JDBC控制事件



  • 事件 :一个包罗多个步调的业务操作。如果这个业务操作被事件管理,则这多个步调要么同时乐成,要么同时失败。
  • 操作:

    • 开启事件
    • 提交事件
    • 回滚事件

  • 使用connection对象来管理事件

    • 开启事件 setAutoCommit(boolean autoCommit) : 调用该方法设置参数为 false,即开启事件

      • 在实行sql之前开启事件

    • 提交事件 commit()

      • 当所有sql都实行完提交事件

    • 回滚事件 rollback()

      • 在catch中回滚事件


练习:转账

代码实现:
  1. import cn.itcast.util.JDBCUtils;
  2. import java.sql.*;
  3. /*
  4. 事务操作
  5. */
  6. public class jdbcDemo10 {
  7.     /*
  8.     转账方法
  9.      */
  10.     public static void main(String[] args) throws Exception {
  11.         Connection connection=null;
  12.         PreparedStatement preparedStatement1=null;
  13.         PreparedStatement preparedStatement2=null;
  14.         ResultSet resultSet=null;
  15.         try {
  16.             //1.获取连接
  17.             connection= JDBCUtils.getConnection();
  18. //                开启事务
  19.             connection.setAutoCommit(false);
  20.             //2.定义sql
  21.             //2.1. 张三-500
  22.             //2.2. 李四+500
  23.             String sql1="update account set balance = balance - ? where id = ?";
  24.             String sql2="update account set balance = balance + ? where id = ?";
  25.             //3.获取执行对象
  26.             preparedStatement1=connection.prepareStatement(sql1);
  27.             preparedStatement2=connection.prepareStatement(sql2);
  28.             //4.设置参数
  29.             preparedStatement1.setDouble(1,500);
  30.             preparedStatement1.setInt(2,1);
  31.             preparedStatement2.setDouble(1,500);
  32.             preparedStatement2.setInt(2,2);
  33.             //5.执行sql
  34.             preparedStatement1.executeUpdate();
  35.             preparedStatement2.executeUpdate();
  36. //                提交事务
  37.             connection.commit();
  38.         } catch (Exception e) {
  39. //                事务回滚
  40.             try {
  41.                 if(connection!=null){
  42.                     connection.rollback();
  43.                 }
  44.             }catch (SQLException e1){
  45.                 e1.printStackTrace();
  46.             }
  47.             e.printStackTrace();
  48.         }finally {
  49.             JDBCUtils.close(preparedStatement1,connection);
  50.             JDBCUtils.close(preparedStatement2,null);
  51.         }
  52.     }
  53. }
复制代码


数据库与毗连池

1. 概念

存放数据库毗连的一个容器(集合)Connection
   当系统运行起来之后,这个毗连池就被创建,在这个毗连池当中,会申请一些对象,当有用户来访问数据库的时候,就从这个毗连池当中获取毗连对象,用户访问竣事之后,毗连池对象会归还给容器
  

2.优点:



  • 节约资源
  • 用户访问高效
3. 毗连池实现:



  • java官方提供的数据库毗连池规范(接口):DataSource (javax.sql包下)

    • 方法:【获取毗连:getConnection();】
    • 【归还毗连池对象:conn.close();】

  • 由数据库厂商为我们实现该接口

    • C3P0
    • Druid (阿里巴巴开辟)

4.C3P0

步调:

1. 导入jar包

   官网:https://sourceforge.net/
  进入官网,搜索框中输入c3p0,并点击下面的提示
  

点击下载即可
  

解压后,在lib文件夹中,复制如下两个jar包到项目lib文件夹中(还有不能忘记数据库驱动jar包mysql-connector-java-8.0.26.jar)


右键libs添加为库
  

  2. 定义设置文件:



  • 文件命名为:c3p0.properties 或者 c3p0-config.xml
  • 位置:src目次下
  • 1.自定义的c3p0-config.xml
  1. <c3p0-config>
  2.   <!-- 使用默认的配置读取连接池对象 -->
  3.   <default-config>
  4.           <!--  连接参数 -->
  5.     <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
  6.     <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbc_study</property>
  7.     <property name="user">root</property>
  8.     <property name="password">Hky6600115</property>
  9.    
  10.     <!-- 连接池参数 -->
  11.     <property name="initialPoolSize">5</property>
  12.     <property name="maxPoolSize">10</property>
  13.     <property name="checkoutTimeout">3000</property>
  14.   </default-config>
  15.   <named-config name="otherc3p0">
  16.     <!--  连接参数 -->
  17.     <property name="driverClass">com.mysql.jdbc.Driver</property>
  18.     <property name="jdbcUrl">jdbc:mysql://localhost:3306/day25</property>
  19.     <property name="user">root</property>
  20.     <property name="password">root</property>
  21.    
  22.     <!-- 连接池参数 -->
  23.     <property name="initialPoolSize">5</property>
  24.     <property name="maxPoolSize">8</property>
  25.     <property name="checkoutTimeout">1000</property>
  26.   </named-config>
  27. </c3p0-config>
复制代码


  • 2.参数表明

    • initialPoolSize:初始化申请的毗连数量
    • maxPoolSize:最大的毗连数量
    • checkoutTimeout:超时时间

3. 创建核心对象

数据库毗连池对象 ComboPooledDataSource
4. 获取毗连

getConnection
代码实现:
  1. import com.mchange.v2.c3p0.ComboPooledDataSource;
  2. import javax.sql.DataSource;
  3. import java.sql.Connection;
  4. /*
  5. c3p0的演示
  6. */
  7. public class c3p0Demo1 {
  8.     public static void main(String[] args) throws Exception {
  9.         //1.创建数据库连接池对象
  10.         DataSource dataSource=new ComboPooledDataSource();
  11.         //2.获取连接对象
  12.         Connection connection = dataSource.getConnection();
  13.         //3.打印
  14.         System.out.println(connection);
  15.     }
  16. }
复制代码

参数查验:

   5
  10
  3000
  1. 查验最大毗连数量

  1. public class c3p0Demo2 {
  2.     public static void main(String[] args) throws Exception {
  3.         DataSource dataSource=new ComboPooledDataSource();
  4.         for (int i=1;i<=10;i++){
  5.             Connection connection=dataSource.getConnection();
  6.             System.out.println(i+":"+connection);
  7.         }
  8.     }
  9. }
复制代码
运行结果:(正常)

2. 查验超时时间

–> 运行有错误会等带一段时间再报错
  1. for (int i=1;i<=11;i++){
  2.     Connection connection=dataSource.getConnection();
  3.     System.out.println(i+":"+connection);
  4. }
复制代码
运行结果:(先输出正常部分,隔3秒报错)

   若中途归还对象,即可正常(重复使用)
  1. public static void main(String[] args) throws SQLException {
  2.         DataSource dataSource=new ComboPooledDataSource();
  3.         for (int i=1;i<=11;i++){
  4.             Connection connection=dataSource.getConnection();
  5.             System.out.println(i+":"+connection);
  6.             
  7.             if(i==5){
  8.                 connection.close();
  9.             }
  10.         }
  11.     }
复制代码
注:



  • DataSource dataSource=new ComboPooledDataSource();表示使用默认设置
  • DataSource dataSource=new ComboPooledDataSource("otherc3p0");表示使用指定名称设置

5.Druid

步调:

1. 导入jar包

官网下载所在:Central Repository: com/alibaba/druid (maven.org)


(详见c3p0)
2.定义设置文件



  • 是properties情势的
  • 可以叫任意名称,可以放在任意目次下

    • 不会自动加载,需要手动

  1. //示例 druid.properties
  2. driverClassName=com.mysql.cj.jdbc.Driver
  3. url=jdbc:mysql:///JDBC_study?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
  4. username=root
  5. password=password
  6. # 初始化连接数量
  7. initialSize=5
  8. #最大连接数
  9. maxActive=10
  10. # 最大等待时间
  11. maxWait=3000
复制代码
步调+1:加载设置文件
3. 获取数据库毗连池对象

通过工厂类来获取 DruidDataSourceFactory
4. 获取毗连

getConnection
代码实现:

  1. import com.alibaba.druid.pool.DruidDataSourceFactory;
  2. import javax.sql.DataSource;
  3. import java.io.InputStream;
  4. import java.sql.Connection;
  5. import java.util.Properties;
  6. public class DruidDemo {
  7.     public static void main(String[] args) throws Exception {
  8.         //加载配置文件
  9.         Properties properties=new Properties();
  10.         InputStream inputStream=DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
  11.         properties.load(inputStream);
  12.         //获取连接池对象
  13.         DataSource dataSource =DruidDataSourceFactory.createDataSource(properties);
  14.         //获取连接
  15.         Connection connection=dataSource.getConnection();
  16.         System.out.println(connection);
  17.     }
  18. }
复制代码

定义工具类

1. 定义一个类

2. 静态代码块



  • 提供静态代码块加载设置文件,初始化毗连池对象
3. 提供方法



  • 获取毗连方法;通过数据库毗连池获取毗连
  • 开释资源
  • 获取毗连池的方法
代码实现:

  1. import com.alibaba.druid.pool.DruidDataSourceFactory;
  2. import javax.sql.DataSource;
  3. import java.io.IOException;
  4. import java.sql.Connection;
  5. import java.sql.ResultSet;
  6. import java.sql.SQLException;
  7. import java.sql.Statement;
  8. import java.util.Properties;
  9. /*
  10. Druid连接池工具类
  11. */
  12. public class JDBCUtils {
  13.     private static DataSource dataSource;
  14.     static {
  15.         try {
  16.             Properties properties=new Properties();
  17.             properties.load(JDBCUtils.class.getClassLoader().getResourceAsStream("druid.properties"));
  18.             dataSource= DruidDataSourceFactory.createDataSource(properties);
  19.         } catch (IOException e) {
  20.             e.printStackTrace();
  21.         } catch (Exception e) {
  22.             e.printStackTrace();
  23.         }
  24.     }
  25.     /*
  26.     获取连接的方法
  27.      */
  28.     public static Connection getConnection() throws SQLException {
  29.         return dataSource.getConnection();
  30.     }
  31.     /*
  32.     释放资源
  33.      */
  34.     public static void close(ResultSet resultSet,Statement statement, Connection connection){
  35.         if (resultSet!=null){
  36.             try {
  37.                 resultSet.close();
  38.             } catch (SQLException e) {
  39.                 e.printStackTrace();
  40.             }
  41.         }
  42.         if (statement!=null){
  43.            try {
  44.                statement.close();
  45.            } catch (SQLException e) {
  46.                e.printStackTrace();
  47.            }
  48.         }
  49.         if (connection!=null){
  50.             try {
  51.                 connection.close();//归还连接
  52.             } catch (SQLException e) {
  53.                 e.printStackTrace();
  54.             }
  55.         }
  56.     }
  57.     public static void close(Statement statement, Connection connection){
  58.         close(null,statement,connection);
  59.     }
  60.     /*
  61.     获取连接池
  62.      */
  63.     public static DataSource getDataSource(){
  64.         return dataSource;
  65.     }
  66. }
复制代码


JDBCTemplate

Spring框架对JDBC的简单封装,提供了一个JdbcTemplate对象,大大的简化了开辟
步调

1. 导入jar包

以下是我的下载参考页面所在↓
spring jar包 以及 jdbcTemplate 相关jar包下载_jdbctemplate的jar包-CSDN博客

2.创建JdbcTemplate对象



  • 依靠于数据源DataSource
JdbcTemplate template = new jdbcTemplate(dataSource);
  1. import cn.itcast.JDBC数据库与连接池.datasource.utils.JDBCUtils;
  2. import org.springframework.jdbc.core.JdbcTemplate;
  3. /*
  4. JDBCTemplateDemo1 入门
  5. */
  6. public class JDBCTemplateDemo1 {
  7.     public static void main(String[] args) {
  8. //        1.导入jar包
  9. //        2.创建JDBCTemplate
  10.         JdbcTemplate template=new JdbcTemplate(JDBCUtils.getDataSource());
  11. //        3.调用方法
  12.         String sql="update account set balance=5000 where id=?";
  13.         int count =template.update(sql,2);
  14.         System.out.println(count);
  15.     }
  16. }
复制代码
3. 调用JdbcTemplate的方法来完成CRUD的操作



  • update():实行DML语句。增、删、改语句
  • queryForMap():查询结果将结果集封装为map集合
  • queryForList():查询结果将结果集封装为list集合
  • query():查询结果,将结果封装为JavaBean对象
  • queryForobject:查询结果,将结果封装为对象
4. 练习



  • 修改1号数据的 salary 为 10000
  • 添加一条记载
  • 删除刚才添加的记载
  • 查询id为1的记载,将其封装为Map集合
  • 查询所有记载,将其封装为List
  • 查询所有记载,将其封装为Emp对象的List集合
  • 查询总记载数

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

卖不甜枣

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表