J2EE学习篇之--JDBC详解(七)

2014-11-23 21:26:05 · 作者: · 浏览: 41
ment st = null; ResultSet rs = null; Savepoint sp = null; try{ conn = JdbcUtils.getConnection(); /**************事务START********************/ conn.setAutoCommit(false); st = conn.createStatement(); String sql = "update user set money=money-10 where id=1"; st.executeUpdate(sql); sp = conn.setSavepoint();//设置回滚点 sql = "update user set money=money-10 where id=3"; st.executeUpdate(sql); sql = "select money from user where id=2"; rs = st.executeQuery(sql); float money = 0.0f; if(rs.next()){ money = rs.getFloat("money"); } System.out.println("money:"+money); if(money>300){ throw new RuntimeException("已经超过最大值"); } sql = "update user set money=money+10 where id=2"; st.executeUpdate(sql); conn.commit(); /*******************事务END*********************/ }catch(SQLException e){ if(conn != null && sp != null){ conn.rollback(sp); conn.commit(); } }finally{ JdbcUtils.free(rs, st, conn); } }我们在用户1之后设置一个保存点,在异常中只需要回滚到保存点就可以了。


下面再来看一下事务的隔离级别,因为这部分的内容比较重要和繁琐,请看另外一篇文章:

http://blog.csdn.net/jiangwei0910410003/article/details/24960785

接着来看JDBC中调用存储过程,关于MySql中的存储过程的知识请看这两篇文章:

http://blog.csdn.net/jiangwei0910410003/article/details/24964331

http://blog.csdn.net/jiangwei0910410003/article/details/24965087

当我们会创建存储过程的时候,我们在到JDBC中去调用这个存储过程,

下面看一下实例:

我们现在想在插入一条数据的时候能够得到主键id的值(因为我们一般把主键id的值设置成自增长的形式),首先来创建一个存储过程:

delimiter $$ //修改定界符
drop procedure if exists addUser $$
create procedure addUser(in name varchar(45),in birthday date,in money float,out pid int)
begin
 insert into user(name,birthday,money) values(anme,birthday,money);
 select last_insert_id() into pid;//当前线程拿到最后一次插入的记录的赋值给pid,这里要注意,user表中的id必须是主键自增长类型,不然报错
end $$
delimiter ;

这里name,birthday,money都是输入值是:in

pid是输出值:out

然后我们在代码中进行执行这个存储过程:

static void test() throws Exception{
		Connection conn = null;
		CallableStatement cs = null;
		try{
			conn = JdbcUtils.getConnection();
			//name,birthday,money,id
			//存储过程名称是:addUser
			String sql = "{ call addUser( , , , )}";
			cs = conn.prepareCall(sql);
			cs.registerOutParameter(4, Types.INTEGER);
			cs.setString(1,"jiangwei");
			cs.setDate(2,new Date(System.currentTimeMillis()));
			cs.setFloat(3,300);
			cs.executeUpdate();
			
			int id = cs.getInt(4);
			System.out.println("id:"+id);
			
			/**
			 * 通过这个存储过程来获取主键id是有一个问题,不同的数据库,存储过程的编写语法是不一样的,所以这种方法是不通用
			 * 还有另外一种方法是OtherApi,通过JDBC中的api来获取
			 */
			
		}catch(SQLException e){
			e.printStackTrace();
		}
	}
这样我们就得到了插入一条记录的时候得到他的主键id的值

其实这种调用存储结构的方法,在早起的时候是很实用的,因为那时候没有分层架构的思想,所以会将业务逻辑层的实现放到存储过程中去做了,在调用存储过程的时候,会发现一个问题就是这样去获取主键id的值的方式,是不通用的,因为不同的数据库可能存储过程的编写是不一样的,所以做不到一致性,而且现在有了三成架构的思想,我们慢慢的就将这种方式给淘汰了,而是直接使用JDBC给我们提供的一套api来获取主键key的值:直接上代码吧:

static void test() throws Exception{
		java.sql.Connection conn = null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		try{
			conn = JdbcUtils.getConnection();
			String sql = "insert into user(name,birthday,money) values('jiangwei','1987-01-01',400)";
			ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);//生成主键id
			ps.executeUpdate();
			//可能是组合主键,可能会返回一个ResultSet
			rs = ps.getGenera