通过Jdbc连接数据库
- 加载Jdbc驱动,将数据库的jdbc驱动加载到到classpath中;
- 将jdbc驱动注册到DriverManager中,Class.forName(driver);
- 建立数据库连接,Connection con = DriverManager.getConnection(url,user,password);
- 创建Statement对象或是PreparedStatement对象;
- 执行Sql语句;
- 访问结果集ResultSet对象;
- 关闭,一次将ResultSet、Statement、PreparedStatement、Connection对象关闭,释放内存。rs.close(),con.close()(原因在于Jdbc驱动在底层通常都是通过网络IO实现Sql命令与数据传输的)
- 自动提交模式;
- 手动提交模式,手动提交事务的处理流程,这时可以使用 DatabaseMedaData 的supportTranslations() 方法进行检查数据库是否支持事务处理,若返回 true 则说明支持事务处理,否则返回 false 。如使用Mysql 的事务功能,就要求Mysql里的表的类型为Innodb才支持事务控制处理,否则,在Java程序中做了 commit 或 rollback ,但数据库中是不生效的。
<pre name="code" class="java"><span style="font-size:18px;">package sql;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Test {
public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
String user = "water";
String password = "abcd1234";
String url ="jdbc:mysql://localhost:3306/testsql";
String driver = "com.mysql.jdbc.Driver";
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
Statement sts = null;
try{
//加载驱动
Class.forName(driver);
//创建连接
conn = DriverManager.getConnection(url, user, password);
//创建Statement对象
sts = conn.createStatement();
//取消自动提交事务,开启手动提交事务
conn.setAutoCommit(false);
//执行sql
sts.execute("insert into Employee values(2,'Janmes',26)");
sts.execute("insert into Employee values(3,'Janmes',22)");
//sts.executeUpdate("update Employee set name='Jonh' Where age = 22");
//获取结果集
rs = sts.executeQuery("select * from Employee");
//提交事务
conn.commit();
while(rs.next()){
System.out.println("name: "+rs.getString("name")+" age: "+rs.getInt("age"));
}
}catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}catch(SQLException el){
el.printStackTrace();
//事务回滚
conn.rollback();
}finally{
if(rs != null){
rs.close();
}
if(sts != null){
sts.close();
}
if(conn != null){
conn.close();
}
}
}
}
</span>
Jdbc的5种事务隔离
- TRASACTION_NONE_JOB 不支持事务;
- TRASACTION_READ_UNCOMMITED。未提交读,说明在提交一个事务可以看到另一个事务的变化。这样读“脏”数据,不可重复读和虚读都是允许的;
- TRASACTION_READ_COMMITED。已提交读,说明读取未提交的数据是不允许的,这个级别仍然允许不可重复读和虚读产生。在一个事务中进行查询时,允许读取提交前的数据,数据提交后,当前查询就可以读取到数据。update数据时候并不锁住表;
- TRASACTION_REPEATABLE_READ。可重复读,说明事务保证能够再次读取相同的数据而不会失败,虚读仍然会出现,在一个事务中进行查询时,不允许读取其他事务update的数据,允许读取到其他事务提交的新增数据;
- TRASACTION_SERIALIZABLE。可序列化。最高的事务级别,它防止”脏”读、不可重复和虚读。在一个事务中进行查询时,不允许任何对这个查询表的数据进行新增或修改。
备注:
读“脏”数据:允许一个事务读取另一个事务未提交的数据,例如当事务A和B并发执行时,当事务A更新后,事务B查询读取到A尚未提交的数据,此时事务回滚,则事务B读到的数据是无效的“脏”数据;
不可重复读:一个事务的操作导致另个事务前后读取到不同的数据,例如当事务A与事务B并发执行时,当事务B查询数据后,事务A更新操作更改事务B查询到的数据,此时事务B再次去读取该数据,发现前后两次的数据不一致;
虚读:一个事务的操作导致另一个事务前后两次查询的结果数据量不同,例如,当事务A和事务B并发执行时,当事务B查询读取数据后,事务A新增或删除了一条满足事务A的查询条件的数据,此时,事务B再次查询,发现查询到前次不存在的记录,或者前次的某个记录不见了。
事务隔离级别越高,为避免冲突所发生的精力也就越多,可以通过Connection对象conn.setTransactionLevel()方法来设置隔离级别,通过conn.getTransactionIsolation()方法来确定事务的级别。