文末附有源码地址
博客为代码完成后才开始整理,展示的代码都是最终代码
个人学习,代码写的不够好,有点乱
通过学习mybatis源码模拟实现Mybatis(在完善)
已实现:
crud(实现XML配置,注解配置写过一点,原理差不多不写了)、
事务、
数据库连接池、
动态sql(一部分,原理没问题了,以后有时间再完善)、
一级二级缓存
单独使用mybatis时,使用sqlsession来处理事务。你一定看过下面的代码:
SqlSession session = factory.openSession(true);
SqlSession session = factory.openSession();
session.commit();
为了实现mybatis事务,通过模仿mybatis写出下面几个类:
首先我们创造出TransactionFactory和Transaction接口。
public interface TransactionFactory {
Transaction newTransaction(Connection conn, boolean autoCommit);
Transaction newTransaction(DataSource dataSource, boolean autoCommit);
}
通过工厂TransactionFactory根据不同的配置创建出Transaction。
public interface Transaction {
Connection getConnection() throws SQLException;
void commit() throws SQLException;
void rollback() throws SQLException;
void close() throws SQLException;
boolean isAutoCommit() throws SQLException;
void setAutoCommit(boolean autoCommit);
}
而TransactionIsolationLevel是一个枚举类,定义了事务隔离级别。
NONE(Connection.TRANSACTION_NONE),
READ_COMMITTED(Connection.TRANSACTION_READ_COMMITTED),
READ_UNCOMMITTED(Connection.TRANSACTION_READ_UNCOMMITTED),
REPEATABLE_READ(Connection.TRANSACTION_REPEATABLE_READ),
SERIALIZABLE(Connection.TRANSACTION_SERIALIZABLE),
我们创造JdbcTransaction 实现Transaction 接口:
public class JdbcTransaction implements Transaction {
protected Connection connection;
protected DataSource dataSource;
protected TransactionIsolationLevel level;
protected boolean autoCommit;
public JdbcTransaction(Connection conn, boolean autoComm) {
this.connection = conn;
this.autoCommit = autoComm;
}
public JdbcTransaction(DataSource dataSource) {
this.dataSource = dataSource;
}
public JdbcTransaction(DataSource ds, TransactionIsolationLevel desiredLevel, boolean desiredAutoCommit) {
dataSource = ds;
level = desiredLevel;
autoCommit = desiredAutoCommit;
}
@Override
public Connection getConnection() throws SQLException {
if (connection == null) {
openConnection();
}
return connection;
}
public void setConnection(Connection connection) {
this.connection = connection;
}
@Override
public void commit() throws SQLException {
connection.commit();
}
@Override
public void rollback() throws SQLException {
connection.rollback();
}
@Override
public void close() throws SQLException {
if (connection != null) {
/**若是返回连接池需重置*/
resetAutoCommit();
connection.close();
}
}
protected void resetAutoCommit() {
try {
if (!connection.getAutoCommit()) {
connection.setAutoCommit(true);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void openConnection() throws SQLException {
connection = dataSource.getConnection();
if (level != null) {
connection.setTransactionIsolation(level.getLevel());
}
setDesiredAutoCommit(autoCommit);
}
protected void setDesiredAutoCommit(boolean desiredAutoCommit) {
try {
if (connection.getAutoCommit() != desiredAutoCommit) {
connection.setAutoCommit(desiredAutoCommit);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public DataSource getDataSource() {
return dataSource;
}
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
public TransactionIsolationLevel getLevel() {
return level;
}
public void setLevel(TransactionIsolationLevel level) {
this.level = level;
}
@Override
public boolean isAutoCommit() {
return autoCommit;
}
@Override
public void setAutoCommit(boolean autoCommit) {
this.autoCommit = autoCommit;
}
}
将DataSource置于JdbcTransaction 中,关闭连接是调用事务的方法。
private void release(Connection con, PreparedStatement pstm, ResultSet rs) {
if (con != null) {
try {
if (transaction.isAutoCommit()) {
transaction.close();
}
} catch (Exception e) {
throw new MybatisException("资源释放异常", e);
}
}
if (rs != null) {
try {
rs.close();
} catch (Exception e) {
throw new MybatisException("资源释放异常", e);
}
}
if (pstm != null) {
try {
pstm.close();
} catch (Exception e) {
throw new MybatisException("资源释放异常", e);
}
}
}
@Override
public void close() {
localCache.clear();
try {
transaction.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void clearLocalCache() {
if (!closed) {
localCache.clear();
}
}
@Override
public void rollback() {
try {
transaction.rollback();
} catch (SQLException e) {
e.printStackTrace();
}
}
@Override
public void commit() {
try {
transaction.commit();
} catch (SQLException e) {
e.printStackTrace();
}
}
最终在Executor中执行事务的各种操作。
github:https://github.com/Alice-175/Mybaits
gitee:https://gitee.com/alice-175/Mybaits