数据库事物与blob的应用
来源:互联网 发布:餐饮软件破解版 编辑:程序博客网 时间:2024/06/05 09:58
在数据库中,所谓事务是指一组逻辑操作单元,使数据从一种状态变换到另一种状态。为确保数据库中数据的一致性,数据的操纵应当是离散的成组的逻辑单元:当它全部完成时,数据的一致性可以保持,而当这个单元中的一部分操作失败,整个事务应全部视为错误,所有从起始点以后的操作应全部回退到开始状态。
事务的操作:先定义开始一个事务,然后对数据作修改操作,这时如果提交(COMMIT),这些修改就永久地保存下来,如果回退(ROLLBACK),数据库管理系统将放弃您所作的所有修改而回到开始事务时的状态。
事务的ACID属性:
1. 原子性(Atomicity)原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发
生。
2. 一致性(Consistency)事务必须使数据库从一个一致性状态变换到另外一个一致性状态。
3. 隔离性(Isolation)事务的隔离性是指一个事务的执行不能被其他事务干扰,即一个事务内部的操作及使用的数据对并发的其他事务是隔离的,并发执行的各个事务之间不能互相干扰。
4. 持久性(Durability)持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来的其他操作和数据库故障不应该对其有任何影响
COMMIT和ROLLBACK语句的优点:
使用COMMIT 和 ROLLBACK语句,我们可以: 确保数据完整性。数据改变被提交之前预览。将逻辑上相关的操作分组。
提交或回滚前的数据状态:
改变前的数据状态是可以恢复的,执行 DML 操作的用户可以通过 SELECT 语句查询提交或回滚之前的修正
其他用户不能看到当前用户所做的改变,直到当前用户结束事务。DML语句所涉及到的行被锁定, 其他用户不能操作。
提交后的数据状态:
数据的改变已经被保存到数据库中。改变前的数据已经丢失。所有用户可以看到结果。锁被释放, 其他用户可以操作涉及到的数据。
JDBC 事物处理:
事务:指构成单个逻辑工作单元的操作集合
事务处理:保证所有事务都作为一个工作单元来执行,即使出现了故障,都不能改变这种执行方式。当在一个事务中执行多个操作时,要么所有的事务都被提交(commit),要么整个事务回滚(rollback)到最初状态当一个连接对象被创建时,默认情况下是自动提交事务:每次执行一个 SQL 语句时,如果执行成功,就会向数据库自动提交,而不能回滚为了让多个 SQL 语句作为一个事务执行:调用 Connection 对象的 setAutoCommit(false); 以取消自动提交事务在所有的 SQL 语句都成功执行后,调用 commit(); 方法提交事务在出现异常时,调用 rollback(); 方法回滚事务
下面来看在mysql和oracle上加入数据的例子,这个里面牵涉到关于事物处理的语句.
这个是在oracle下插入图片:
package cn.itcast.jdbc;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Blob;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import oracle.sql.BLOB;
public class TestOracleBlob {
public static Connection getConnection(){
Connection conn = null;
String user = "system";
String password = "itcast";
String driver = "oracle.jdbc.driver.OracleDriver";
String url = "jdbc:oracle:thin:@192.168.1.10:1521:orcl";
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void releaseDBSource(ResultSet rs, Statement st, Connection conn){
try {
if(rs != null)
rs.close();
if(st != null)
st.close();
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void insertBlob_1(){
Connection conn = null;
PreparedStatement ps = null;
try {
conn = getConnection();
String sql = "INSERT INTO userinfo (name, picture) VALUES(?, ?)";
ps = conn.prepareStatement(sql);
ps.setString(1, "Bob12345");
FileInputStream fis = new FileInputStream("ronaerdo.jpg");
ps.setBinaryStream(2, fis, fis.available());
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//7. 关闭数据库资源
releaseDBSource(null, ps, conn);
}
}
public static void insertBlob(){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
PreparedStatement ps = null;
try {
conn = getConnection();
//0. 设置 Connection 为非自动提交, 因为需要进行两次操作
conn.setAutoCommit(false);
//需求: 向 orcl 数据库 userinfo 表中插入一条记录:
//1. 插入一个空的 blob, 目标: 获取 pictuer 字段的指针
String sql = "INSERT INTO userinfo (name, picture) VALUES('Jerry', empty_blob())";
st = conn.createStatement();
st.executeUpdate(sql);
//向 userinfo 表的 'Tom' 记录中插入图片
//2. 获取 picture 字段的指针
sql = "SELECT picture FROM userinfo WHERE name = 'Jerry' for update";
rs = st.executeQuery(sql);
rs.next();
BLOB picture = (BLOB) rs.getBlob(1);
//3. 获取图片的输入流
FileInputStream fis = new FileInputStream("car.jpg");
//4. 获取 picture 字段的指针指向的数据区的输出流: 需要调用 oracle.sql.BLOB 的 getBinaryOutputStream(); 方法
OutputStream os = null;
os = picture.getBinaryOutputStream();
//5. io 操作
byte [] temp = new byte[1024 * 5];
int length = 0;
while((length = fis.read(temp)) != -1){
os.write(temp, 0, length);
}
fis.close();
os.close();
//6. 提交数据
conn.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
//6. 回滚
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
//7. 关闭数据库资源
}
}
public static void queryBlob(){
//1. 建立数据库连接
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = getConnection();
//2. 准备 sql 文
String sql = "SELECT picture FROM userinfo WHERE name = 'Jerry'";
//3. 获取 Statement 对象
st = conn.createStatement();
//4. 查询操作
rs = st.executeQuery(sql);
//5. 处理结果集
Blob picture = null;
if(rs.next()){
picture = rs.getBlob(1);
}
//6. 获取 picture 字段的输入流
InputStream is = picture.getBinaryStream();
//7. 建立输出流
FileOutputStream pic = new FileOutputStream("myPic.jpg");
//8. io 操作
byte [] bytes = new byte[1024 * 5];
int length = 0;
while((length = is.read(bytes)) != -1){
pic.write(bytes, 0, length);
}
is.close();
pic.close();
} catch (Exception e) {
e.printStackTrace();
}finally{
//9. 关闭数据库资源
releaseDBSource(rs, st, conn);
}
}
public static void updateBlob(){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = getConnection();
st = conn.createStatement();
//1. 获取 picture 字段的指针
String sql = "SELECT picture FROM userinfo WHERE name = 'Jerry' for update";
rs = st.executeQuery(sql);
rs.next();
BLOB picture = (BLOB) rs.getBlob(1);
//3. 获取图片的输入流
FileInputStream fis = new FileInputStream("threadlocal.jpg");
//4. 获取 picture 字段的指针指向的数据区的输出流: 需要调用 oracle.sql.BLOB 的 getBinaryOutputStream(); 方法
OutputStream os = null;
os = picture.getBinaryOutputStream();
//5. io 操作
byte [] temp = new byte[1024 * 5];
int length = 0;
while((length = fis.read(temp)) != -1){
os.write(temp, 0, length);
}
fis.close();
os.close();
//6. 提交数据
conn.commit();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
try {
//6. 回滚
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}finally{
//7. 关闭数据库资源
releaseDBSource(rs, st, conn);
}
}
//删除二进制数据, 即: 让该字段的数据内容为空
public static void deleteBlob(){
Connection conn = null;
Statement st = null;
try {
conn = getConnection();
st = conn.createStatement();
String sql = "UPDATE userinfo SET picture = empty_blob() WHERE name = 'Jerry'";
st.execute(sql);
} catch (SQLException e) {
e.printStackTrace();
}finally{
releaseDBSource(null, st, conn);
}
}
public static void main(String[] args) {
//queryBlob();
//updateBlob();
//queryBlob();
//deleteBlob();
insertBlob_1();
}
}
mysql的插入数据的方法
package cn.itcast.jdbc;
import java.io.FileInputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class TestMysqlBlob {
public static void main(String[] args) {
//insertBlob();
//updateBlob();
deleteBlob();
}
public static Connection getConnection(){
Connection conn = null;
String user = "root";
String password = "1230";
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3309/itcast";
try {
Class.forName(driver);
conn = DriverManager.getConnection(url, user, password);
} catch (Exception e) {
e.printStackTrace();
}
return conn;
}
public static void releaseDBSource(ResultSet rs, Statement st, Connection conn){
try {
if(rs != null)
rs.close();
if(st != null)
st.close();
if(conn != null)
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void deleteBlob(){
Connection conn = null;
PreparedStatement ps = null;
String sql = "UPDATE userinfo SET picture = ? WHERE name = ?";
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
//FileInputStream fis = new FileInputStream("myPic.jpg");
ps.setString(2, "Tom");
//不能使用 ps.setBlob(), 因为无法自己创建 Blob 对象
ps.setBinaryStream(1, null, 0);
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
releaseDBSource(null, ps, conn);
}
}
public static void updateBlob(){
Connection conn = null;
PreparedStatement ps = null;
String sql = "UPDATE userinfo SET picture = ? WHERE name = ?";
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
FileInputStream fis = new FileInputStream("myPic.jpg");
ps.setString(2, "Tom");
//不能使用 ps.setBlob(), 因为无法自己创建 Blob 对象
ps.setBinaryStream(1, fis, fis.available());
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
releaseDBSource(null, ps, conn);
}
}
public static void insertBlob(){
Connection conn = null;
PreparedStatement ps = null;
String sql = "INSERT INTO userinfo(name, picture) VALUES(?, ?)";
try {
conn = getConnection();
ps = conn.prepareStatement(sql);
FileInputStream fis = new FileInputStream("1321554.jpg");
ps.setString(1, "Tom");
//不能使用 ps.setBlob(), 因为无法自己创建 Blob 对象
ps.setBinaryStream(2, fis, fis.available());
ps.executeUpdate();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
releaseDBSource(null, ps, conn);
}
}
}
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。实际使用中根据需要存入的数据大小定义不同的BLOB类型。需要注意的是:如果存储的文件过大,数据库的性能会下降。
使用JDBC来写入Blob型数据到Oracle中 :
1.Oracle的Blob字段比long字段的性能要好,可以用来保存如图片之类的二进制数据。
2.Oracle的BLOB字段由两部分组成:数据(值)和指向数据的指针(定位器)。尽管值与表自身一起存储,但是一个BLOB列并不包含值,仅有它的定位指针。为了使用大对象,程序必须声明定位器类型的本地变量。
3.当Oracle内部LOB被创建时,定位器被存放在列中,值被存放在LOB段中,LOB段是在数据库内部表的一部分。
4.因为Blob自身有一个cursor,当写入Blob字段必须使用指针(定位器)对Blob进行操作,因而在写入Blob之前,必须获得指针(定位器)才能进行写入
5.如何获得Blob的指针(定位器):需要先插入一个empty的blob,这将创建一个blob的指针,然后再把这个empty的blob的c指针查询出来,这样通过两步操作,就获得了blob的指针,可以真正的写入blob数据了。
如果将一些重要的数据导入数据库中是很安全的,除非你的数据库的密码被别人事先已经知道,否则任何人都盗取不到任何信息的!只有用户名和密码的人才能够看到数据里面的内容的!
- 数据库事物与blob的应用
- mysql数据库的事物与链接池
- 数据库 事物 与 并发 事物隔离等级
- 数据库的事物管理
- 数据库的事物
- 数据库的事物机制
- 数据库的事物
- redis事物介绍与应用
- 数据库事物与隔离级别
- Spring的全局事物与局部事物
- CLOB、BLOB , CLOB与BLOB的区别
- CLOB、BLOB , CLOB与BLOB的区别
- CLOB、BLOB , CLOB与BLOB的区别
- CLOB、BLOB , CLOB与BLOB的区别
- CLOB、BLOB , CLOB与BLOB的区别
- 数据库的事物隔离级别
- 数据库事物的隔离级别
- 数据库事物的隔离级别
- 自定义标签
- 数据库入门
- JDBC(一)增,删,改,查操作
- JDBC(二)增,删,改,查操作
- PreparedStatement vs Statement
- 数据库事物与blob的应用
- 数据库连接池
- cookie
- session的应用
- 在qt creator中引入动态链接库
- 关于验证码的应用
- 简易购物车
- 简易购物车---获取图书信息
- 简易购物车---分页