JDBC:批处理+存储过程+事务

3 篇文章 0 订阅

1.批处理

一次执行多条sql.sql语句的格式不同.
发送sql到数据库执行的对象:Statement/PreparedStatement.

Statement: 
void addBatch(sql); 添加批处理sql
int[] executeBatch(); 执行批处理sql
void clearBatch(); 清空批处理sql
//可以处理多条不同格式的sql语句,如insert、select...
//没有对sql语句进行预编译

PreparedStatement:
void addBatch();
int[] executeBatch();
void clearBatch();
//可以对sql语句进行预编译,防止sql语句注入
//只能执行同一格式的sql语句
//对内存要求比较高,所以要每N条先执行一次,清空缓存,再下一次批处理

----------------------------------------------------------

2.数据类型

1).char与varchar
char  一个字符长度
char(n) n个长度的字符,但无论数据是否有n个字符长,该列的值都是占n个字符大小内存

varchar(n) 可变长字符数据
即列的数据占多大内存,存储列的内存就为多大

2). int 与int(n)
int(n) 整形(可补充0,配合 zerofill ,不足n为的用0补足)

3).enum与set
eg:
_name ENUM('A','B','C') 
-- _name的值只能是其中之一,不能是其他值,或其中之2

_name SET('A','B','C')
-- _name的值可以是set中的任意一个或多个

4).时间类型
Date 日期类型
Datetime 日期时间类型
Timestamp 时间戳(该字段可以记录当前行数据的最新更新时间)

5).大数据类型(数据量大)
Oracle数据库:
blob/longblod 存储二进制类型数据,如图片/文件等.
clob  存储长文本类型数据,如一篇文章.

MySQL数据库:
bolb/longblod  存储二进制类型数据,如图片/文件等.
text/longtext  存储长文本类型数据,如一篇文章.
(不支持clob数据类型)

====操作大数据类型数据
//异常处理略
// content类型是text
String sql = "INSERT INTO longdata(content)VALUES(?)";


// 创建连接
con = JdbcUtils.getConnection();
// 执行命令对象
pstmt = con.prepareStatement(sql); // 预编译

// 获取文件的类路径
String path = this.getClass().getResource("readme.txt").getPath();
// 构建文件对象
File file = new File(path);
// 读取文件
FileReader reader = new FileReader(file);

// 设置参数值
pstmt.setCharacterStream(1, reader);

// 执行更新命令
pstmt.executeUpdate();
// 直接执行编译后结果(sql)

==读取时
// content类型是text
String sql = "select content from longdata where id=1";


// 方式1: 
String content = rs.getString(1);
System.out.println(content);

// 方式2: 获取reader对象 (输出到指定的文件!)
//rs.getCharacterStream(0)


3.JDBC操作存储过程

存储过程:可以看做是一个方法,里面可以处理简单的业务逻辑.

执行命令的对象:
|-- interface  Statement      执行命令
|-- interface  PreparedStatement    对sql语句预编译
|-- interface  CallableStatement     执行存储过程

===数据库中:
===不带输出参数的存储过程
-- 创建一个存储过程,调用的时候需要传入一个id参数
DELIMITER $
CREATE PROCEDURE proc_findStudent(IN id_ INT)
BEGIN
  SELECT * FROM student WHERE id=id_;
END $


-- 调用
CALL proc_findStudent(1);

===带输出参数的存储过程
-- 输入参数存储过程
-- 需求: 根据id查询,返回名称
DELIMITER $
CREATE PROCEDURE proc_getName(id_  INT, OUT name_ VARCHAR(200))
BEGIN
  SELECT stuName INTO name_ FROM student WHERE id=id_;
END $
-- 调用
SET @name_='';  -- 保存存储过程返回的值
CALL proc_getName(1,@name_);
SELECT @name_;  -- 显示看



===JDBC中:
===不带输出参数的存储过程
// 要执行的存储过程
String sql = "CALL proc_findStudent(?);";
int id=1;
try {
//1. 创建连接对象
con = JdbcUtils.getConnection();
//2. 创建执行存储过程的命令对象
cstmt = con.prepareCall(sql);
// 设置占位符参数值
cstmt.setInt(1, id);

//3. 执行存储过程
/*
* 存储过程执行的是查询: cstmt.executeQuery()
* 存储过程执行的是更新: cstmt.executeUpdate()
* 或:
* cstmt.execute()   执行任何sql!
*/
rs = cstmt.executeQuery();

===带输出参数的存储过程
int id = 2;
// 要执行的存储过程
String sql = "CALL proc_getName(?,?);";


//1. 创建连接对象
con = JdbcUtils.getConnection();

//2. 创建执行存储过程的命令对象
cstmt = con.prepareCall(sql);

// 设置参数值
cstmt.setInt(1, id);

// 注册一个存储过程的输出参数,指定参数类型即可  (执行完存储过程后,存储过程会给第二个参数赋值)
cstmt.registerOutParameter(2, Types.VARCHAR);

// 执行
cstmt.execute();

// 获取存储过程输入参数值 (获取第二个参数的值)
String content = cstmt.getString(2);




4.插入数据获取自增长值

向数据表插入一条数据,获取自增长编号列的值.

PreparedStatement prepareStatement(String sql ,int autoGeneratedKeys);
//创建一个PreparedStatement对象,该对象会自动获取自动生成的键.
//参数: autoGeneratedKeys - 指示是否应该返回自动生成的键的标志,它是 Statement.RETURN_GENERATED_KEYS 或 Statement.NO_GENERATED_KEYS 之一 .


//获取自增长值 (结果集rs里面存储的就是,生成的所有的自增长值)
rs = pstmt.getGeneratedKeys();
if (rs.next()) {
int id = rs.getInt(1);
}


5.事务

a).事务指的是逻辑上的一组操作,组成这操作的各个单元,要么全部成功,要么全部不成功.
即这组操作的所有单元全部成功,那么,这组操作才有意义;只要有一个单元不成功,那么这组操作全部失败,之前成功的单元也要回滚,回滚到这组操作执行前的状态.

b). 数据库中有关事务的关键字
start transaction  开始一个事务(或结束上一个事务)
commit   提交事务
rollback   回滚事务
rollback to   回滚到保存点
  与 savepoint sp 结合使用
  
c).事务的特性
原子性:事务是一个不可再分的工作单位,事务中的操作要么都发生,要么都不发生.

一致性:事务必须使数据库从一个一致性状态变换到另一个一致性状态.
数据在事务过程中要保持一致性状态.

隔离性:多个用户并发访问数据库时,数据库为每一个用户开启事务,不能被其它事务的操作数据所干扰,多个并发事务之间要相互间隔.

持久性:一个事务一旦被提交,它对数据库中数据的改变是永久性的,接下来即使数据库发生故障也不应该对其有任何影响.

d).隔离级别:
查看全局的隔离级别:SELECT @@global.tx_isolation;(全局)   (全局变量)
SET GLOBAL TRANSACTION ISOLATION LEVEL
read uncommitted; -- 读未提交(会读取未提交的数据)(安全性最低)

read committed; -- 读已提交(提交后的数据才能被读到)

repeatable read; -- 可重复读(解决同一个事务内多次读取结果不一样的问题)
-- 保证一个事务内多次读取的数据的结果一致.

serializable; -- 串行化(在多个事务操作表数据时,首先操作表的事务会锁定表.在锁定状态的表无法被其它事务操作.)(安全级别最高)(效率低)

e).JDBC操作事务
|-- interface Connection  事务的操作在Connection对象里
|-- void setAutoCommit(boolean autoCommit) conn对象默认是自动提交事务.若想手动提交事务,需要设置为false.
|-- void commit() 提交事务
|-- void rollback() 回滚事务
|-- Savepoint setSavepoint() 定义一个回滚点.回滚点设置在一个事务结束之前.
|-- void rollback(Savepoint savepoint) 回滚到回滚点

==eg:
try{
// 创建连接对象
Connection con = JdbcUtils.getConnection();
// 【设置事务手动提交】
con.setAutoCommit(false);
// 执行命令对象
PreparedStatement pstmt = con.prepareStatement(sql_jet);
// 执行jet转出
pstmt.execute();

// 执行rose转入
pstmt = con.prepareStatement(sql_rose);
pstmt.execute();

} catch (SQLException e) {
e.printStackTrace();
try {
// 【回滚】
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
} finally {
try {
// 【提交事务】
con.commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
JdbcUtils.closeAll(con, pstmt, null);
}
}

*若有不足或错误,请多多指教,谢谢!*





















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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值