JDBC核心技术-day2

向数据表中插入Blob类型的数据

//向数据表customers中插入Blob类型的字段
    public void testInsert() throws Exception{
        Connection conn = JDBCUtil.getConnection();
        String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
        PreparedStatement ps = conn.prepareStatement(sql);

        ps.setObject(1,"达达");
        ps.setObject(2,"123@163.com");
        ps.setObject(3,"1992-09-08");
        FileInputStream is = new FileInputStream(new File("C:\\Users\\Administrator\\Desktop\\bird.jpg"));
        ps.setBlob(4,is);

        ps.execute();

        JDBCUtil.closeResource(conn,ps);


    }
 public void testQuery(){
        Connection conn = null;
        PreparedStatement ps = null;
        InputStream is = null;
        FileOutputStream fos = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtil.getConnection();
            String sql = "select id,name,email,birth,photo from customers where id = ?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1,21);

            rs = ps.executeQuery();
            if (rs.next()){
                //方式1:顺序不能改变
    //            int id = rs.getInt(1);
    //            String name = rs.getString(2);
    //            String email = rs.getString(3);
    //            Date birth = rs.getDate(4);
                //方式2:
                int id = rs.getInt("id");
                String name =rs.getString("name");
                String email = rs.getString("email");
                Date birth = rs.getDate("birth");

                Customer cust = new Customer(id,name,email,birth);
                System.out.println(cust);

                //将Blob类型的字段下载下来,以文件的方式保存在本地
                Blob photo = rs.getBlob("photo");
                is = photo.getBinaryStream();
                fos = new FileOutputStream("bird.jpg");
                byte[] buffer = new byte[1024];
                int len;
                while((len = is.read(buffer)) != -1){
                    fos.write(buffer,0,len);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            try {
                if (is != null){
                    is.close();
                }

            } catch (IOException e) {
                e.printStackTrace();
            }
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            JDBCUtil.closeResource(conn,ps,rs);
        }

    }

如果指定了相关的Blob类型以后,还报错 xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数:max_allowed_packet=16M

批量插入数据的操作:
update、delete本身就具有批量操作的效果,此时的批量操作,主要是指批量插入,使用preparedStatement实现高效的批量插入

向goods表中插入2000条数据:

批量插入的方式:

方式1:耗时很久

public void testInsert1() {
    Connection conn = null;
    PreparedStatement ps = null;
    try {
        long start = System.currentTimeMillis();

        conn = JDBCUtil.getConnection();
        String sql = "Insert into goods(name) values(?)";
        ps = conn.prepareStatement(sql);
        for (int i = 1;i <= 20000;i++){
            ps.setObject(1,"name_" + i);

            ps.execute();
        }
        long end = System.currentTimeMillis();

        System.out.println("花费的时间为:" + (end - start));
    } catch (Exception e) {
        e.printStackTrace();
    }
    JDBCUtil.closeResource(conn,ps);
}

方式2:耗时565
addBatch()、exexuteBatch()、clearBacth()
mysql服务器默认是关闭批处理的,我们需要通过一个参数,让Mysql开启批处理的支持,?rewriteBatchStatements=true 写在配置文件url的后面
使用更新的Mysql驱动:mysql-connector-java-5.1.37-bin.jar

 public void testInsert2(){
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            long start = System.currentTimeMillis();

            conn = JDBCUtil.getConnection();
            String sql = "Insert into goods(name) values(?)";
            ps = conn.prepareStatement(sql);
            for (int i = 1;i <= 20000;i++){
                ps.setObject(1,"name_" + i);
                
                //攒sql语句
                ps.addBatch();

                if (i % 500 == 0){
                    //执行bacth
                    ps.execute();
                    //清空batch
                    ps.clearBatch();
                }
            }
            long end = System.currentTimeMillis();

            System.out.println("花费的时间为:" + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        }
        JDBCUtil.closeResource(conn,ps);
    }

方式3:

 @Test
    //设置连接不运行自动提交数据
    public void testInsert3(){
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            long start = System.currentTimeMillis();

            conn = JDBCUtil.getConnection();

            conn.setAutoCommit(false);

            String sql = "Insert into goods(name) values(?)";
            ps = conn.prepareStatement(sql);
            for (int i = 1;i <= 20000;i++){
                ps.setObject(1,"name_" + i);

                ps.addBatch();

                if (i % 500 == 0){
                    ps.execute();

                    ps.clearBatch();
                }
            }
            //提交数据
            conn.commit();
            long end = System.currentTimeMillis();

            System.out.println("花费的时间为:" + (end - start));
        } catch (Exception e) {
            e.printStackTrace();
        }
        JDBCUtil.closeResource(conn,ps);
    }

数据库事务的问题引入:

数据一旦提交,就不可回滚

哪些操作会导致数据的自动提交?
DDL操作一旦执行,就会自动提交
DML默认情况下,一旦执行,就会自动提交,我们可以通过set autocommit = false的方式取消DML操作的自动提交
默认在关闭连接时,会自动的提交数据

考虑事务,数据修改的代码实现:

 @Test
    public void testUpdate() {
        Connection conn = null;
        try {
            conn = JDBCUtil.getConnection();
            System.out.println(conn.getAutoCommit());

            //取消数据的自动提交
            conn.setAutoCommit(false);

            String sql1 = "update user_table set balance = balance - 100 where user = ?";
            update(conn,sql1,"AA");//之前写过的update()方法

            String sql2 = "update user_table set balance = balance + 100 where user = ?";
            update(conn,sql2,"BB");

            System.out.println("转账成功");

            //提交数据
            conn.commit();
        } catch (Exception e) {
        
            e.printStackTrace();
            try {
                //回滚数据
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally {
             //主要针对于使用数据库连接池的使用
            try {
                conn.setAutoCommit(true);
            } catch (SQLException e) {
                e.printStackTrace();
            }
            JDBCUtil.closeResource(conn,null);
        }
    }

JDBC事务处理:

若此时Connection没有被关闭,还可能被重复利用,则需要恢复自动提交状态

数据库连接池:
JDBC的数据库连接池使用javax.sql.DataSource来表示,DataSource只是一个接口,该接口通常由服务器实现。

多种开源的数据库连接池:
DBCP是Apache提高的数据库连接池。tomcat服务器自带dbcp数据库连接池,速度相对c3p0较快,但因自身存在BUG,hibernate3已不再提供使用。

C3P0是一个开源组织提供的一个数据库连接池,速度相对较慢,稳定性还可以,hibernate官方推荐使用。

Druid是阿里提供的数据库连接池,集DBCP,C3P0,Proxool优点于一身的数据库连接池。

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

插入操作:

   @Test
    public void testInsert() throws Exception {
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtil.getConnection1();

            String sql = "insert into customers(name,email,birth)values(?,?,?)";
            int insertCount = runner.update(conn,sql,"蔡徐坤","caixukun@163.com","1997-08-09");
            System.out.println("添加了"+ insertCount + "条记录");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.closeResource(conn,null);
        }

    }

查询操作:

单条

//BeanHander:是ResultSetHandler接口的实现类,用于封装表中的一条记录
  public void QueryTest() throws Exception {
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCUtil.getConnection3();
        String sql = "select id,name,email,birth from customers where id = ?";
        BeanHandler<Customer> handler = new BeanHandler<>(Customer.class);
        Customer customer = runner.query(conn, sql, handler, 23);
    }

多条查询:

//BeanListHandler:是ResultSetHandler接口的实现类,用于封装表中的多条记录构成的集合
  public void QueryTest2() throws Exception {
        QueryRunner runner = new QueryRunner();
        Connection conn = JDBCUtil.getConnection3();
        String sql = "select id,name,email,birth from customers where id = ?";
        BeanListHandler<Customer> handler = new BeanListHandler<>(Customer.class);
        List<Customer> list = runner.query(conn, sql, handler, 23);
        list.forEach(System.out::println);
    }

以Map的形式返回

MapHandler handler = new MapHandler();
Map<String, Object> map =runner.query(conn,sql,handler,23);
System.out.println(map);

查询特殊值:

public void QueryTest4() {
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtil.getConnection3();
            String sql = "select count(*) from customers";
            ScalarHandler handler = new ScalarHandler();
            Long count = (Long) runner.query(conn,sql,handler);
            System.out.println(count);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.closeResource(conn,null);
        }
    }
 @Test
    public void QueryTest5() {
        Connection conn = null;
        try {
            QueryRunner runner = new QueryRunner();
            conn = JDBCUtil.getConnection3();
            String sql = "select id,name,email,birth from customers where id = ?";

            ResultSetHandler<Customer> handler = new ResultSetHandler<Customer>() {
                @Override
                public Customer handle(ResultSet rs) throws SQLException {
//                    System.out.println("handle");
//                    return null;
//                    return  new Customer(12,"cheng","jack@163.com,new Date(5564646264L)");
                    if (rs.next()) {
                        int id = rs.getInt("id");
                        String name = rs.getString("name");
                        String email = rs.getString("email");
                        Date birth = rs.getDate("birth");
                        Customer customer = new Customer(id, name, email, birth);
                        return customer;

                    }
                    return null;
                }
            };
            Customer customer = runner.query(conn, sql, handler, 23);
            System.out.println(customer);

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtil.closeResource(conn,null);
        }
    }
    
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qtayu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值