• Java基础(二十五):JDBC



    一、JDBC

    1.1 概述

    1. 为访问不同的数据库提供了统一的接口
    2. Java程序员使用jdbc,可以连接任何提供了jdbc驱动程序的数据库系统

    1.2 快速入门

    JDBC编写步骤:

    1. 注册驱动 - 加载Driver类
    2. 获取连接 - 得到Connection
    3. 执行增删改查 - 发送SQL命令给到mysql执行
    4. 释放资源 - 关闭相关的连接

    第一步:新建一个libs文件夹,将mysql的jdbc的jar包放入其中,然后右击add as library将jar包导入项目

    在这里插入图片描述

    第二步:向数据库mydb的表actor插入一条数据

    package JDBC_Exercise;
    
    
    import com.mysql.cj.jdbc.Driver;
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class Jdbc01 {
        public static void main(String[] args) throws SQLException {
            //将mysql.jar 拷贝到该目录下,加载为库
    
            //1. 注册驱动
            // 创建一个driver对象:new com.cj.mysql.jdbc.Driver   8.0版本需要.cj
            Driver driver = new Driver();
    
            //2. 得到连接
            //解读:jdbc:mysql:// 规定好的协议,通过jdbc的方式来连接mysql
            //(2)localhost 主机,可以是IP地址
            //(3)3306 表示mysql监听的端口
            //(4)jdbc 表示连接到mysql dbms 的哪个数据库
            //(5)mysql的连接本质:就是socket连接
            //(6)serverTimezone=UTC需要设置时区
            String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC";
            //将 用户名和密码放入到Properties 对象
            Properties properties = new Properties();
            //说明:user  和 password 是规定好的,后边的值根据实际情况来写
            properties.setProperty("user", "root");//用户
            properties.setProperty("password", "123456");//密码
            //根据url连接数据库
            Connection connect = driver.connect(url, properties);
    
            //3. 执行sql语句
            String sql = "insert into actor values(null,'吴彦祖','男','2023-09-14','1235')";
            //用于执行静态sql语句,并返回结果
            Statement statement = connect.createStatement();
            int i = statement.executeUpdate(sql);//如果是 dml 语句,返回的就是影响行数
            System.out.println(i > 0 ? "成功" : "失败");
    
            //4. 关闭连接资源
            statement.close();
            connect.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49

    二、获取数据库连接的5种方式

    package JDBC_Exercise;
    
    
    import com.mysql.cj.jdbc.Driver;
    import org.junit.jupiter.api.Test;
    
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class Jdbc01 {
        public static void main(String[] args)  {
    
        }
        @Test
        public void jdbcConnect01() throws SQLException{
            //方式一:静态加载
            Driver driver = new Driver();
            String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC";
            Properties properties = new Properties();
            properties.setProperty("user", "root");//用户
            properties.setProperty("password", "123456");//密码
            Connection connect = driver.connect(url, properties);
            System.out.println("方式1 " + connect);
            connect.close();
        }
        @Test
        public void jdbcConnect02() throws ClassNotFoundException, IllegalAccessException, InstantiationException, SQLException {
            //方式二:使用反射加载Diver类 动态加载,更加灵活
            Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
            Driver driver = (Driver)aClass.newInstance();
            String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC";
            Properties properties = new Properties();
            properties.setProperty("user", "root");//用户
            properties.setProperty("password", "123456");//密码
            Connection connect = driver.connect(url, properties);
            System.out.println("方式2 " + connect);
            connect.close();
        }
        @Test
        public void jdbcConnect03()throws Exception{
            //方式三:使用DriverManager替代Manager进行 统一管理
            Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
            Driver driver = (Driver)aClass.newInstance();
            String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC";
            String user = "root";
            String password = "123456";
    
            DriverManager.registerDriver(driver);//注册Driver驱动
    
            Connection connection = DriverManager.getConnection(url, user, password);
            System.out.println("方式3 " + connection);
            connection.close();
        }
        @Test
        public void jdbcConnect04()throws Exception{
            //方式四:使用Class.forName自动完成注册驱动,简化代码
            // 在加载Driver类时,自动完成了注册
            Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");//可以省略,但是建议写上
            String url = "jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC";
            String user = "root";
            String password = "123456";
    
            Connection connection = DriverManager.getConnection(url, user, password);
            System.out.println("方式4 " + connection);
            connection.close();
        }
        @Test
        public void jdbcConnect05()throws Exception{
            //方式五:在第四种上优化,设置配置文件,更加灵活
    		// ------使用的最多------
            // 从配置文件拿到信息
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\mysql.properties"));
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            String driver = properties.getProperty("driver");
            String url = properties.getProperty("url");
    
            Class<?> aClass = Class.forName(driver);//可以省略,但是建议写上
            Connection connection = DriverManager.getConnection(url, user, password);
            System.out.println("方式5 " + connection);
            connection.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80
    • 81
    • 82
    • 83
    • 84
    • 85
    • 86
    • 87
    • 88
    • 89
    • 90
    • 91
    • 92

    三、ResultSet

    1. 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成;
    2. ResultSet 对象保持一个光标指向其当前的数据行。最初,光标位于第一行之前;
    3. next 方法将光标移动到下一行,并且由于在 ResultSet 对象中没有更多行时返回 false ,因此可以在 while 循环中使用循环来遍历结果集。
    package JDBC_Exercise;
    
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    import java.util.Date;
    import java.util.Properties;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class ResultSet_ {
        public static void main(String[] args) throws Exception {
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\mysql.properties"));
            // 1.注册驱动
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            String driver = properties.getProperty("driver");
            String url = properties.getProperty("url");
            // 2.得到连接
            Class<?> aClass = Class.forName(driver);//可以省略,但是建议写上
            Connection connection = DriverManager.getConnection(url, user, password);
            // 3.得到statement
            Statement statement = connection.createStatement();
            // 4.组织SQL语句
            String sql = "select id,name,sex,borndate,phone from actor";
            ResultSet resultSet = statement.executeQuery(sql);
            while (resultSet.next()) {
                int id = resultSet.getInt(1);
                String name = resultSet.getString(2);
                String sex = resultSet.getString(3);
                Date date = resultSet.getDate(4);
                String phone = resultSet.getString(5);
                System.out.println(id + "\t" + name + "\t" + sex
                        + "\t" + date + "\t" + phone);
            }
            // 5.关闭
            resultSet.close();
            statement.close();
            connection.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47

    四、Statement与PreparedStatement

    4.1 Statement存在SQL注入

    在这里插入图片描述

    演示SQL注入:

    package JDBC_Exercise;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;
    import java.util.Scanner;
    
    public class Statement_ {
        public static void main(String[] args) throws IOException, SQLException, ClassNotFoundException {
            Scanner scanner = new Scanner(System.in);
            //让用户输入管理员名和密码
            System.out.print("请输入名字:");
            /*  next 接收到 空格就结束
                如果希望看到sql注入,则这里需要使用nextLine */
            String admin_name = scanner.nextLine();
            System.out.print("请输入电话:");
            String admin_pwd = scanner.nextLine();
    
            //通过properties获取配置文件的信息
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\mysql.properties"));
            //获取相关的值
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            String driver = properties.getProperty("driver");
            String url = properties.getProperty("url");
    
            //1.注册驱动
            Class.forName(driver);
            //2.得到连接
            Connection connection = DriverManager.getConnection(url, user, password);
            //3.得到statement
            Statement statement = connection.createStatement();
            //4.组织一个sql语句
            String sql = "select name,phone from actor " +
                    "where name ='" + admin_name + "' and pwd = '" + admin_pwd + "'";
            ResultSet resultSet = statement.executeQuery(sql);
            if (resultSet.next()) {  //查询到一条记录,则说明存在
                System.out.println("成功");
            } else {
                System.out.println("失败");
            }
            resultSet.close();
            statement.close();
            connection.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48

    结果分析:名字和电话显然是错的,但是这条语句还能成功,显然存在SQL、注入。

    请输入名字:1' or
    请输入电话:or '1'= '1
    成功
    
    • 1
    • 2
    • 3

    4.2 PreparedStatement

    1. 不再使用 + 拼接SQL语句,减少语法错误
    2. 有效的解决了sql注入问题
    3. 大大减少了编译次数,效率较高
    package JDBC_Exercise;
    
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.util.Properties;
    import java.util.Scanner;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class PreparedStatement_ {
        public static void main(String[] args) throws Exception{
    
            Scanner scanner = new Scanner(System.in);
            //让用户输入管理员名和密码
            System.out.print("请输入管理员的名字:");//next 接收到 空格就结束
            String admin_name = scanner.nextLine();//如果希望看到sql注入,则这里需要使用nextLine
            System.out.print("请输入管理员的密码:");
            String admin_pwd = scanner.nextLine();
    
    
            Properties properties = new Properties();
            properties.load(new FileInputStream("src\\mysql.properties"));
            String user = properties.getProperty("user");
            String password = properties.getProperty("password");
            String driver = properties.getProperty("driver");
            String url = properties.getProperty("url");
    
    
            Class.forName(driver);
            Connection connection = DriverManager.getConnection(url, user, password);
    
            //3.得到PreparedStatement
            // 3.1 组织一个sql语句 ?:相当于占位符
            String sql = "select name ,pwd from admin where NAME =? and pwd =?";
            // 3.2 preparedStatement 实现了 PreparedStatement 接口的一个实现类的对象
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            // 3.3 给? 赋值
            preparedStatement.setString(1,admin_name);
            preparedStatement.setString(2,admin_pwd);
            //4.执行
            // 这里执行 executeQuery ,不要写sql,之前已经赋值
            ResultSet resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){  //查询到一条记录,则说明该管理存在
                System.out.println("成功");
            }else {
                System.out.println("失败");
            }
            //5.关闭
            resultSet.close();
            preparedStatement.close();
            connection.close();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    五、JDBC API

    在这里插入图片描述

    在这里插入图片描述


    六、事务

    在这里插入图片描述

    不使用事务

    @Test
    public void noTransaction(){
        //操作转账的业务
        //1.得到连接
        Connection connection = null;
        //2.组织sql语句
        String sql = "update account set balance = balance - 100 where id = 1";
        String sql2 = "update account set balance = balance + 100 where id = 2";
        PreparedStatement preparedStatement = null;
        //3.创建PrepareStatement 对象
        try {
            connection = JDBCUtils.getConnection();//在默认情况下,connection对象是默认自动提交
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();//执行第一条sql,并且自动提交commit
            int i = 1/0;         // 会抛出异常,会导致前一条语句执行成功,后一条语句不执行
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate();//执行第二条sql,并且自动提交commit
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    使用事务

    @Test
    //使用事务解决
    public void useTransaction(){
        //1.得到连接
        Connection connection = null;
        //2.组织sql语句
        String sql = "update account set balance = balance - 100 where id = 1";
        String sql2 = "update account set balance = balance + 100 where id = 2";
        PreparedStatement preparedStatement = null;
        //3.创建PrepareStatement 对象
        try {
            connection = JDBCUtils.getConnection();//在默认情况下,connection对象是默认自动提交
            //将connection 设置为不自动提交
            connection.setAutoCommit(false);//相当于开启了事务
            preparedStatement = connection.prepareStatement(sql);
            preparedStatement.executeUpdate();//执行第一条sql
            int i = 1/0;        // 抛出异常,则回滚
            preparedStatement = connection.prepareStatement(sql2);
            preparedStatement.executeUpdate();//执行第二条sql
    
            //若无异常,直接提交事务
            connection.commit();
        } catch (SQLException e) {
            //这里我们可以进行回滚,撤销即将执行的sql
            //默认回滚到事务开始的状态
            System.out.println("执行发生了异常,撤销执行的sql");
            try {
                connection.rollback();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    七、批处理

    1. 当需要成批插入或者更新记录时。可以采用Java的批量更新机制,这一机制允许多条语句一次性提交给数据库批量处理。通常情况下比单独提交处理更有效率
    2. JDBC的批量处理语句包括下面方法:
      JDBC连接MySQL时,如果要使用批处理功能,请再url中加参数? rewriteBatchedStatements=true
      addBatch():添加需要批量处理的SQL语句或参数;
      executeBatch():执行批量处理语句;
      clearBatch():清空批处理包的语句;
    3. 批处理往往和PreparedStatement一起搭配使用,可以既减少编译次数,又减少运行次数,效率大大提高

    代码演示

    package JDBC_Exercise;
    
    import org.junit.jupiter.api.Test;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class Batch_ {
        @Test
        public void noBatch() throws Exception {//3000ms
            Connection connection = JDBCUtils.getConnection();
            String sql = "insert into admin2 values(null,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            System.out.println("开始执行了");
            long start = System.currentTimeMillis();
            for (int i = 0; i < 5000 ; i++) {
                preparedStatement.setString(1,"jack" + i);
                preparedStatement.setString(2,"666");
                preparedStatement.executeUpdate();
            }
            long end = System.currentTimeMillis();
            System.out.println("传统的方式 耗时=" + (end - start));
            JDBCUtils.close(null,preparedStatement,connection);
        }
        //使用批量处理添加数据
        @Test
        public void batch() throws Exception {
            Connection connection = JDBCUtils.getConnection();
            String sql = "insert into admin2 values(null,?,?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            System.out.println("开始执行了");
            long start = System.currentTimeMillis();
            for (int i = 0; i < 5000; i++) {
                preparedStatement.setObject(1,"jack" + i);
                preparedStatement.setObject(2,"666");
                //将sql语句加入到批处理包中 -> 源码
                preparedStatement.addBatch();
                //当有1000条记录时,再批量执行
                if ((i + 1) % 1000 == 0){
                    preparedStatement.executeBatch();
                    //清空
                    preparedStatement.clearBatch();
                }
            }
            long end = System.currentTimeMillis();
            System.out.println("batch的方式 耗时=" + (end - start));
            JDBCUtils.close(null,preparedStatement,connection);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    八、数据库的连接方式

    8.1 传统的连接方式

    在这里插入图片描述

    8.2 数据库的连接池技术

    这里懒得写了,参考了这篇博客

    在这里插入图片描述

    在这里插入图片描述

    8.2.1 C3P0

    前期工作:配置文件
    将C3P0的jar包按照上述jdbc的方式导入项目中,并且书写c3p0-config.xml文件

    <?xml version="1.0" encoding="UTF-8"?>
    <c3p0-config>
    <!--配置连接池mysql-->
        <named-config name="c3p0_mysql">           <!--数据源名称代表连接池 这里等会连接时候使用-->
            <property name="driverClass">com.mysql.jdbc.Driver</property>    <!--驱动类-->
            <property name="jdbcUrl">jdbc:mysql://localhost:3306/mysql?characterEncoding=utf-8&serverTimezone=UTC</property>  <!--url-->
            <property name="user">root</property>            <!--用户名-->
            <property name="password"></property>      <!--密码-->
            <property name="initialPoolSize">10</property>  <!--初始化的连接数-->
            <property name="acquireIncrement">5</property>  <!--每次增长的连接数-->
            <property name="maxIdleTime">30</property>
            <property name="maxPoolSize">60</property>  <!--最大的连接数-->
            <property name="minPoolSize">10</property>   <!--最小的连接数-->
        </named-config>
        <!--配置连接池2,可以配置多个-->
    </c3p0-config>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    方式一:

    @Test
    public void testC3P0_01() throws Exception{
        //1.创建一个数据源对象
        ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
        //2.通过配置文件mysql.propertie获取相关的信息
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\mysql.properties"));
        //读取相关的属性值
        String user = properties.getProperty("user");
        String password = properties.getProperty("password");
        String url = properties.getProperty("url");
        String driver = properties.getProperty("driver");
    
        //给数据源 comboPooledDataSource 设置相关的参数
        //注意:连接管理是由 comboPooledDataSource 来管理
        comboPooledDataSource.setDriverClass(driver);
        comboPooledDataSource.setJdbcUrl(url);
        comboPooledDataSource.setUser(user);
        comboPooledDataSource.setPassword(password);
    
        //设置初始化连接数
        comboPooledDataSource.setInitialPoolSize(10);
        //设置最大连接数
        comboPooledDataSource.setMaxPoolSize(50);
        //测试连接池的效率,测试对mysql 5000ci操作
        long start = System.currentTimeMillis();
        for (int i = 0; i < 5000; i++) {
            //这个方法是从 DataSource 接口实现的
            Connection connection = comboPooledDataSource.getConnection();
            connection.close();
        }
        long end = System.currentTimeMillis();
        System.out.println("c3p0 连接5000次mysql 耗时=" + (end-start));
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    方式二:

    //方式二:使用配置文件模板来完成
    
    //1. 将c3p0 提供的 xml 文件拷贝到src目录下
    //2. 该文件指定了连接数据库和连接池的相关参数
    @Test
    public void testC3P0_02() throws SQLException {
        ComboPooledDataSource com = new ComboPooledDataSource("c3p0_mysql");
        //测试5000次连接MySQL
        long start = System.currentTimeMillis();
        System.out.println("开始执行");
        for (int i = 0; i < 5000; i++) {
            Connection connection = com.getConnection();
            //System.out.println("连接成功---");
            connection.close();
        }
        long end = System.currentTimeMillis();
        System.out.println("c390的第二种方式 耗时=" + (end-start));
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    8.2.2 德鲁伊连接池

    前期工作:配置文件
    将driud的jar包按照上述jdbc的方式导入项目中,并且书写druid.properties文件
    在这里插入图片描述
    演示

    @Test
    public void testDruid() throws Exception {
        //1. 加入jar 包
        //2. 加入配置文件druid.properties
        //3. 创建Properties对象,读取配置文件
        Properties properties = new Properties();
        properties.load(new FileInputStream("src\\druid.properties"));
        //4. 创建一个指定参数的数据库连接池,Druid连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        long start = System.currentTimeMillis();
        for (int i = 0; i < 500000; i++) {
            Connection connection = dataSource.getConnection();
           //System.out.println("连接成功");
            connection.close();
        }
        //druid连接池 操作5000次 耗时268
        long end = System.currentTimeMillis();
        System.out.println("druid连接池 耗时" + (end - start));//耗时332
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    九、自定义连接数据库的工具类

    9.1 自定义JDBCUtils工具类

    JDBCUtils

    package JDBC_Exercise;
    
    import java.io.FileInputStream;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;
    
    /**
     * @author 神代言
     * @version 1.0
     * JDBC连接数据库的工具类
     */
    public class JDBCUtils {
        //定义相关的属性(4个),因为因为只需要一次,因此,我们做成static
        private static String user;//用户名
        private static String password;//密码
        private static String url;//url
        private static String driver;//驱动名字
        //在static代码块中去初始化
        static {
            Properties properties = new Properties();
            try {
                properties.load(new FileInputStream("src\\mysql.properties"));
                //读取相关的属性值
                user = properties.getProperty("user");
                password = properties.getProperty("password");
                url = properties.getProperty("url");
                driver = properties.getProperty("driver");
            } catch (IOException e) {
                //在实际开发中,我们可以这样处理
                //1.将编译异常变成运行异常
                //2.这是调用者,可以选择捕获该异常,也可以选择默认处理该异常,比较方便
                throw new RuntimeException(e);
            }
        }
    
        //连接数据库,返回Connection
        public static Connection getConnection(){
            try {
                return DriverManager.getConnection(url,user,password);
            } catch (SQLException e) {
                //1.将编译异常变成运行异常
                //2.这是调用者,可以选择捕获该异常,也可以选择默认处理该异常,比较方便
                throw new RuntimeException(e);
            }
        }
    
        //关闭相关资源
        /*
            1.ResultSet 结果集
            2.Statement 或者 PrepareStatement
            3.Connection
            4.如果需要关闭资源,就传入对象否则传入null
         */
        public static void close(ResultSet resultSet, Statement statement, Connection connection){
            //判断是否为null
            try {
                if (resultSet!=null){
                    resultSet.close();
                }
                if (statement!=null){
                    statement.close();
                }
                if (connection!=null){
                    connection.close();
                }
            } catch (SQLException e) {
                //将编译异常转成运行异常抛出
                throw new RuntimeException(e);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    测试JDBCUtils

    package JDBC_Exercise;
    
    import org.junit.jupiter.api.Test;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Date;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class JDBCUtils_Use {
        @Test
        public void testDML(){
            //1.得到连接
            Connection connection = null;
            //2.组织sql语句
            String sql = "update actor set name = ? where id = ?";
            //delete 与 insert
            PreparedStatement preparedStatement = null;
            //3.创建PrepareStatement 对象
            try {
                connection = JDBCUtils.getConnection();
                preparedStatement = connection.prepareStatement(sql);
                //给占位符赋值
                preparedStatement.setObject(1,"周星驰");
                preparedStatement.setObject(2,1);
                //执行
                preparedStatement.executeUpdate();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭资源
                JDBCUtils.close(null,preparedStatement,connection);
            }
        }
        @Test
        public void testSelect(){
            //1.得到连接
            Connection connection = null;
            //2.组织sql语句
            String sql = "select * from actor";
            //delete 与 insert
            PreparedStatement preparedStatement = null;
            ResultSet set = null;
            //3.创建PrepareStatement 对象
            try {
                connection = JDBCUtils.getConnection();
                preparedStatement = connection.prepareStatement(sql);
                //执行
                set = preparedStatement.executeQuery();
                //遍历该结果集
                while (set.next()) {
                    int id = set.getInt("id");
                    String name = set.getString("name");
                    String sex = set.getString("sex");
                    Date borndate = set.getDate("borndate");
                    String phone = set.getString("phone");
                    System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭资源
                JDBCUtils.close(set,preparedStatement,connection);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71

    9.2 使用Druid实现JDBCUtils工具类

    编写工具类

    package JDBC_Exercise;
    
    import com.alibaba.druid.pool.DruidDataSourceFactory;
    
    import javax.sql.DataSource;
    import java.io.FileInputStream;
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class JDBCUtilsByDriud {
        private static DataSource ds;
        // 在静态代码块中完成ds的初始化
        static{
            Properties properties = new Properties();
            try {
                properties.load(new FileInputStream("src\\druid.properties"));
                ds = DruidDataSourceFactory.createDataSource(properties);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        // 编写getConnection方法
        public static Connection getConnection() throws SQLException {
            return ds.getConnection();
        }
        // 关闭连接
        // 注意:Driud连接池技术在这里不是断掉连接,而是把连接放回连接池
        /*
            1.ResultSet 结果集
            2.Statement 或者 PrepareStatement
            3.Connection
            4.如果需要关闭资源,就传入对象否则传入null
         */
        public static void close(ResultSet resultSet, Statement statement, Connection connection){
            //判断是否为null
            try {
                if (resultSet!=null){
                    resultSet.close();
                }
                if (statement!=null){
                    statement.close();
                }
                if (connection!=null){
                    connection.close();
                }
            } catch (SQLException e) {
                //将编译异常转成运行异常抛出
                throw new RuntimeException(e);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    测试工具类

    package JDBC_Exercise;
    
    import org.junit.jupiter.api.Test;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.Date;
    
    /**
     * @author 神代言
     * @version 1.0
     * 测试JDBCUtilsByDriud工具类
     */
    public class JDBCUtilsByDriud_Use {
        @Test
        public void testDML(){
            //1.得到连接
            Connection connection = null;
            //2.组织sql语句
            String sql = "update actor set name = ? where id = ?";
            //delete 与 insert
            PreparedStatement preparedStatement = null;
            //3.创建PrepareStatement 对象
            try {
                connection = JDBCUtilsByDriud.getConnection();
                preparedStatement = connection.prepareStatement(sql);
                //给占位符赋值
                preparedStatement.setObject(1,"周星驰");
                preparedStatement.setObject(2,1);
                //执行
                preparedStatement.executeUpdate();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭资源
                JDBCUtilsByDriud.close(null,preparedStatement,connection);
            }
        }
        @Test
        public void testSelect(){
            //1.得到连接
            Connection connection = null;
            //2.组织sql语句
            String sql = "select * from actor";
            //delete 与 insert
            PreparedStatement preparedStatement = null;
            ResultSet set = null;
            //3.创建PrepareStatement 对象
            try {
                connection = JDBCUtilsByDriud.getConnection();
                preparedStatement = connection.prepareStatement(sql);
                //执行
                set = preparedStatement.executeQuery();
                //遍历该结果集
                while (set.next()) {
                    int id = set.getInt("id");
                    String name = set.getString("name");
                    String sex = set.getString("sex");
                    Date borndate = set.getDate("borndate");
                    String phone = set.getString("phone");
                    System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
                }
            } catch (SQLException e) {
                throw new RuntimeException(e);
            } finally {
                //关闭资源
                JDBCUtilsByDriud.close(set,preparedStatement,connection);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72

    十、使用开源的DBUtils工具类操作数据库

    10.1 问题引入

    问题引入

    1. resultSet与connection是关联的,关闭connection后,resultSet结果集无法使用;
    2. resultSet不利于数据管理。
      在这里插入图片描述

    如何解决上述问题?使用原始的方法,创建一个Actor实体类,将resultSet结果集放入一个Actor数组中。

    @Test
    public ArrayList<Actor> testSelectToArrayList(){
        System.out.println("我们使用Druid方式完成");
        //1.得到连接
        Connection connection = null;
        //2.组织sql语句
        String sql = "select * from actor";
        //delete 与 insert
        PreparedStatement preparedStatement = null;
        ResultSet set = null;
        ArrayList<Actor> list = new ArrayList<Actor>();
        //3.创建PrepareStatement 对象
        try {
            connection = JDBCUtilsByDruid.getConnection();
            System.out.println(connection.getClass());//运行类型
            preparedStatement = connection.prepareStatement(sql);
            //执行
            set = preparedStatement.executeQuery();
            //遍历该结果集
            while (set.next()) {
                int id = set.getInt("id");
                String name = set.getString("name");
                String sex = set.getString("sex");
                Date borndate = set.getDate("borndate");
                String phone = set.getString("phone");
                //把得到的result 的记录,封装到 Actor 对象,放入到list集合
                list.add(new Actor(id,name,sex,borndate,phone));
            }
            System.out.println("list集合数据=" + list);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            //关闭资源
            JDBCUtilsByDruid.close(set,preparedStatement,connection);
        }
        return list;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    但是,显然这样还是很麻烦,因此,接下来介绍Apache提供的开源工具类-DBUtils。

    10.2 使用DBUtils+数据连接池(Driud)方式,操作数据库

    在这里插入图片描述
    前期工作:配置文件
    将DBUtils和driud的jar包按照上述jdbc的方式导入项目中,并且书写druid.properties文件

    Actor实体类

    package JDBC_Exercise;
    
    import java.util.Date;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class Actor {
        private Integer id;
        private String name;
        private String sex;
        private Date borndate;
        private String phone;
        public Actor(){
        }
    
        public Actor(Integer id, String name, String sex, Date borndate, String phone) {
            this.id = id;
            this.name = name;
            this.sex = sex;
            this.borndate = borndate;
            this.phone = phone;
        }
    
        @Override
        public String toString() {
            return "Actor{" +
                    "id=" + id +
                    ", name='" + name + '\'' +
                    ", sex='" + sex + '\'' +
                    ", borndate=" + borndate +
                    ", phone='" + phone + '\'' +
                    '}';
        }
    
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getSex() {
            return sex;
        }
    
        public void setSex(String sex) {
            this.sex = sex;
        }
    
        public Date getBorndate() {
            return borndate;
        }
    
        public void setBorndate(Date borndate) {
            this.borndate = borndate;
        }
    
        public String getPhone() {
            return phone;
        }
    
        public void setPhone(String phone) {
            this.phone = phone;
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    演示DBUtils+数据连接池(Driud)

    package JDBC_Exercise;
    
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;
    import org.junit.jupiter.api.Test;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.List;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class DBUtils_Use {
        // 使用apache-DBUtils工具类+driud连接池方式,完成对数据库的操作
    
        @Test
        // 返回结果是多行多列的情况 BeanListHandler
        public void testQueryMany() throws SQLException {
            //1.先得到一个连接 druid
            Connection connection = JDBCUtilsByDruid.getConnection();
            //2.使用DBUtils 类和接口,先引入DBUtils相关的jar文件,加入到本Project
            //3.创建一个 QueryRunner
            QueryRunner queryRunner = new QueryRunner();
            //4.就可以执行相关的方法,返回ArrayList结果集
            String sql = "select * from actor where id >= ?";
            //解读 query 方法就是执行一个sql 语句,得到resultset --封装--> ArrayList 集合中,然后返回集合
            //     query 底层会将resultset和PreparedStatement关闭
            // 1)connection:连接
            // 2)sql:执行的sql语句
            // 3)new BeanListHandler<>(actor.class):将resultset -> actor对象 -> 封装到 ArrayList
            //   底层使用反射机制 去获取actor类的属性,然后进行封装
            // 4)1 就是给sql语句中?赋值的,可以有多个值,因为是可变参数
            List<Actor> list = queryRunner.query(connection, sql, new BeanListHandler<>(Actor.class), 1);
            System.out.println("输出集合的的信息");
            for(Actor actor : list){
                System.out.println(actor);
            }
            //释放资源
            JDBCUtilsByDruid.close(null,null,connection);
        }
        @Test
        // 返回结果是单行多列的情况 BeanHandler
        public void testQuerySingle() throws SQLException {
            Connection connection = JDBCUtilsByDruid.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "select * from actor where id = ?";
            // 单行所以使用的是BeanHandler
            Actor query = queryRunner.query(connection, sql, new BeanHandler<>(Actor.class), 4);
            System.out.println(query);
            JDBCUtilsByDruid.close(null,null,connection);
        }
        @Test
        // 返回结果是单行单列的情况 ScalarHandler
        public void testScalar() throws SQLException {
            Connection connection = JDBCUtilsByDruid.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "select name from actor where id = ?";
            //
            Object query = queryRunner.query(connection, sql, new ScalarHandler(), 1);
            System.out.println(query);
            JDBCUtilsByDruid.close(null,null,connection);
        }
        @Test
        // 完成DML(update,insert,delete)
        public void testDML() throws SQLException {
            Connection connection = JDBCUtilsByDruid.getConnection();
            QueryRunner queryRunner = new QueryRunner();
            String sql = "update actor set name = ? where id = ?";
            // 返回结果是受影响的行数
            int affectedRow = queryRunner.update(connection, sql, "张三丰", 1);
            System.out.println(affectedRow);
            JDBCUtilsByDruid.close(null,null,connection);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78

    十一、【最终版】BasicDao+Druid

    上述apache-DBUtils+Druid 简化了JDBC开发,但还有不足:

    1. SQL 语句是固定,不能通过参数传入,通用性不好,需要进行改进,更方便执行 增删改查;
    2. 对于select 操作,如果有返回值,返回类型不能固定,需要使用泛型;
    3. 将来的表很多,业务需求复杂,不可能只靠一个Java类完成

    框架结构:

    1. com.utils:编写工具类JDBCUtilsByDruid(用于连接/关闭数据库)
    2. com.domain:java bean实体类
    3. com.dao:存放***Dao和BasicDao(其他DAO的父类)(DAO数据访问对象,用于操作数据库的增删改查)
    4. com.test:编写测试类

    在这里插入图片描述
    Actor实体类和JDBCUtilsByDruid工具类上面有,这里就不演示了

    BasicDao

    package JDBC_Exercise.dao;
    
    import JDBC_Exercise.utils.JDBCUtilsByDruid;
    import org.apache.commons.dbutils.QueryRunner;
    import org.apache.commons.dbutils.handlers.BeanHandler;
    import org.apache.commons.dbutils.handlers.BeanListHandler;
    import org.apache.commons.dbutils.handlers.ScalarHandler;
    
    import java.sql.Connection;
    import java.sql.SQLException;
    import java.util.List;
    
    /**
     * @author 神代言
     * @version 1.0
     * 其他Dao的父类,是Dao的共性
     */
    public class BasicDao<T> { //泛型
        private QueryRunner qr = new QueryRunner();
    
        // 更新
        public int update(String sql, Object... parameters) {
            Connection connection = null;
            try {
                connection = JDBCUtilsByDruid.getConnection();
                int update = qr.update(connection, sql, parameters);
                return update;
            } catch (SQLException e) {
                // 将编译异常->运行异常 抛出
                throw new RuntimeException(e);
            } finally {
                JDBCUtilsByDruid.close(null, null, connection);
            }
        }
    
        // 查询(多行)
        /**
         *
         * @param sql sql语句
         * @param classz 传入一个类的class对象,例如:Actor.class
         * @param parameters sql语句中的?对应的参数
         * @return
         */
        public List<T> queryMultiply(String sql, Class<T> classz, Object... parameters) {
            Connection connection = null;
            try {
                connection = JDBCUtilsByDruid.getConnection();
                return qr.query(connection, sql, new BeanListHandler<T>(classz), parameters);
            } catch (SQLException e) {
                // 将编译异常->运行异常 抛出
                throw new RuntimeException(e);
            } finally {
                JDBCUtilsByDruid.close(null, null, connection);
            }
        }
        //查询单行结果的通用方法
        public T querySingle(String sql,Class<T> clazz,Object... parameters){
            Connection connection = null;
            try {
                connection = JDBCUtilsByDruid.getConnection();
                return qr.query(connection,sql,new BeanHandler<T>(clazz),parameters);
            } catch (SQLException e) {
                throw new RuntimeException(e);//将一个编译异常->运行异常
            } finally {
                JDBCUtilsByDruid.close(null,null,connection);
            }
        }
        //查询单行单列的方法,即返回单值的方法
        public Object  queryScalar(String sql,Object... parameters){
            Connection connection = null;
            try {
                connection = JDBCUtilsByDruid.getConnection();
                return qr.query(connection,sql,new ScalarHandler<>(),parameters);
            } catch (SQLException e) {
                throw new RuntimeException(e);//将一个编译异常->运行异常
            } finally {
                JDBCUtilsByDruid.close(null,null,connection);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75
    • 76
    • 77
    • 78
    • 79
    • 80

    ActorDao

    package JDBC_Exercise.dao;
    
    import JDBC_Exercise.domain.Actor;
    
    /**
     * @author 神代言
     * @version 1.0
     * 继承BasicDao,并将自己的class类型传入实现泛型
     */
    public class ActorDao extends BasicDao<Actor> {
        // 继承BasicDao的方法
        // 也可以编写自己的dao方法
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    测试Dao

    package JDBC_Exercise.test;
    
    import JDBC_Exercise.dao.ActorDao;
    import JDBC_Exercise.domain.Actor;
    import org.junit.jupiter.api.Test;
    
    import java.util.List;
    
    /**
     * @author 神代言
     * @version 1.0
     */
    public class TestDao {
        @Test
        public void testActorDao(){
            //1.查询多行记录
            ActorDao actorDao = new ActorDao();
            List<Actor> actors = actorDao.queryMultiply("select * from actor where id >= ?", Actor.class, 1);
            for (Actor actor : actors) {
                System.out.println(actor);
            }
            //2.查询单行记录
            Actor actor = actorDao.querySingle("select * from actor where id = ?", Actor.class, 1);
            System.out.println("查询单行结果");
            System.out.println(actor);
            //3.查询单行单列
            Object o = actorDao.queryScalar("select name from actor where id =?", 3);
            System.out.println("====查询单行单列值=======");
            System.out.println(o);
            //4.dml 操作
            int update = actorDao.update("insert into actor values(null,?,?,?,?)", "岳小琳", "女", "1999-06-01", "13266");
            System.out.println(update > 0?"执行成功":"执行没有影响");
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    特别说明
    本文章是个人整理的学习笔记,参考b站韩顺平老师的课程(【零基础 快速学Java】韩顺平 零基础30天学会Java)。老师讲的非常好,有兴趣的可以去看一下。

  • 相关阅读:
    Selenium自动化测试之Selenium IDE
    ios 使用runtime实现自动解归档
    有哪些好用的供应商管理系统
    论文辅导 | 基于贝叶斯优化-卷积神经网络-双向长短期记忆神经网络的锂电池健康状态评估
    使用 Helm 安装 极狐GitLab
    webpack——webpack环境安装、开发环境devServer、package.json指令相关、开发依赖和生产依赖、面试题
    独立级联(Independent Cascade)模型的原理及代码实现
    Linux权限管理(umask、粘滞位)
    顺序表第三节(通讯录基础版)
    MySQL 创建和管理表
  • 原文地址:https://blog.csdn.net/shendaiyan/article/details/132891715