当前位置:   article > 正文

JDBC笔记_argodb api

argodb api

第一章

一. JDBC概述

在这里插入图片描述

二.JDBC程序编写顺序

在这里插入图片描述

补充:ODBC(Open Database Connectivity,开放式数据库连接),是微软在Windows平台下推出的。使用者在程序中只需要调用ODBC API,由 ODBC 驱动程序将调用转换成为对特定的数据库的调用请求。

第二章 获取数据库连接

一.Driver接口实现类

1.Driver接口概述

ava.sql.Driver 接口是所有 JDBC 驱动程序需要实现的接口。这个接口是提供给数据库厂商使用的,不同数据库厂商提供不同的实现。

  • 方式一
	@Test
    public void testConnection1() throws SQLException {
        Driver driver = new com.mysql.jdbc.Driver();

        //url:http:localhost:8080/gmall/keyboard.hpg
        //jdbc:mysql:协议
        //localhost:ip协议
        //3306:默认mysql的端口号
        //test:test数据库
        String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
        //?characterEncoding=utf8:设置字符格式
        //封装用户名和密码
        Properties info = new Properties();
        info.setProperty("user","root");
        info.setProperty("password","123456");

        Connection conn = driver.connect(url,info);

        System.out.println(conn);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 方式二:使用反射
    @Test
    public void testConnection2()  throws Exception{
        
        //使用反射
        Class clazz = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver)clazz.newInstance();

        String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
        Properties info = new Properties();
        info.setProperty("user","root");
        info.setProperty("password","123456");

        Connection conn = driver.connect(url,info);
        System.out.println(conn);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 方式三:使用DriverManager替换Driver
    @Test
    public void testConnection3() throws Exception{
        //1.获取Driver实现类的对象
        Class clazz = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver)clazz.newInstance();

        String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
        String user = "root";
        String password = "123456";

        //2.注册驱动
        DriverManager.registerDriver(driver);

        //3.获取连接
        Connection conn = DriverManager.getConnection(url, user, password);

        System.out.println(conn);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 方式四:
    @Test
    public void testConnection4() throws Exception{
        //1.提供基本信息
        String url = "jdbc:mysql://localhost:3306/test?characterEncoding=utf8";
        String user = "root";
        String password = "123456";

        //2.加载Driver
        //连接MySQL数据库时 加载Driver这句代码也可以省略
        Class.forName("com.mysql.jdbc.Driver");
        /*在MySQL的Driver类中,声明了
        static {
            try {
                java.sql.DriverManager.registerDriver(new Driver());
            } catch (SQLException E) {
                throw new RuntimeException("Can't register driver!");
            }
            }
         加载时自动注册了驱动
         */

        //3.获取连接
        Connection conn = DriverManager.getConnection(url, user, password);

        System.out.println(conn);
    }
  • 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
  • 方式五:将数据库连接需要的信息放在配置文件中,获取连接
    配置文件放在src目录下
    @Test
    public void testConnection5() throws Exception{
        //1.读取配置文件的信息
        InputStream rs = Connection.class.getClassLoader().getResourceAsStream("jdbc.properties");

        Properties pro = new Properties();
        pro.load(rs);

        String user = pro.getProperty("user");
        String url = pro.getProperty("url");
        String password = pro.getProperty("password");
        String driverClass = pro.getProperty("driverClass");

        //2.加载Driver
        Class.forName(driverClass);

        //3.连接
        Connection conn = DriverManager.getConnection(url, user, password);

        System.out.println(conn);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

第三章:使用PreparedStatement实现CRUD操作

一.操作和访问数据库

数据库连接被用于向数据库服务器发送命令和 SQL 语句,并接受数据库服务器返回的结果。其实一个数据库连接就是一个Socket连接。
在 java.sql 包中有 3 个接口分别定义了对数据库的调用的不同方式:

  • Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
  • PrepatedStatement:SQL 语句被预编译并存储在此对象中,可以使用此对象多次高效地执行该语句。
  • CallableStatement:用于执行 SQL 存储过程
    在这里插入图片描述

二. 使用Statement操作数据表的弊端

  • 问题一:存在拼串操作,繁琐
  • 问题二:存在SQL注入问题
    如:SELECT user, password FROM user_table WHERE user=‘a’ OR 1 = ’ AND password = ’ OR ‘1’ = ‘1’

三. PreparedStatement的使用

1.实现增删改除

增:

    @Test
    public void testInsert() throws Exception{

        //连接数据库
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");

        Properties pros = new Properties();
        pros.load(is);

        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        String url = pros.getProperty("url");
        String driverClass = pros.getProperty("driverClass");

        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);

        //预编译sql语句,返回PreparedStatement的实例
        String sql = "insert into customers(name,email,birth)values(?,?,?)";
        PreparedStatement pre = conn.prepareStatement(sql);
        pre.setString(1,"哪吒");
        pre.setString(2,"nazha@163.com");
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
        java.util.Date parse = simpleDateFormat.parse("2000-10-08");
        pre.setDate(3,new Date(parse.getTime()));

        //执行操作
        pre.execute();

        //关闭资源
        pre.close();
        conn.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

通用增删改
连接数据库关闭资源封装在JDBCutils.java内

public class JDBCutils {
    public static Connection getConnection() throws Exception{
        //连接数据库
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("jdbc.properties");

        Properties pros = new Properties();
        pros.load(is);

        String user = pros.getProperty("user");
        String password = pros.getProperty("password");
        String url = pros.getProperty("url");
        String driverClass = pros.getProperty("driverClass");

        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
        return conn;
    }

    public static void closeResource(Connection con,Statement pre){
        try {
            if(con != null)
                con.close();
            if(pre != null)
                pre.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}
  • 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
	//通用增删改
    public void Update(String sql,Object ...args){
        Connection conn = null;
        PreparedStatement pre = null;
        try{
        	//连接数据库
            conn = JDBCutils.getConnection();
            pre = conn.prepareStatement(sql);
            //填充占位符
            for(int i = 0;i < args.length;i++){
                pre.setObject(i+1,args[i]);
            }
            //执行操作
            pre.execute();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
        	//关闭资源
            JDBCutils.closeResource(conn,pre);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

测试:

    public void UpdateTest(){
        String sql = "update customers set name = ? where id = ?";
        Update(sql,"Crown","19");
    }
  • 1
  • 2
  • 3
  • 4

2.查询

    @Test
    public void testQuery1() throws Exception{
        Connection conn = JDBCutils.getConnection();
        String sql = "select name,email,birth from customers where id = ?";
        PreparedStatement pre = conn.prepareStatement(sql);
        pre.setObject(1,1);
        //返回结果
        ResultSet resultSet = pre.executeQuery();
        if(resultSet.next()){//判断是否有下一个并指针后移
            String name = resultSet.getString(1);
            String email = resultSet.getString(2);
            Date birth = resultSet.getDate(3);

            Customers customers = new Customers(name, email, birth);
            System.out.println(customers);
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

ORM编程思想
一个数据表对应一个java类,表中的一条记录对应java类的一个对象,表中的一个字段对应java的一个属性。
Java与SQL对应数据类型转换表
在这里插入图片描述
通用查询(针对一个表)

    public Customers queryForCustomers(String sql, Object ...args) throws Exception{
        Connection conn = JDBCutils.getConnection();
        PreparedStatement pre = conn.prepareStatement(sql);
        for(int i=0;i< args.length;i++){
            pre.setObject(i+1,args[i]);
        }

        ResultSet resultSet = pre.executeQuery();
        //获取结果集的元数据 ResultSetMetaDate
        ResultSetMetaData metaData = resultSet.getMetaData();
        //通过ResultSetMetaData获取结果集中的列数
        int columnCount = metaData.getColumnCount();

        if(resultSet.next()){
            Customers cust = new Customers();
            //处理结果集一行数据中的每一个列
            for(int j=0;j<columnCount;j++){
                //获取列值
                Object columValue = resultSet.getObject(j + 1);

                //获取每个列的列名 获取别名:getColumnLabel
                String columnName = metaData.getColumnName(j + 1);

                //将cust对象指定的columnName属性,赋值为columValue,通过反射 注意属性名应该与列名相同,可以通过别名实现
                Field field = Customers.class.getDeclaredField(columnName);
                field.setAccessible(true);
                field.set(cust,columValue);
            }
            return cust;
        }
        JDBCutils.closeResources(conn,pre,resultSet);
        return null;
    }


//测试:
    @Test
    public void testQuertCustomers() throws Exception{
        String sql = "select id,name,birth,email from customers where id = ?";
        Customers customers = queryForCustomers(sql,19);
        System.out.println(customers);
    }
  • 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

针对不同表的查询,返回一条记录(一个对象)
使对象创建为动态

    public <T> T queryForAllTable(Class<T> clazz,String sql, Object ...args) throws Exception{
        Connection conn = JDBCutils.getConnection();
        PreparedStatement pre = conn.prepareStatement(sql);
        for(int i=0;i< args.length;i++){
            pre.setObject(i+1,args[i]);
        }

        ResultSet resultSet = pre.executeQuery();
        //获取结果集的元数据 ResultSetMetaDate
        ResultSetMetaData metaData = resultSet.getMetaData();
        //通过ResultSetMetaData获取结果集中的列数
        int columnCount = metaData.getColumnCount();

        if(resultSet.next()){
            T t = clazz.newInstance();
            //处理结果集一行数据中的每一个列
            for(int j=0;j<columnCount;j++){
                //获取列值
                Object columValue = resultSet.getObject(j + 1);

                //获取每个列的列名
                String columnName = metaData.getColumnName(j + 1);

                //将cust对象指定的columnName属性,赋值为columValue,通过反射
                Field field = clazz.getDeclaredField(columnName);
                field.setAccessible(true);
                field.set(t,columValue);
            }
            return t;
        }
        JDBCutils.closeResources(conn,pre,resultSet);
        return null;
    }
  • 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

针对不同表的查询,返回多条记录(多个对象)
使用List存储对象

    public <T> List<T> QueryForAll(Class<T> clazz, String sql, Object ...args) throws Exception{
        Connection conn = null;
        PreparedStatement pre = null;
        ResultSet resultSet = null;
        try {
            conn = JDBCutils.getConnection();
            pre = conn.prepareStatement(sql);
            for(int i=0;i< args.length;i++){
                pre.setObject(i+1,args[i]);
            }

            resultSet = pre.executeQuery();
            //获取结果集的元数据 ResultSetMetaDate
            ResultSetMetaData metaData = resultSet.getMetaData();
            //通过ResultSetMetaData获取结果集中的列数
            int columnCount = metaData.getColumnCount();
            ArrayList<T> list = new ArrayList<>();
            while(resultSet.next()){
                T t = clazz.newInstance();
                //处理结果集一行数据中的每一个列
                for(int j=0;j<columnCount;j++){
                    //获取列值
                    Object columValue = resultSet.getObject(j + 1);

                    //获取每个列的列名
                    String columnName = metaData.getColumnName(j + 1);

                    //将cust对象指定的columnName属性,赋值为columValue,通过反射
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t,columValue);
                }
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResources(conn,pre,resultSet);
        }
        return null;
    }
  • 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

3.解决注入问题

PrepareStatement 预编译SQL语句

第4章 操作BLOB类型字段

一.MySQL BLOB类型

在这里插入图片描述

二.向数据表中插入大数据类型

    @Test
    public void testInsert() throws Exception{
        Connection conn = JDBCutils.getConnection();
        String sql = "insert into customers values(?,?,?,?,?)";
        PreparedStatement pre = conn.prepareStatement(sql);

        pre.setObject(1,21);
        pre.setObject(2,"yun");
        pre.setObject(3,"yun@123.com");
        pre.setObject(4,"00-00-00");
        
        FileInputStream fileInputStream = new FileInputStream(new File("lib/1.png"));
        pre.setBlob(5,fileInputStream);

        pre.execute();

        JDBCutils.closeResource(conn,pre);

    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

三.查询数据表中Blob类型的字段

    @Test
    public void readTest() throws Exception{
        InputStream is = null;
        FileOutputStream fos = null;
        Connection conn = JDBCutils.getConnection();
        String sql = "select id,name,email,birth,photo from customers where id = ?";
        PreparedStatement pre = conn.prepareStatement(sql);
        pre.setObject(1,16);
        ResultSet rs = pre.executeQuery();
        if(rs.next()){
            int id = rs.getInt("id");
            String name = rs.getString("name");
            String email = rs.getString("email");
            Date birth = rs.getDate("birth");
            Customers customers = new Customers(id, name, email, birth);
            System.out.println(customers);
            //使用文件的格式存储下来
            Blob photo = rs.getBlob("photo");
            is = photo.getBinaryStream();
            fos = new FileOutputStream("zhuyin.jpg");
            byte[] buffer = new byte[100000000];
            int len;
            if((len = is.read(buffer)) != -1){
                fos.write(buffer,0,len);
            }

        }
        JDBCutils.closeResources(conn,pre,rs);
        is.close();
        fos.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

如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数: max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。

第5章 批量插入

一.批量执行SQL语句

update,delete本身就具有批量操作的效果
批量插入方式一

    @Test
    public void InsertTest() throws Exception{
        Connection conn = JDBCutils.getConnection();
        String sql = "insert into goods(name)values(?)";
        PreparedStatement pre = conn.prepareStatement(sql);
        for(int i = 1;i <= 2000;i++){
            pre.setString(1,"name"+i);
            pre.execute();
        }
        JDBCutils.closeResource(conn,pre);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

批量插入方式二

  • addBatch():添加需要批量处理的SQL语句或是参数;
  • executeBatch():执行批量处理语句;
  • clearBatch():清空缓存的数据

mysql服务器默认是关闭批处理的,我们需要通过一个参数,让mysql开启批处理的支持。
?rewriteBatchedStatements=true 写在配置文件的url后面

    @Test
    public void InsertTest1() throws Exception{
        Connection conn = JDBCutils.getConnection();
        String sql = "insert into goods(name)values(?)";
        PreparedStatement pre = conn.prepareStatement(sql);
        for(int i = 1;i <= 2000;i++){
            pre.setString(1,"name"+i);
            //"攒"batch
            pre.addBatch();
            if(i % 100 == 0)
                //执行batch
                pre.executeBatch();
                //清空batch
                pre.clearBatch();
        }
        JDBCutils.closeResource(conn,pre);
    }

}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

取消自动提交并手动提交

    @Test
    public void InsertTest2() throws Exception{
        Connection conn = JDBCutils.getConnection();
        String sql = "insert into goods(name)values(?)";
        PreparedStatement pre = conn.prepareStatement(sql);

        //设置不允许自动提交
        conn.setAutoCommit(false);
        for(int i = 1;i <= 2000;i++){
            pre.setString(1,"name"+i);
            //"攒"batch
            pre.addBatch();
            if(i % 100 == 0)
                //执行batch
                pre.executeBatch();
            //清空batch
            pre.clearBatch();
        }
        //提交数据
        conn.commit();
        
        JDBCutils.closeResource(conn,pre);
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

第6章: 数据库事务

一.事务处理(事务操作):

保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),那么这些修改就永久地保存下来;要么数据库管理系统将放弃所作的所有修改,整个事务**回滚(rollback)**到最初状态。

二.JDBC事务处理

JDBC程序中为了让多个 SQL 语句作为一个事务执行:

  • 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务(DDL语句不行,使用DML)
  • 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务
  • 在出现异常时,调用 rollback(); 方法回滚事务

若此时 Connection 没有被关闭,还可能被重复使用,则需要恢复其自动提交状态 setAutoCommit(true)。尤其是在使用数据库连接池技术时,执行close()方法前,建议恢复自动提交状态。

例:AA转账给BB

public class TransactionTest {
    //通用增删改(事务版本)
    public void Update(Connection conn, String sql, Object ...args) throws Exception{
        PreparedStatement pre = conn.prepareStatement(sql);
        for(int i = 0;i < args.length;i++){
            pre.setObject(i+1,args[i]);
        }
        pre.execute();
        JDBCutils.closeResource(null,pre);
    }
    @Test
    //事务演示例子
    public void test(){
        Connection connection = null;
        try {
            connection = JDBCutils.getConnection();
            connection.setAutoCommit(false);
            String sql1 = "update user_table set balance = balance - 100 where user = ?";
            Update(connection,sql1,"AA");


            String sql2 = "update user_table set balance = balance + 100 where user = ?";
            Update(connection,sql2,"BB");
            connection.commit();
            System.out.println("成功");
        } catch (Exception e) {
            try {
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally {
            try {
                connection.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            JDBCutils.closeResource(connection,null);
        }
    }
}
  • 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

三.事务的ACID属性

1.原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

2.一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态。

3.隔离性:事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。

4.持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响。

四.并发问题

对于同时运行的多个事务, 当这些事务访问数据库中相同的数据时, 如果没有采取必要的隔离机制, 就会导致各种并发问题:

  • 脏读: 对于两个事务 T1, T2, T1 读取了已经被 T2 更新但还没有被提交的字段。之后, 若 T2 回滚, T1读取的内容就是临时且无效的。
  • 不可重复读: 对于两个事务T1, T2, T1 读取了一个字段, 然后 T2 更新了该字段。之后, T1再次读取同一个字段, 值就不同了。
  • 幻读: 对于两个事务T1, T2, T1 从一个表中读取了一个字段, 然后 T2 在该表中插入了一些新的行。之后, 如果 T1 再次读取同一个表, 就会多出几行。

五.四种隔离级别

在这里插入图片描述

  • Oracle 支持的 2 种事务隔离级别:READ COMMITED, SERIALIZABLE。 Oracle 默认的事务隔离级别为: READ COMMITED

  • Mysql 支持 4 种事务隔离级别。Mysql 默认的事务隔离级别为: REPEATABLE READ。

五.在MySql中设置隔离级别

  • 每启动一个 mysql 程序, 就会获得一个单独的数据库连接. 每个数据库连接都有一个全局变量 @@tx_isolation, 表示当前的事务隔离级别。

  • 查看当前的隔离级别:

    SELECT @@tx_isolation;
    
    • 1
  • 设置当前 mySQL 连接的隔离级别:

    set  transaction isolation level read committed;
    
    • 1
  • 设置数据库系统的全局的隔离级别:

    set global transaction isolation level read committed;
    
    • 1
  • 补充操作:

    • 创建mysql数据库用户:

      create user tom identified by 'abc123';
      
      • 1
    • 授予权限

      #授予通过网络方式登录的tom用户,对所有库所有表的全部权限,密码设为abc123.
      grant all privileges on *.* to tom@'%'  identified by 'abc123'; 
      
       #给tom用户使用本地命令行方式,授予atguigudb这个库下的所有表的插删改查的权限。
      grant select,insert,delete,update on atguigudb.* to tom@localhost identified by 'abc123'; 
      
      • 1
      • 2
      • 3
      • 4
      • 5

第7章:DAO及相关实现类

类 BaseDAO.java:封装增删改查,查询等操作

public abstract class BaseDao {
    //通用增删改
    public int update(Connection conn,String sql, Object ...args){
        PreparedStatement pre = null;
        try{
            //连接数据库
            conn = JDBCutils.getConnection();
            pre = conn.prepareStatement(sql);
            //填充占位符
            for(int i = 0;i < args.length;i++){
                pre.setObject(i+1,args[i]);
            }
            //执行操作
            pre.execute();
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            //关闭资源
            JDBCutils.closeResource(null,pre);
        }
        return 0;
    }


    //通用查询一个表
    public <T> T getInstance(Connection conn,Class<T> clazz,String sql, Object ...args){
        PreparedStatement pre = null;
        ResultSet resultSet = null;
        try {
            pre = conn.prepareStatement(sql);
            for(int i=0;i< args.length;i++){
                pre.setObject(i+1,args[i]);
            }

            resultSet = pre.executeQuery();
            //获取结果集的元数据 ResultSetMetaDate
            ResultSetMetaData metaData = resultSet.getMetaData();
            //通过ResultSetMetaData获取结果集中的列数
            int columnCount = metaData.getColumnCount();
            if(resultSet.next()){
                T t = null;
                try {
                    t = clazz.newInstance();
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //处理结果集一行数据中的每一个列
                for(int j=0;j<columnCount;j++){
                    //获取列值
                    Object columValue = resultSet.getObject(j + 1);

                    //获取每个列的列名
                    String columnName = metaData.getColumnName(j + 1);

                    //将cust对象指定的columnName属性,赋值为columValue,通过反射
                    Field field = null;
                    try {
                        field = clazz.getDeclaredField(columnName);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                    field.setAccessible(true);
                    try {
                        field.set(t,columValue);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
                return t;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            JDBCutils.closeResources(null,pre,resultSet);
        }
        return null;
    }


    //查询多条记录
    public <T> List<T> getForList(Connection conn,Class<T> clazz, String sql, Object ...args){
        PreparedStatement pre = null;
        ResultSet resultSet = null;
        try {
            conn = JDBCutils.getConnection();
            pre = conn.prepareStatement(sql);
            for(int i=0;i< args.length;i++){
                pre.setObject(i+1,args[i]);
            }

            resultSet = pre.executeQuery();
            //获取结果集的元数据 ResultSetMetaDate
            ResultSetMetaData metaData = resultSet.getMetaData();
            //通过ResultSetMetaData获取结果集中的列数
            int columnCount = metaData.getColumnCount();
            ArrayList<T> list = new ArrayList<>();
            while(resultSet.next()){
                T t = clazz.newInstance();
                //处理结果集一行数据中的每一个列
                for(int j=0;j<columnCount;j++){
                    //获取列值
                    Object columValue = resultSet.getObject(j + 1);

                    //获取每个列的列名
                    String columnName = metaData.getColumnName(j + 1);

                    //将cust对象指定的columnName属性,赋值为columValue,通过反射
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t,columValue);
                }
                list.add(t);
            }
            return list;
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResources(null,pre,resultSet);
        }
        return null;
    }

    //查询特殊值
    public <E> E getValue(Connection conn,String sql,Object ...args){
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            ps = conn.prepareStatement(sql);
            for(int i = 0;i < args.length;i++){
                ps.setObject(i+1,args[i]);

            }
            rs = ps.executeQuery();
            if(rs.next()){
                return (E) rs.getObject(1);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResources(null,ps,rs);
        }
        return null;
    }
}
  • 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
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144

抽象接口:CustomerDAO:定义各种功能

public interface CustomerDAO {
    //将cust对象添加到数据库中
    void insert(Connection conn, Customers cust);

    //根据id删除表中一条记录
    void delete(Connection conn,int id);

    //针对内存中的cust对象,去修改数据表中指定的记录
    void update(Connection conn,Customers cust);

    //针对指定的id查询得到对应Customers对象
    Customers getCutsomerByID(Connection conn,int id);

    //查询表中的所有记录构成的集合
    List<Customers> getAll(Connection conn);

    //查询表有多少条记录
    Long getCount(Connection conn);

    //返回数据表中最大的生日
    Date getMaxBirth(Connection conn);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

类 CustomerDAOImpl:继承BaseDAO和CustomerDAO,功能的具体实现

public class CustomerDAOImpl extends BaseDao implements CustomerDAO{
    @Override
    public void insert(Connection conn, Customers cust) {
        String sql = "insert into customers(id,name,email,birth) values(?,?,?,?)";
        update(conn,sql,cust.getId(),cust.getName(),cust.getEmail(),cust.getBirth());
    }

    @Override
    public void delete(Connection conn, int id) {
        String sql = "delete from customers where id = ?";
        update(conn,sql,id);
    }

    @Override
    public void update(Connection conn, Customers cust) {
        String sql = "update customers set name = ?,email = ?,birth = ? where id = ?";
        update(conn,sql,cust.getName(),cust.getEmail(),cust.getBirth(),cust.getId());
    }

    @Override
    public Customers getCutsomerByID(Connection conn, int id) {
        String sql = "select id,name,email,birth from customers where id = ?";
        return getInstance(conn,Customers.class,sql,id);
    }

    @Override
    public List<Customers> getAll(Connection conn) {
        String sql = "select id,name,email,birth from customers";
        return getForList(conn,Customers.class,sql);
    }

    @Override
    public Long getCount(Connection conn) {
        String sql = "select count(*) from customers";
        return getValue(conn,sql);
    }

    @Override
    public Date getMaxBirth(Connection conn) {
        String sql = "select MAX(birth) from customers";
        return getValue(conn,sql);
    }
}
  • 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

测试:

public class CustomerDAOImplTest  {
    CustomerDAOImpl customerDAO = new CustomerDAOImpl();
    @Test
    void testInsert() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            Customers cust = new Customers(22, "abc", "abc@126.com", new Date(213131131331L));
            customerDAO.insert(conn,cust);
            System.out.println("添加成功");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }

    @Test
    void testDelete() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            customerDAO.delete(conn,22);
            System.out.println("删除成功");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }

    @Test
    void testUpdate() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            Customers cust = new Customers(12, "黎明", "liming@111.com", new Date(21212112L));
            customerDAO.update(conn,cust);
            System.out.println("更新成功");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }

    @Test
    void testGetCutsomerByID() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            Customers cutsomerByID = customerDAO.getCutsomerByID(conn, 20);
            System.out.println(cutsomerByID);
            System.out.println("更新成功");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }

    @Test
    void testGetAll() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            List<Customers> list = customerDAO.getAll(conn);
            list.forEach(System.out::println);
            System.out.println("更新成功");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }

    @Test
    void testGetCount() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            Long count = customerDAO.getCount(conn);
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }

    @Test
    void testGetMaxBirth() {
        Connection conn = null;
        try {
            conn = JDBCutils.getConnection();
            Date maxBirth = customerDAO.getMaxBirth(conn);
            System.out.println(maxBirth);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCutils.closeResource(conn,null);
        }
    }
}
  • 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
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104

优化
既然已经定义为Customers数据表下的功能,就没有必要在BaseDAO中查询时将Customers.class作为参数之一。作出以下修改:将BaseDAO改为泛型类,并写一个方法:泛型获取泛型类型
在这里插入图片描述

方法名修改(类已经定义为泛型,则方法名不需要重复定义):
在这里插入图片描述
在这里插入图片描述

第8章:数据库连接池

一.JDBC数据库连接池的必要性

**对于每一次数据库连接,使用完后都得断开。**否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将导致重启数据库。(回忆:何为Java的内存泄漏?)

二.数据库连接池技术

数据库连接池的基本思想:就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。

1.工作原理

在这里插入图片描述

2.多种开源的数据库连接池

  • DBCP 是Apache提供的数据库连接池。tomcat 服务器自带dbcp数据库连接池。速度相对c3p0较快,但因自身存在BUG,Hibernate3已不再提供支持。
  • C3P0 是一个开源组织提供的一个数据库连接池,**速度相对较慢,稳定性还可以。**hibernate官方推荐使用
  • Proxool 是sourceforge下的一个开源项目数据库连接池,有监控连接池状态的功能,稳定性较c3p0差一点
  • BoneCP 是一个开源组织提供的数据库连接池,速度快
  • Druid 是阿里提供的数据库连接池,据说是集DBCP 、C3P0 、Proxool 优点于一身的数据库连接池,但是速度不确定是否有BoneCP快

DataSource 通常被称为数据源,它包含连接池和连接池管理两个部分,习惯上也经常把 DataSource 称为连接池
DataSource用来取代DriverManager来获取Connection,获取速度快,同时可以大幅度提高数据库访问速度。
注意:

  • 数据源和数据库连接不同,数据源无需创建多个,它是产生数据库连接的工厂,因此整个应用只需要一个数据源即可。
  • 当数据库访问结束后,程序还是像以前一样关闭数据库连接:conn.close(); 但conn.close()并没有关闭数据库的物理连接,它仅仅把数据库连接释放,归还给了数据库连接池。

3.C3P0数据池

  • 方式一:
    @Test
    public void testGetConnection() throws Exception{
        //获取c3p0数据库连接池
        ComboPooledDataSource cpds = new ComboPooledDataSource();
        cpds.setDriverClass( "com.mysql.jdbc.Driverr" ); //loads the jdbc driver
        cpds.setJdbcUrl( "jdbc:mysql://localhost::3306/test" );
        cpds.setUser("root");
        cpds.setPassword("123456");

        //设置初始时数据库池中的连接数
        cpds.setInitialPoolSize(10);

        Connection conn = cpds.getConnection();
        System.out.println(conn);

        //销毁c3p0数据库连接池
//        DataSources.destroy(cpds);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 方式二:使用配置文件 xml
    xml文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<c3p0-config>

    <!-- This app is massive! -->
    <named-config name="helloc3p0">
        <!-- 提供获取连接的四个基本信息-->
        <property name="dricerClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql:///test</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <!-- 进行数据库连接池管理的基本信息-->
        <!--当数据库连接池的连接数不够时,c3p0一次性向数据库服务器申请的连接数 -->
        <property name="acquireIncrement">5</property>
        <!-- c3p0数据库连接池中初始化时的连接数-->
        <property name="initialPoolSize">10</property>
        <!-- c3p0数据库连接池维护的最少连接数 -->
        <property name="minPoolSize">10</property>
        <!-- c3p0数据库连接池维护的最多连接数-->
        <property name="maxPoolSize">100</property>
        <!--c3p0数据库连接池最多维护的Statement的个数 -->
        <property name="maxStatements">50</property>
        <!--每个连接中最多使用的Statement的个数 -->
        <property name="maxStatementsPerConnection">5</property>
    </named-config>
</c3p0-config>
  • 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
    //方式二:使用配置文件 xml
    @Test
    public void testGetConnection1() throws Exception{
        ComboPooledDataSource cpds = new ComboPooledDataSource("helloc3p0");
        Connection conn = cpds.getConnection();
        System.out.println(conn);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

4.Druid(德鲁伊)数据库连接池:可以说是目前最好的连接池之一。

使用配置文件读入
创建druid.properties

jdbcUrl=jdbc:mysql:///test
username=root
password=123456
driverClassName=com.mysql.jdbc.Driver
  • 1
  • 2
  • 3
  • 4
    @Test
    public void getConnection() throws Exception{
        Properties pros = new Properties();
        InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream("druid.properties");
        pros.load(is);
        DataSource dataSource = DruidDataSourceFactory.createDataSource(pros);
        Connection conn = dataSource.getConnection();
        System.out.println(conn);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

第九章 Apache-DBUtils实现CRUD操作

一.简介

commons-dbutils 是 Apache 组织提供的一个开源 JDBC工具类库,它是对JDBC的简单封装,学习成本极低,并且使用dbutils能极大简化jdbc编码的工作量,同时也不会影响程序的性能。

二.QueryRunner类的使用

1.更新

     @Test
    public void test() throws Exception{
         QueryRunner runner = new QueryRunner();
         Connection conn = JDBCutils.getConnection();
         String sql = "insert into customers(name,email,birth) values(?,?,?)";
         int insertCount = runner.update(conn, sql, "蔡徐坤", "caixukun@123.com", "1997-02-13");
         System.out.println("添加了" + insertCount + "条记录");
         JDBCutils.closeResource(conn,null);
     }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.查询 ResultSetHandler

  • 查询1:单条记录
     @Test
     //查询1:查询一条记录 BeanHandler
    public void Query1() throws Exception {
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCutils.getConnection();
        String sql = "select name,email,birth from customers where id = ?";
        //BeanHander:是ResultSetHandler接口的实现类,用于封装表中的一条记录
        BeanHandler<Customers> rsh = new BeanHandler<>(Customers.class);
        //query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
         Customers cust = runner.query(conn, sql, rsh, 21);
         System.out.println(cust);
         JDBCutils.closeResource(conn,null);
     }

    @Test
    //查询1:查询一条记录 MapHandler
    public void Query3() throws Exception{
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCutils.getConnection();
        String sql = "select name,email,birth from customers where id = ?";
        //MapHander:是ResultSetHandler接口的实现类,对应表中的一条记录,将字段及相应字段的值作为map中的key和value
        MapHandler handler = new MapHandler();
        Map<String, Object> map = runner.query(conn, sql, handler, 21);
        System.out.println(map);
        JDBCutils.closeResource(conn,null);
    }

  • 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
  • 查询2:多条记录 ·
    @Test
    //查询2:查询多条记录BeanListHandler
    public void Query2() throws Exception {
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCutils.getConnection();
        String sql = "select name,email,birth from customers";
        //BeanListHander:是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合
        BeanListHandler<Customers> rsh = new BeanListHandler<>(Customers.class);
        //query(Connection conn, String sql, ResultSetHandler<T> rsh, Object... params)
        List<Customers> cust = runner.query(conn, sql, rsh);
        cust.forEach(System.out::println);
        JDBCutils.closeResource(conn,null);
    }

    @Test
    //查询2:查询多条记录MapListHandler
    public void Query4() throws Exception{
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCutils.getConnection();
        String sql = "select name,email,birth from customers";
        //MapHander:是ResultSetHandler接口的实现类,对应表中的多条记录的集合,将字段及相应字段的值作为map中的key和value,将这些map添加到List中。
        MapListHandler handler = new MapListHandler();
        List<Map<String, Object>> list = runner.query(conn, sql, handler);
        list.forEach(System.out::println);
        JDBCutils.closeResource(conn,null);
    }
  • 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
  • ScalarHandler 特殊值
    @Test
    public void Query5() throws Exception{
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCutils.getConnection();
        String sql = "select count(*) from customers";
        ScalarHandler handler = new ScalarHandler();
        Long count = (Long) runner.query(conn, sql, handler);
        System.out.println(count);
        JDBCutils.closeResource(conn,null);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

3.自定义ResultSetHandler

    @Test
    public void Query6() throws Exception {
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCutils.getConnection();
        String sql = "select id,name,email,birth from customers where id = ?";
        ResultSetHandler<Customers> rsh = new ResultSetHandler<Customers>() {
            @Override
            public Customers handle(ResultSet resultSet) throws SQLException {
                if(resultSet.next()){
                    int id = resultSet.getInt("id");
                    String name = resultSet.getString("name");
                    String email = resultSet.getString("email");
                    Date birth = resultSet.getDate("birth");
                    return new Customers(id,name,email,birth);
                }
                return null;
            }
        };
        Customers cust = runner.query(conn, sql, rsh, 21);
        System.out.println(cust);
        JDBCutils.closeResource(conn,null);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

三.DBUtils

DbUtils :提供如关闭连接、装载JDBC驱动程序等常规工作的工具类,里面的所有方法都是静态的。

        DbUtils.close(conn);
        /*
        public static void close(Connection conn) throws SQLException {
            if (conn != null) {
                conn.close();
            }        
         */
        DbUtils.closeQuietly(conn);
/*        public static void closeQuietly(Connection conn) {
            try {
                close(conn);
            } catch (SQLException var2) {
            }

        }*/
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/木道寻08/article/detail/904264
推荐阅读
相关标签
  

闽ICP备14008679号