JDBC 之插入Blob(图片)& 批处理 & 数据库事务
2016-10-17 03:03
381 查看
插入Blob字段类型(如图片) 实现批处理和 数据库事务的一致性 |
---|
一、插入Blob类型数据(如:图片)
使用JDBC来写入Blob型数据到数据库中 数据库中的Blob字段比long字段的性能要好,可以用来保存如图片之类的二进制数据。 BLOB字段由两部分组成:数据(值)和指向数据的指针(定位器)。 尽管值与表自身一起存储,但是一个BLOB列并不包含值,仅有它的定位指针。 为了使用大对象,程序必须声明定位器类型的本地变量。 当数据库内部LOB被创建时,定位器被存放在列中,值被存放在LOB段中, LOB段是在数据库内部表的一部分。 因为Blob自身有一个cursor,当写入Blob字段必须使用指针(定位器) 对Blob进行操作,因而在写入Blob之前,必须获得指针(定位器)才能进行写入 如何获得Blob的指针(定位器) :需要先插入一个empty的blob, 这将创建一个blob的指针,然后再把这个empty的blob的指针查询出来, 这样通过两步操作,就获得了blob的指针,可以真正的写入blob数据了。
<1>第一步:连接数据库和释放资源的JDBCUtils是不可少的
封装使用C3P0获取连接和关闭连接 这两个方法封装如下:
public class JDBCUtils { //数据库连接池值应该被初始化一次放在静态代码块中 private static DataSource datasource=null; static{ datasource =new ComboPooledDataSource("helloc3p0"); } public static Connection getConnection() throws SQLException{ return datasource.getConnection(); } //用完资源后需要关闭 /*释放资源: Connection Statement ResultSet 1 尽量晚创建早释放 2 后使用的先关闭*/ public static void release(ResultSet rs,Statement statement,Connection conn){ if(rs!=null){ try{ rs.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(statement!=null){ try{ statement.close(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }
<2> 编码格式 数据库utf8
<2>第二步:实现插入Blob类型(图片)的数据如下:
public class TestBlob { @Test public void testInsert() throws Exception{ //获取连接 Connection connection = JDBCUtils.getConnection(); PreparedStatement statement = connection.prepareStatement("insert into star values(null,'mnls',?)"); //插入图片占位符值 图片存储在src包下 statement.setBlob(1, new FileInputStream("src/mnls.jpg")); //执行插入图片 int executeUpdate = statement.executeUpdate(); if (executeUpdate>0) { System.out.println("success"); } else { System.out.println("failure"); } JDBCUtils.release(connection, statement, null); }
<2>第三步:实现将数据库中Blob类型(图片)的数据取出:
//查询blob数据 @Test public void testRead() throws Exception{ Connection connection = DBUtils.getConnection(); PreparedStatement statement = connection.prepareStatement("select * from star where id=1"); ResultSet set = statement.executeQuery(); if (set.next()) { Blob blob = set.getBlob("photo"); //获取二进制流对象 ★ InputStream stream = blob.getBinaryStream(); //一边读一边写 写入src下存为copy.jpg //将读到的数据转换成字符数组(方法如下) byte[] arrs = StreamUtils.streamToByteArray(stream); FileOutputStream fos = new FileOutputStream("src/copy.jpg"); fos.write(arrs); fos.close(); } DBUtils.release(connection, statement, set); } }
//将输入流转换成byte[] 如下
public class StreamUtils { /** * * 将 输入流 转换成byte[] * @param is * @return */ public static byte[] streamToByteArray(InputStream is) throws IOException{ //创建字节数组的输出流 ByteArrayOutputStream baos = new ByteArrayOutputStream(); byte[] b=new byte[1024]; int len; while((len=is.read(b))!=-1){ baos.write(b, 0, len);//写到字节数组的输出流 } is.close(); baos.close(); return baos.toByteArray(); } }
二、JDBC之批处理操作
描述:批量处理JDBC语句提高处理速度 当需要成批插入或者更新记录时。 可以采用Java的批量更新机制,这一机制允许多条语句一次性 提交给数据库批量处理。通常情况下比单独提交处理更有效率 JDBC的批量处理语句包括下面两个方法: addBatch(String):添加需要批量处理的SQL语句或是参数; executeBatch():执行批量处理语句; clearBatch():清空缓存的数据 通常我们会遇到两种批量执行SQL语句的情况: 多条SQL语句的批量处理; 一个SQL语句的批量传参;
<1> 注意url的配置 和数据库与java项目的编码一致utf8
<2> 加入jar包commons-dbutils-1.3.jar
url:
jdbc:mysql://localhost:3306/test?rewriteBatchedStatements=true
<3>实现批处理如下
/** * 此类用于演示批处理 * @author liyuting * */ public class TestBatch { @Test public void testBatch(){ Connection connection=null; PreparedStatement statement =null; try { connection = JDBCUtils.getConnection(); statement= connection.prepareStatement ("insert into 表名 values(null,?,'男','38835@qq.com',now())"); for (int i =1; i <=20000; i++) { statement.setString(1, "李四"+i); statement.addBatch();//添加到批处理的语句中 if (i%500==0) {//每500条sql语句执行一次 statement.executeBatch();//真正的执行 statement.clearBatch();//清空缓存 } } } catch (SQLException e) { e.printStackTrace(); } finally{ JDBCUtils.release(connection, statement, null); } }
}
三、JDBC之数据库事务(控制多条sql执行中其中一条会出现异常)
<1>描述:JDBC 事务处理: 当一个连接对象被创建时,默认情况下是自动提交事务: 每次执行一个 SQL 语句时,如果执行成功, 就会向数据库自动提交,而不能回滚 为了让多个 SQL 语句作为一个事务执行: 调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务 在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务 在出现异常时,调用 rollback(); 方法回滚事务 若此时 Connection 没有被关闭, 则需要恢复其自动提交状态
<2>实现如下:
/** * 此类用于演示演示事务 * @author liyuting * */ public class TestTransaction { @Test public void testBatch(){ Connection connection = null; try { //1获取连接 connection=DBUtils.getConnection(); //2.开启事务 (start transaction) connection.setAutoCommit(false);//取消每一行的自动提交 //执行一条修改语句 update(connection,"update users set name='张三' where id=?",1); int i = 10/1;//模拟异常 //执行第二条修改语句 update(connection,"update users set name='李四' where id=?",2); //提交事务(commit) connection.commit(); } catch (SQLException e) { //回滚事务(rollback) try { connection.rollback(); } catch (SQLException e1) { e1.printStackTrace(); } } }
相关文章推荐
- 数据库_jdbc_大数据(text+blob)_批处理
- JDBC之向数据库中插入图片
- JDBC(Oracle 数据库)中的批处理…
- JDBC:元数据 && 获取插入记录的主键值 && _JDBC_处理 Blob
- 通过JDBC向数据库中存储&读取Blob数据
- 插入图片到数据库(BLOB大字段保存对象)
- Caused by: com.microsoft.sqlserver.jdbc.SQLServerException: 数据库 'BHIoTV1.1' 的事务日志已满。若要查明无法重用日志中的空间的原
- jdbc将图片(二进制文件如电影,音乐等)插入数据库
- 在Java中使用JDBC向数据库插入图片和读取数据库中的图片(八)
- JDBC&&c3p0、事务、批处理、多线程 于一体的经典秘方QueryRunner (common-dbutils)
- JDBC学习笔记(6)——获取自动生成的主键值&处理Blob&数据库事务处理
- 复习课程jdbc:使用配置文件properties进行连接数据库,数据库存取图片,批处理,时间戳,事物回滚等等
- 使用JDBC和Hibernate在oracle中插入和读取Blob数据的图片的java程序
- java中用Blob的数据类型向数据库插入图片
- JDBC连接数据库:单线程、多线程、批处理插入数据的对比
- [zt]JDBC对数据库的事务操作
- 使用jdbc与hibernate将BLOB字段写入数据库
- 上传图片以二进制插入到数据库,且读取显示
- 使用jdbc与hibernate将BLOB字段写入数据库
- 上传图片以二进制插入到数据库,且读取显示