java学习笔记(三十六)JDBC(二)

1 JDBC进行批处理
1.1 为什么要用批处理?
之前:一次操作只能发送一条sql语句到数据库服务器,效率并不高!如果要插入2000条记录,那么必须发送2000条sql语句。

如果IO流的话,一次写出一个字节,显然效率效率并不高,所以可以使用缓存字节数组提高每次写出的效率。

现在:插入2000条记录,但现在使用sql缓存区,一次发送多条sql到数据库服务器执行。这种做法就叫做批处理。

1.2 JDBC批处理的API
Statement批处理:

    void addBatch(String sql)  添加sql到缓存区(暂时不发送)
    int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql
    void clearBatch()  清空sql缓存区

PreparedStatement批处理:

    void addBatch() 添加参数到缓存区
    int[] executeBatch() 执行批处理命令。 发送所有缓存区的sql
    void clearBatch()  清空sql缓存区

练习:分别测试statement和preparedstatement使用和不使用批处理向学生表插入2000条数据 的效率
package com.pichu;

import java.sql.Connection;
import java.sql.Statement;
import com.JDBCUtil.JdbcUtil;

public class Demo {
public static void main(String[] args) {
long starttime=System.currentTimeMillis();
//statementtest();没有批处理
statementbatch();//添加批处理
long endtime=System.currentTimeMillis();
System.out.println(endtime-starttime);
}

private static void statementbatch() {

    Connection conn  =null;
    Statement stmt = null;
    try{
        //获取连接
        conn = JdbcUtil.getConn();
        //获取statement对象
        stmt = conn.createStatement();
        //每次给stmt这个命令行中添加20条sql语句,一次性进行发送
        for (int i = 1; i <=2000; i++) {
            String sql  = "insert into stu values("+i+",'刘德华');";
            //将这个sql先暂时添加在stmt的命令行中
            stmt.addBatch(sql);
            if (i%20==0) {
                //批量发送sql
                stmt.executeBatch();
                //清空stmt的命令行列表
                stmt.clearBatch();
            }
        }


    }catch(Exception e){
        e.printStackTrace();
    }finally{
        //释放资源
        JdbcUtil.close(conn, stmt, null);
    }
}

private static void statementtest() {
    Connection conn=null;
    Statement stmt=null;
    try {
        //获取链接
        conn=JdbcUtil.getConn();
        //插入2000条数据
        stmt = conn.createStatement();

        for (int i = 1; i <= 2000; i++) {
            String sql="insert into stu values("+i+3+",'李四',50);";

            stmt.executeUpdate(sql);

        }
    //定义sql

    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }finally{
        //释放资源
        JdbcUtil.close(conn, stmt, null);
    }       
}

}
注意:在mysql中使用批处理和不适用批处理效率相差不大,因为mysql不支持sql缓存
2 JDBC获取自增长值
2.1 使用两个参数的prepareStatement()方法,指定可以返回自动增长的键值

 Statement.RETURN_GENERATED_KEYS: 可以返回自动增长值
 Statement.NO_GENERATED_KEYS: 不能返回自动增长值

2.2 获取自增长的值

       stmt.getGeneratedKeys();

练习:在给部门表插入一条数据的同时,再给员工表中刚刚插入的该部门插入一条员工数据

package com.incrementDEmo;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import com.JDBCUtil.JdbcUtil;

/*
 * /需求:在给部门表插入一条数据的同时,再给员工表中刚刚插入的该部门插入一条员工数据
 */
public class IncermentTest {
    public static void main(String[] args) {
        Connection conn=null;
        PreparedStatement stmt=null;
        ResultSet rs=null;
        try {
            //获取连接
            conn=JdbcUtil.getConn();
            //定义sql
            String sql1="INSERT INTO dept (deptName)VALUES(?);";
            String sql2="INSERT INTO employee (name,deptId)VALUES(?,?);";
            stmt = conn.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS);
            stmt.setString(1, "人事部");
            int count = stmt.executeUpdate();
            System.out.println(count);
            rs = stmt.getGeneratedKeys();
            int deptid=0;
            while(rs.next()){
                deptid=rs.getInt(1);
            }
            //预编译第二条sql
            stmt = conn.prepareStatement(sql2);
            stmt.setString(1, "张飞");
            stmt.setInt(2, deptid);
            int count2 = stmt.executeUpdate();
            System.out.println(count2); 
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            JdbcUtil.close(conn, stmt, rs);
        }   
    }
}

3 JDBC处理大数据文件
3.1 什么是大容量
字符:

      存储字符内容: mysql: char(0-255)  varchar(0-65535)  长度有限的。 65535
      大容量的字符字段:
            mysql: text(64K)   longtext(4G字符内容)
            oracle :  clob   longclob           

字节:

        mysql: blob(65kb)   mediumblob(16mb)  longblog(4GB)     
        oracle:   blob

3.1 jdbc操作字符文件
练习:数据库中写入文章

package com.blob_clob;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.Reader;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.JDBCUtil.JdbcUtil;
/**
 * 数据库中写入文章

 */
public class ClobTest {
    public static void main(String[] args) {
        write();
        read();
    }

    private static void read() {
        Connection conn=null;
        PreparedStatement stmt=null;
        ResultSet rs=null;
        //获取连接
        try {
            conn=JdbcUtil.getConn();
            //定义sql
            String sql="select * from news where title=?;";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, "haha");
            rs = stmt.executeQuery();
            while (rs.next()) {
                Reader reader = rs.getCharacterStream(2);
                FileWriter fw = new FileWriter("a.txt");
                int len ;
                char[] cbuf=new char[1024];
                while((len=reader.read(cbuf))!=-1){
                    fw.write(cbuf, 0, len);
                    fw.flush();
                }
                reader.close();
                fw.close(); 
            }   
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            JdbcUtil.close(conn, stmt, rs);
        }   
    }
    private static void write() {
        Connection conn=null;
        PreparedStatement stmt=null;
        //获取连接
        try {
            conn=JdbcUtil.getConn();
            //定义sql
            String sql="insert into news values(?,?);";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, "haha");
            stmt.setClob(2, new FileReader("课堂练习.txt"));
            int count = stmt.executeUpdate();
            System.out.println(count);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            JdbcUtil.close(conn, stmt, null);
        }
    }
}

3.1 jdbc操作字符文件
练习:往数据库中写入图片文件,并读出到本地

package com.blob_clob;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;

import com.JDBCUtil.JdbcUtil;


public class BlobTest {
    public static void main(String[] args) {
        //write();
        read();

    }

    private static void read() {
        Connection conn=null;
        PreparedStatement stmt=null;
        ResultSet rs=null;
        //获取连接
        conn=JdbcUtil.getConn();
        //定义sql
        String sql="select* from pictrue;";
        //创建stmt对象啊
        try {
            stmt = conn.prepareCall(sql);
            //zhixing
            rs = stmt.executeQuery();
            while(rs.next()){
                InputStream is = rs.getBinaryStream(2);
                FileOutputStream fos = new FileOutputStream("h.png");
                int len;
                byte[] buf=new byte[1024];
                while((len=is.read(buf))!=-1){
                    fos.write(buf, 0, len);
                }
                is.close();
                fos.close();
            }


        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //释放资源
            JdbcUtil.close(conn, stmt, null);
        }   
    }

    private static void write()   {
        Connection conn=null;
        PreparedStatement stmt=null;
        //获取连接
        conn=JdbcUtil.getConn();
        //定义sql
        String sql="insert into pictrue values('男沉默女流泪',?);";
        //创建stmt对象啊
        try {
            stmt = conn.prepareCall(sql);
            //给问好设置值
            stmt.setBlob(1, new FileInputStream("批处理.png"));
            //执行
            int count = stmt.executeUpdate();
            System.out.println(count);
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            //释放资源
            JdbcUtil.close(conn, stmt, null);
        }
    }
}

4 数据库事务
4.1 什么是事务?
所谓的事务,如果把多条sql语句看做一个事务,那么这个事务要么一起成功,要么一起失败!!
4.2 mysql事务操作命令
set autocommit =0 / 1; 设置是否自动提交事务
1: 表示自动提交事务,每执行一条sql语句,自动提交事务。
0: 表示关闭自动提交事务。
commit; 提交事务,一旦提交事务不能回滚
rollback; 回滚事务。回滚到事务的起始点。
4.3 jdbc事务操作

    Connection.setAutoCommit(false)  开启事务
    Connection.commit();  成功执行,最后提交事务
    Connection.rollback();  一旦遇到错误,回滚事务

练习:转账操作

package com.transation;

import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;

import com.JDBCUtil.JdbcUtil;

/**
 * 转载操作
 *
 */
public class TransationTest {
    public static void main(String[] args) {
        Connection conn=null;
        Statement stmt=null;
        try {
            //获取连接
            conn=JdbcUtil.getConn();
            //定义sql
            String delSql = "update account set balance=balance-2000 where name='james';";
            String addSql = "update account set balance=balance+2000 where name='weide';";
            stmt = conn.createStatement();
            //开启事务
            conn.setAutoCommit(false);
            stmt.executeUpdate(addSql);
            int u=1/0;
            stmt.executeUpdate(delSql);
            //提交事务
            conn.commit();

        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            //回滚
            try {
                conn.rollback();
            } catch (SQLException e1) {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }finally{
            JdbcUtil.close(conn, stmt, null);
        }

    }

}

4.4事务4大特性

原子性: 要么一起成功过,要么一起失败
一致性: 数据库应该从一个一致性的状态到另一个一致性的状态,保持不变
隔离性: 多个并发事务直接应该可以相互隔离
持久性: 事务一旦提交,应该永久保持下来。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值