bind定义变量
like查询例子
<bind name="userName" value="'%'+inputParam+'%'" />
select * from t_test where user_name like #{userName};
$和#的区别
带#的变量,入参会经过prepareStatement预编译,经过编译之后再把入参拼接到SQL中;而带$符的变量的入参是直接拼接在SQL中,不会加''。直接拼接的这种方式可能会出现SQL注入风险,也就是入参作为一段SQL,然后拼接到原有的SQL语句后面,影响数据和系统安全。
$特殊使用场景:
#动态排序
select * from t_test where 1=1 order by ${columnName}=#{paramName}
#动态查询字段值
select * from t_test where ${columnName}=#{paramValue}
鉴别映射器
可根据字段不同的值,定义不懂的对象
<resultMap id="BaseResultMap" type="com.ycj.User">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userAge" column="user_age"/>
<result property="userStatus" column="user_status"/>
<result property="memo" column="memo"/>
</resultMap>
<resultMap id="UserResultMap2" type="com.ycj.User">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userAge" column="user_age"/>
<result property="userStatus" column="user_status"/>
</resultMap>
<resultMap id="UserResultMap2" type="com.ycj.User">
<discriminator javaType="int" column="userStatus">
<case value="0" resultMap="UserResultMap1"></case>
<case value="1" resultMap="BaseResultMap"></case>
</discriminator>
</resultMap>
<select id="selectByUserName" resultMap="userResultMap2">
select * from t_test where user_name='haha' and user_status='1';
</select>
自定义类型转换器
- 自定义转换器实现TypeHandler接口,并且增加MapperJdbcTypes、MappedTypes注解
//字符串转成list转换器
@MapperJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class String2ListHandler implements TypeHandler<List<String>>{
@Overiide
void setParameter(......){
//入参List转成String
}
@Overiide
List<String> getResult(.){
//出参String转换成List
}
@Overiide
List<String> getResult(){
//出参String转换成List
}
}
- 当字段作为入参时,加上typeHandler属性
select * from t_test where user_hobbies =#{useHobbies,typeHandler=com.ycj.typehandler.String2ListHandler}
- 作为返回字段时,在resultMap增加typeHandler属性
<resultMap id="BaseResultMap" type="com.ycj.User">
<id property="id" column="id"/>
<result property="userName" column="user_name"/>
<result property="userAge" column="user_age"/>
<result property="userStatus" column="user_status"/>
<result property="memo" column="memo"/>
<result property="userHobbies" column="user_hobbies" typeHandler="com.ycj.typehandler.String2ListHandler"/>
</resultMap>
一级缓存
在同一个SQLsession中,同一条sql多次执行时,只走一次真实的查询,其他的直接取缓存中的结果返回
public class CacheTest{
private UserMapper userMapper;
private SqlSession sqlSession;
@Before
public void initSession(){
sqlSession=new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")).openSession();
userMapper=sqlSession.getMapper(UserMapper.class);
}
@Test
public void testCache1(){
User user1=userMapper.queryByUserId(22L);
System.out.println("user1:"+user1);
user1.setUserName("呵呵");
User user2=userMapper.queryByUserId(22L);
System.out.println("user2:"+user2);
//sout输出的结果中,user2的userName为呵呵,跟user1的不一致
}
@After
public void afterRun(){
sqlSession.close();
}
}
二级缓存
二级缓存会在SQL执行更新、删除、修改数据时,更新缓存中的数据。查询先从缓存中查,没有再走SQL查询。二级缓存不受session影响,session关闭之后,重新打开的session还是会走缓存查询,它影响的是一个SqlSessionFactory下的数据。
- 在application.yml配置
mybatis:
configuration:
cache-enable: true
- 在mapper.xml 加上,加上之后,当前mapper.xml的查询会走缓存,更新、删除、新增会自动更新缓存
#LRU——最长时间不用的对象(默认),FIFO——先进先出,SOFT——基于软引用策略,
#flushinterval——缓存刷新时间间隔(默认没有这个配置,配置之后会导致只有在固定时间间隔才更新缓存)
#size——缓存的数量(默认1024)
#readOnly——保证缓存每次返回的是相同的实例,且这个实例不允许被修改
<cache envicion="LRU" flushinterval="6000" size="1024" readOnly="true" />
网友评论