mybatis
mybatis拦截器
参考文档
[mybatis拦截器介绍](https://www.cnblogs.com/fangjian0423/p/mybatis-interceptor.html)
功能介绍:
-
允许拦截的方法及说明:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed) 拦截执行器的方法
ParameterHandler (getParameterObject, setParameters) 拦截参数的处理
ResultSetHandler (handleResultSets, handleOutputParameters) 拦截结果集的处理
StatementHandler (prepare, parameterize, batch, update, query) 拦截Sql语法构建的处理 -
使用说明:
- 拦截器接口 Interceptor
- 拦截器注解 Intercepts
- 拦截器配置(在mybatis-conf主配置文件中配置)
- 拦截器接口 Interceptor
源码分析(原理介绍)
mybatis一二级缓存及关闭
- 一级缓存是 SqlSession 级别的缓存。默认打开,不能关闭,默认session级别,可以调整为statement级别以保证没个sql执行都查数据库。
默认session,可需改为statement
<setting name="localCacheScope" value="SESSION"/>
- 二级缓存是 Mapper 级别的缓存,多个 SqlSession 去操作同一个 Mapper 的 sql 语句,多个 SqlSession 可以共用二级缓存,二级缓存是跨 SqlSession 的。二级缓存默认关闭
默认关闭
<setting name="cacheEnabled" value="true"/>
mybatis使用
jdbc操作数据库步骤
- 加载驱动
- 获取连接
- open SqlSession
- 执行sql
- 关闭连接
public static void main(String[] args) {
insert("Test", 18);
}
static void insert(String name, int age) {
String sql = "insert into user(username,age) value(?,?)";
Connection conn = DbUtil.open();
try {
PreparedStatement pstmt = (PreparedStatement) conn.prepareStatement(sql);
pstmt.setString(1, name);
pstmt.setInt(2, age);
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
DbUtil.close(conn);
}
}
public class DbUtil {
/*
* 打开数据库
*/
private static String driver;//连接数据库的驱动
private static String url;
private static String username;
private static String password;
static {
driver = "com.mysql.jdbc.Driver";//需要的数据库驱动
url = "jdbc:mysql://localhost:3306/test";//数据库名路径
username = "root";
password = "********";
}
public static Connection open() {
try {
Class.forName(driver);
return (Connection) DriverManager.getConnection(url, username, password);
} catch (Exception e) {
System.out.println("数据库连接失败!");
e.printStackTrace();
}//加载驱动
return null;
}
/*
* 关闭数据库
*/
public static void close(Connection conn) {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
mybatis基本使用示例
- 通过配置文件 初始化SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
- 从 SqlSessionFactory 中获取 SqlSession,执行sql
SqlSession session = sqlSessionFactory.openSession();
try {
User user = session.selectOne("org.mybatis.example.UserMapper.selectUser", 1);
System.out.println("user:{}"+user);
} finally {
session.close();
}
-
sqlSession执行sql过程中,有通过数据库连接池获取数据库连接,释放数据库连接的操作
调用链路:DefaultSqlSession -> xx Executor -> PrepareStatement -> Datasource.getConnection -> sql执行 -> 提交事务(事务结束时) -> 释放连接到连接池(close)- 没开启事务时,通常框架会设置datasource 自动提交,即每个sql执行完自动提交事务。每个sql执行时都从连接池获取连接,执行完后,归还连接到数据库连接池;下次执行sql会重新获取连接
- 开启事务后,事务中的sql执行每次获取的是同一个连接,事务提交后,commit,close释放连接。
mybatis重要原理
mybatis架构及源代码解析(// todo)
mybatis架构与源码解析
//todo
sqlSession的创建(基于mybatis spring SqlSessionTemplate)
没开启事务时,每执行一个sql都会创建一个SqlSession;
开启事务后,事务内的sql用同一个sqlSession,SqlSession通过Executor创建PrepareStatement时会通过spring事务管理器获取数据库连接,即一个数据库事务获取的会是同一个数据库连接
mybatis sqlSession下四大对象解析(Executor、StatementHandler、ParameterHandler和ResultSetHandler)
mybatis基于接口的动态代理源码分析
mybatis动态代理源码解析
Mybatis 代理工厂中具体生成动态代理类具体逻辑:
1. 根据 .xml 上关联的 namespace, 通过 ** Class#forName 反射的方式返回 Class 接口对象 (不止 .xml namespace 一种方式)
2. 将得到的 Class 对象(实际就是接口对象)传递给 Mybatis 代理工厂生成代理对象 **,也就是刚才 mapperInterface 属性。
3. mybatis使用JDKproxy生成代理对象,即Proxy.newProxyInstance(类加载器,接口class,代理逻辑/切面伙计/InvoketionHander逻辑)