一、批处理
1、原因:提高jdbc操作效率,一次发送多条SQL到数据库服务器执行
2、方法(API):
(1)Statement批处理:
主要方法:
void addBatch(String sql) 添加sql到缓存区(暂时不发送)
int[]executeBatch() 执行批处理命令。 发送所有缓存区的sql
voidclearBatch() 清空sql缓存区
(3)PreparedStatement批处理:
主要方法:
voidaddBatch() 添加参数到缓存区
int[]executeBatch() 执行批处理命令。 发送所有缓存区的sql
voidclearBatch() 清空sql缓存区
举例:
1、往一张表中插入2000条数据:
分别使用了Statement批处理和PreparedStatement批处理
和不使用批处理的这两个方法进行对比:
package com.deu.a.statement.preparedstatement;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.Statement;
import com.jdbc.c.util.JdbcUtil;
public class Demo {
public static void main(String[] args) {
long starttime = System.currentTimeMillis();
//testStatemet();//不使用批处理忘数据库学生表中插入2000条数据//76268
//testStatementBatch();//使用批处理//3837
//testPreparedment();//采用预编译,不使用批处理//72041
testPreparedmentBatch();//使用批处理//4321
long endtime = System.currentTimeMillis();
System.out.println(endtime-starttime);
}
private static void testPreparedmentBatch() {
Connection conn = null;
PreparedStatement stmt = null;
try{
//获取连接
conn = JdbcUtil.getConnection();
String sql = "INSERT INTO student VALUES(?,?);";
//获取statement对象
stmt = conn.prepareStatement(sql);
for (int i = 1; i <= 2000; i++) {
stmt.setInt(1, i);
stmt.setString(2, "hello");
stmt.addBatch();
if (i%20==0) {
///执行sql语句
stmt.executeUpdate();
//清空缓存
stmt.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
JdbcUtil.close(conn, stmt, null);
}
}
private static void testPreparedment() {
Connection conn = null;
PreparedStatement stmt = null;
try{
//获取连接
conn = JdbcUtil.getConnection();
String sql = "INSERT INTO student VALUES(?,?);";
//获取statement对象
stmt = conn.prepareStatement(sql);
for (int i = 1; i <= 2000; i++) {
stmt.setInt(1, i);
stmt.setString(2, "hello");
stmt.executeUpdate();
}
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
JdbcUtil.close(conn, stmt, null);
}
}
private static void testStatementBatch() {
Connection conn = null;
Statement stmt = null;
try{
//获取连接
conn = JdbcUtil.getConnection();
//获取statement对象
stmt = conn.createStatement();
//给数据库发送2000次sql语句
//每次给stmt中存储添加20条数据
for (int i = 1; i < 2000; i++) {
String sql = "INSERT INTO student VALUES("+i+",'hello');";
//先将这个sql暂时添加到stmt中
stmt.addBatch(sql);
if (i%20==0) {
//批量发送sql
stmt.executeUpdate(sql);
//清空stmt缓冲区
stmt.clearBatch();
}
}
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
JdbcUtil.close(conn, stmt, null);
}
}
private static void testStatemet() {
Connection conn = null;
Statement stmt = null;
try{
//获取连接
conn = JdbcUtil.getConnection();
//获取statement对象
stmt = conn.createStatement();
//给数据库发送2000次sql语句
for (int i = 1; i < 2000; i++) {
String sql = "INSERT INTO student VALUES("+i+",'hello');";
stmt.executeUpdate(sql);
}
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
JdbcUtil.close(conn, stmt, null);
}
}
}
二、jdbc获取自增长值
package com.deu.b.getautocreament;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import com.jdbc.c.util.JdbcUtil;
/**
* 获取自增长值
*需求:在给部门表插入一条数据的同时,再给员工表中刚刚插入的该部门插入一条员工数据
* 1.给部门表中插入一个新的部门“财务部”
* 2.获取财务部对应的id
* 3.给员工表中插入一条员工数据,对应的部门就是财务部对应的id
*/
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
//创建两条sql语句
//创建给部门表添加数据
String sql1 = "insert into dept(name) values(?);";
String sql2 = "insert into employee(name,deptId) values(?,?);";
try{
conn = JdbcUtil.getConnection();
//先给部门表中插入数据
//PreparedStatement prepareStatement(String sql, int autoGeneratedKeys)throws SQLException
//创建一个默认 PreparedStatement 对象,该对象能获取自动生成的键
//Statement.RETURN_GENERATED_KEYS: 可以返回自动增长值
//Statement.NO_GENERATED_KEYS: 不能返回自动增长值
stmt = conn.prepareStatement(sql1, Statement.RETURN_GENERATED_KEYS);
//设置参数
stmt.setString(1, "后勤部");
//提交数据
stmt.executeUpdate();
//获取自增长的键值
rs = stmt.getGeneratedKeys();
int deptId = 0;
while (rs.next()) {
deptId = rs.getInt(1);
}
//给员工表添加数据
stmt = conn.prepareStatement(sql2);
stmt.setString(1, "咋打");
stmt.setInt(2, deptId);
stmt.executeUpdate();
}catch(Exception e){
e.printStackTrace();
}finally{
//释放资源
JdbcUtil.close(conn, stmt, rs);
}
}
}
三、jdbc处理大数据文件
字符:
普通存储字符字段: 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
举例:
1、jdbc操作字符文件
将任意一篇文章存储到数据库:
package com.deu.c.club;
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.jdbc.c.util.JdbcUtil;
public class ClubDemo {
public static void main(String[] args) {
//写入数据
//write();
//读取数据
readerd();
}
private static void readerd() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try{
//获取连接
conn = JdbcUtil.getConnection();
//创建预编译sql对象
String sql = "select * from test;";
//创建PreparedStatement
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while (rs.next()) {
Reader reder = rs.getCharacterStream(2);
FileWriter fw = new FileWriter("a.java");
char[] cha = new char[1024];
int len;
while ((len=reder.read(cha))!=-1) {
fw.write(cha, 0, len);
fw.flush();
}
//关流
fw.close();
reder.close();
}
}catch (Exception e) {
e.printStackTrace();
}finally{
JdbcUtil.close(conn, stmt, rs);
}
}
private static void write() {
Connection conn = null;
PreparedStatement stmt = null;
try{
//获取连接
conn = JdbcUtil.getConnection();
//创建PreparedStatment
//创建预编译sql语句
String sql = "insert into test values(?,?);";
stmt = conn.prepareStatement(sql);
stmt.setInt(1, 1);
stmt.setClob(2, new FileReader("Demo.java"));
stmt.executeUpdate();
}catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
JdbcUtil.close(conn, stmt, null);
}
}
}
2、jdbc操作字节文件
把一张图片存储到数据库
package com.deu.c.club;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.jdbc.c.util.JdbcUtil;
public class BlubDemo {
public static void main(String[] args) {
//存入图片
//writeDemo();
//读取图片
readerDemo();
}
private static void readerDemo() {
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
//获取连接
conn = JdbcUtil.getConnection();
//创建sql预编译对象
String sql = "select * from ad";
//创建PreparedStatement
stmt = conn.prepareStatement(sql);
rs = stmt.executeQuery();
while (rs.next()) {
InputStream bs = rs.getBinaryStream(2);
FileOutputStream fos = new FileOutputStream("c.jpg");
//数据库默认要求,写入文件的大小是1m,如果存入数据库的文件大于这个容量就会抛出异常
//com.mysql.jdbc.PacketTooBigException
//max_allowed_packet
byte[] bch = new byte[1024];
int len;
while ((len=bs.read(bch))!=-1) {
fos.write(bch, 0, len);
}
//关流
bs.close();
fos.close();
}
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
}
}
private static void writeDemo() {
Connection conn = null;
PreparedStatement stmt = null;
try {
//获取连接
conn = JdbcUtil.getConnection();
//创建sql预编译对象
String sql = "insert into ad values(?,?)";
//创建PreparedStatement
stmt = conn.prepareStatement(sql);
//设置值
stmt.setInt(1, 1);
stmt.setBlob(2, new FileInputStream("3.jpg"));
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally{
//释放资源
}
}
}
四、数据库事务
1、事务概念:就是把多条SQL语句看做一个事务,那么这个事务要么一起成功,要么一起失败
2、mysql事务操作命令:
set autocommit =0 / 1; 设置是否自动提交事务1: 表示自动提交事务,每执行一条sql语句,自动提交事务。 0: 表示关闭自动提交事务。
commit; 提交事务,一旦提交事务不能回滚
rollback; 回滚事务。回滚到事务的起始点。
3、jdbc事务操作
Connection.setAutoCommit(false) 开启事务
Connection.commit(); 成功执行,最后提交事务
Connection.rollback(); 一旦遇到错误,回滚事务
4、事务的特性:
原子性:要么一起成功,要么一起失败
一致性:数据库应该从一个一致性的状态到另一个一致性的状态,保持不变
隔离性:多个事务直接应该可以相互隔离
持久性:事务一旦提交,应该拥挤保持下来
举例:
银行转账:
package com.deu.d.autocommit;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import com.jdbc.c.util.JdbcUtil;
public class Demo {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement stmt = null;
String sql1 = "UPDATE blank SET balance=balance-2000 WHERE id=1;";
String sql2 = "UPDATE blank SET balance=balance+2000 WHERE id=2;";
try{
//获取连接
conn = JdbcUtil.getConnection();
//开启事务
conn.setAutoCommit(false);//等价于set autocommit=0;
//预编译sql1
stmt = conn.prepareStatement(sql1);
//执行sql
stmt.executeUpdate();
//发生异常
//int i = 100/0;
stmt = conn.prepareStatement(sql2);
stmt.executeUpdate();
//提交事务
conn.commit();
}catch (Exception e) {
e.printStackTrace();
try {
//如果发生失误就回滚
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
//释放资源
}
}
}