欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Mybatis 学习标注

程序员文章站 2022-07-12 22:19:07
...

Mybatis 了解

Mybatis 配置

/# mapper
mapper:
mappers:
com.zyd.shiro.plugin.BaseMapper
not-empty: false
identity: MYSQL
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

Mybatis:
我们经常使用的是#{},一般解说是因为这种方式可以防止SQL注入,简单的说#{}这种方式SQL语句是经过预编译的,它是把#{}中间的参数转义成字符串
而使用${}在动态解析时候,会传入参数字符串
动态SQL
操作一:

插入数据返回主键ID

<insert id="saveAndGetId" parameterType="com.simtrip.bean.job" useGeneratedKeys="true" keyProperty="id">

useGeneratedKeys,这会令MyBatis使用JDBC的getGeneratedKeys方法获取由数据库内部生成的主键,默认为false,需要配合keyproperty属性使用。useGeneratedKeys=“true” 表示给主键设置自增长
keyproperty,MyBatis会通过getGeneratedKeys的返回值设置它的键值。keyProperty=“id” 表示自增长后的Id赋值给实体类的id字段

Mybatis 分页插件PageHelper

他的原理是利用== mybatis拦截器 ==,在查询数据库的时候,拦截下SQL,然后进行修改,从而实现分页
在插件的拦截方法内拦截待执行的sql,然后重写sql,根据dialect方言,添加对应的物理分页语句和物理分页参数。
MyBatis 允许你在已映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:
Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
ParameterHandler (getParameterObject, setParameters)
ResultSetHandler (handleResultSets, handleOutputParameters)
StatementHandler (prepare, parameterize, batch, update, query)
我们看到了可以拦截Executor接口的部分方法,比如update,query,commit,rollback等方法,还有其他接口的一些方法等。
总体概括为:
拦截执行器的方法
拦截参数的处理
拦截结果集的处理
拦截Sql语法构建的处理

Mapper接口动态代理

public interface UserMapper {
	List<SysUser> selectAll();
}
public class MyMapperProxy<T> implements InvocationHandler {
	private Class<T> mapperInterface;
	private SqlSession sqlSession;
	
	public MyMapperProxy(Class<T> mapperInterface, SqlSession sqlSession) {
			this.mapperInterface = mapperInterface;
			this.sqlSession = sqlSession;
	}

	@Override
	public Object invoke(Object proxy , Method method , Object[] args)
			throws Throwable {
		//针对不同的 sql 类型,需要调用sqlSession不同的方法
		//接口方法中的参数也有很多情况 ,这里只考虑没有有参数的情况
		List<T> list= sqlSession.selectList(
				mapperInterface.getCanonicalName() + ”.” + method.getName());
		//返回位也有很多情况,这里不做处理直接返回
		return list;
	}
}
//获取sqlSession
SqlSession sqlSession = getSqlSession();
//获取 UserMapper 接口
MyMapperProxy userMapperProxy = new MyMapperProxy(
		UserMapper.class , sqlSession) ;
UserMapper userMapper = (UserMapper) Proxy.newProxyinstance (
		Thread.currentThread().getContextClassLoader(),
		new Class[ ] {UserMapper.class},
		userMapperProxy) ;
//调 用 selectAll 方 法
List<SysUser> user= userMapper.selectAll();

Mybatis 缓存机制

== 一级缓存:sqlsession级别的缓存 ==
在操作数据库时,需要构造sqlsession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据 不同的sqlsession之间的缓存区域是互相不影响的。
Mybatis 学习标注

工作原理:
第一次发起查询sql查询用户id为1的用户,先去找缓存中是否有id为1的用户,如果没有,再去数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。
如果sqlsession执行了commit操作(插入,更新,删除),会清空sqlsession中的一级缓存,避免脏读
第二次发起查询id为1的用户,缓存中如果找到了,直接从缓存中获取用户信息
mybatis默认支持一级缓存。
Mybatis 学习标注

== 二级缓存:mapper级别的缓存 ==
     多个sqlsession去操作同一个mapper的sql语句,多个sqlsession可以共用二级缓存,所得到的数据会存在二级缓存区域,二级缓存是跨sqlsession的
工作原理:
Mybatis 学习标注

首先要手动开启mybatis二级缓存。
在config.xml设置二级缓存开关 , 还要在具体的mapper.xml开启二级缓存

<settings>
    <!--开启二级缓存-->
    <setting name="cacheEnabled" value="true"/>       
</settings>

2.需要将映射的javapojo类实现序列化
class Student implements Serializable{}
3.
<cache eviction="LRU" flushInterval="10000"/>
flushCache标签:刷新缓存(清空缓存)
<select id="getStudentById" parameterType="java.lang.Integer" resultType="Student" flushCache="true">
一般下执行完commit操作都需要刷新缓存,flushCache="true 表示刷新缓存,可以避免脏读
二级缓存应用场景
对于访问多的查询请求并且用户对查询结果实时性要求不高的情况下,可采用mybatis二级缓存,降低数据库访问量,提高访问速度,如电话账单查询
根据需求设置相应的flushInterval:刷新间隔时间,比如三十分钟,24小时等。。。

关联查询

只有在做select查询时才会用到这两个标签,都有三种用法,且用法类似
在项目中,某些实体类之间肯定有关键关系,比如一对一,一对多等。在hibernate 中用one to one和one to many,而mybatis 中就用association和collection。
association: 一对一关联(has one)
collection:一对多关联(has many)