JDBC 之插入Blob(图片)& 批处理 & 数据库事务
来源:互联网 发布:灯塔炒股软件 编辑:程序博客网 时间:2024/06/05 21:57
插入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();}//用完资源后需要关闭/*释放资源:ConnectionStatementResultSet1 尽量晚创建早释放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 {@Testpublic 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数据@Testpublic 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 {@Testpublic 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 {@Testpublic 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(); } }}
0 0
- JDBC 之插入Blob(图片)& 批处理 & 数据库事务
- JDBC之向数据库中插入图片
- 通过JDBC使用批处理+事务,往数据库中插入百万级数据测试
- 插入图片/文本(blob /clob)到oracle数据库
- JDBC之批处理、事务、存储过程
- JDBC批处理-大量数据插入数据库减少插入时间
- JDBC事务和批处理
- jdbc批处理插入数据
- jdbc批处理插入数据
- jdbc操作数据库blob
- JDBC上传图片文件到MySQL数据库的blob字段
- Oracle jdbc 插入 clob blob
- MySql的Blob插入(JDBC)
- java中用Blob的数据类型向数据库插入图片
- 插入图片到数据库(BLOB大字段保存对象)
- Oracle数据库中插入图片BLOB字段的方法
- jdbc批处理的事务控制
- JDBC存储过程、批处理、事务
- jdk1.8新特性
- HDU-1009-FatMouse' Trade
- Windows下面安装和配置MySQL(5.6.20)
- Valid Parentheses
- JS数组方法汇总/数组增删查改
- JDBC 之插入Blob(图片)& 批处理 & 数据库事务
- 利用word2vec对关键词聚类
- SQL 数据库 学习 024 查询-07 order by 的用法 --- 以某个字段排序
- docker筑基篇-01-docker基础命令及常用选项
- linux的sort基本使用
- 【STM32】STM32之系统滴答定时器
- Leetcode 163. Missing Ranges
- youcompleteme安装
- Facebook面试题:Task Schedule