hibernate对JDBC封装的简单分析

本文介绍了标准的JDBC操作流程及Hibernate如何封装这些操作,重点解析了Hibernate中ConnectionManager的工作原理及其与JDBCContext的关系,并详细展示了Hibernate如何通过JDBCTransaction实现对事务的控制。
摘要由CSDN通过智能技术生成
标准的jdbc操作流程:
String Driver=com.microsoft.sqlserver.jdbc.SQLServerDriver";
String url=jdbc:sqlserver://localhost:1433;DatabaseName=dbname";
String user="sa";
String password="sa";Class.forName(driverClass);
Connection   conn=DriverManager.getConnection(url,user,password);
Connection对象代表与数据库的连接
createStatement()  //创建Statement对象
prepareStatement(String sql) //创建预处理语句
prepareCall(String sql)  //来处理一个 SQL 存储过程调用语句 
close()  //关闭数据库连接
isClosed()  //判断数据库连接是否超时或被显示关闭
setAutoCommit()  //设置操作是否自动提交到数据库,默认为  true
commit()  //提交所执行的SQL语句,在 setAutoCommit(false)之后才有效
rollback()  //回滚所执行的SQL语句在 setAutoCommit(false)      之后才有效
getMetaData()    //获取一个DatabaseMetaData对象,该对象包含了有关数据库的基本信息


Hibernate的封装:
org.hibernate.jdbc.ConnectionManager
public Connection getConnection() throws HibernateException {
.....
openConnection();
.....
}
private void openConnection() throws HibernateException{
......
connection = factory.getConnectionProvider().getConnection();
......
}


ConnectionProvider是 factory.getConnectionProvider()返回的对象的接口.
且看有哪些对象实现了这个接口?
挑其中一个来看-DriverManagerConnectionProvider,我们是否看到了很多熟悉的变量名?比如driverClass,autocommit,isolation,url
public void configure(Properties props) throws HibernateException {
String driverClass = props.getProperty(Environment.DRIVER);
autocommit = PropertiesHelper.getBoolean(Environment.AUTOCOMMIT, props);
isolation = PropertiesHelper.getInteger(Environment.ISOLATION, props);
if (driverClass==null) {
log.warn("no JDBC Driver class was specified by property " + Environment.DRIVER);
}
else {
try {
// trying via forName() first to be as close to DriverManager's semantics
Class.forName(driverClass);
}
catch (ClassNotFoundException cnfe) {
try {
ReflectHelper.classForName(driverClass);
}
catch (ClassNotFoundException e) {
String msg = "JDBC Driver class not found: " + driverClass;
log.error( msg, e );
throw new HibernateException(msg, e);
}
}
}
url = props.getProperty( Environment.URL );
if ( url == null ) {
String msg = "JDBC URL was not specified by property " + Environment.URL;
log.error( msg );
throw new HibernateException( msg );
}
connectionProps = ConnectionProviderFactory.getConnectionProperties( props );
log.info( "using driver: " + driverClass + " at URL: " + url );
}


我们是否看到了熟悉的connection获取的代码.
public Connection getConnection() throws SQLException {
        ..............
Connection conn = DriverManager.getConnection(url, connectionProps);
...............
return conn;
}


继而Hibernate抽象出了一个对象 org.hibernate.jdbc.JDBCContext
它和ConnectionManager的关系是 has-a. 同时,他实现了ConnectionManager.Callback
在创建ConnectionManager的同时,将自身的引用传递给了ConnectionManager实例,注册了一个钩子.
public JDBCContext(Context owner, Connection connection, Interceptor interceptor) {
...................
this.connectionManager = new ConnectionManager(
        owner.getFactory(),
        this,
        owner.getConnectionReleaseMode(),
        connection,
        interceptor
);
                ...................
}


同时,在JDBCContext中声明了一个接口
public static interface Context extends TransactionFactory.Context {
/**
 * We cannot rely upon this method being called! It is only
 * called if we are using Hibernate Transaction API.
 */
public void afterTransactionBegin(Transaction tx);
public void beforeTransactionCompletion(Transaction tx);
public void afterTransactionCompletion(boolean success, Transaction tx);
public ConnectionReleaseMode getConnectionReleaseMode();
public boolean isAutoCloseSessionEnabled();
}


再看看JDBCContext的构造函数中的Context owner,
意味着,JDBCContext是提供了一个钩子,看接口定义的行为来判断,应该是为事务前后的处理提供的钩子入口.
JDBCContext 会在哪里创建呢?
org.hibernate.impl.SessionImpl中会创建,可以看到SessionImpl将自身的引用注册到了JDBCContext实例中.
SessionImpl实现了Context接口.
this.jdbcContext = new JDBCContext( this, connection, interceptor );
那么Hibernate是如何来完成事务控制的呢?
我们来看一下传统的事务控制代码.
Connection.setAutoCommit(false)
Connection.commit();
如果出现错误就调用
Connection.rollback();
再来看看Hibernate如何封装JDBC事务控制的.
事务接口
org.hibernate.Transaction
实现这个接口的对象有:
我们来看看JDBCTransaction
public void begin() throws HibernateException {
.....................
try {
toggleAutoCommit = jdbcContext.connection().getAutoCommit();
if (toggleAutoCommit) {
log.debug("disabling autocommit");
jdbcContext.connection().setAutoCommit(false);
}
}
catch (SQLException e) {
                        .....................
}
                .................
}


核心代码和传统JDBC方式一模一样.
在JDBCContext中有如下方法:
public Transaction getTransaction() throws HibernateException {
if (hibernateTransaction==null) {
hibernateTransaction = owner.getFactory().getSettings()
.getTransactionFactory()
.createTransaction( this, owner );
}
return hibernateTransaction;
}


这个owner就是我们刚才说到的SessionImpl-JDBCContext构造函数中的Context接口的实现.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值