Java学习之jdbc加强

一、批处理

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{
			//释放资源
			
		}
	}
}















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值