bind定義變量
like查詢例子
<bind name="userName" value="'%'+inputParam+'%'" />
select * from t_test where user_name like #{userName};
$和#的區(qū)別
帶#的變量,入?yún)?jīng)過prepareStatement預(yù)編譯,經(jīng)過編譯之后再把入?yún)⑵唇拥絊QL中;而帶$符的變量的入?yún)⑹侵苯悠唇釉赟QL中,不會加''。直接拼接的這種方式可能會出現(xiàn)SQL注入風(fēng)險(xiǎn),也就是入?yún)⒆鳛橐欢蜸QL,然后拼接到原有的SQL語句后面,影響數(shù)據(jù)和系統(tǒng)安全。
$特殊使用場景:
#動(dòng)態(tài)排序
select * from t_test where 1=1 order by ${columnName}=#{paramName}
#動(dòng)態(tài)查詢字段值
select * from t_test where ${columnName}=#{paramValue}
鑒別映射器
可根據(jù)字段不同的值,定義不懂的對象
<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>
自定義類型轉(zhuǎn)換器
- 自定義轉(zhuǎn)換器實(shí)現(xiàn)TypeHandler接口,并且增加MapperJdbcTypes、MappedTypes注解
//字符串轉(zhuǎn)成list轉(zhuǎn)換器
@MapperJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class String2ListHandler implements TypeHandler<List<String>>{
@Overiide
void setParameter(......){
//入?yún)ist轉(zhuǎn)成String
}
@Overiide
List<String> getResult(.){
//出參String轉(zhuǎn)換成List
}
@Overiide
List<String> getResult(){
//出參String轉(zhuǎn)換成List
}
}
- 當(dāng)字段作為入?yún)r(shí),加上typeHandler屬性
select * from t_test where user_hobbies =#{useHobbies,typeHandler=com.ycj.typehandler.String2ListHandler}
- 作為返回字段時(shí),在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>
一級緩存
在同一個(gè)SQLsession中,同一條sql多次執(zhí)行時(shí),只走一次真實(shí)的查詢,其他的直接取緩存中的結(jié)果返回
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輸出的結(jié)果中,user2的userName為呵呵,跟user1的不一致
}
@After
public void afterRun(){
sqlSession.close();
}
}
二級緩存
二級緩存會在SQL執(zhí)行更新、刪除、修改數(shù)據(jù)時(shí),更新緩存中的數(shù)據(jù)。查詢先從緩存中查,沒有再走SQL查詢。二級緩存不受session影響,session關(guān)閉之后,重新打開的session還是會走緩存查詢,它影響的是一個(gè)SqlSessionFactory下的數(shù)據(jù)。
- 在application.yml配置
mybatis:
configuration:
cache-enable: true
- 在mapper.xml 加上,加上之后,當(dāng)前mapper.xml的查詢會走緩存,更新、刪除、新增會自動(dòng)更新緩存
#LRU——最長時(shí)間不用的對象(默認(rèn)),F(xiàn)IFO——先進(jìn)先出,SOFT——基于軟引用策略,
#flushinterval——緩存刷新時(shí)間間隔(默認(rèn)沒有這個(gè)配置,配置之后會導(dǎo)致只有在固定時(shí)間間隔才更新緩存)
#size——緩存的數(shù)量(默認(rèn)1024)
#readOnly——保證緩存每次返回的是相同的實(shí)例,且這個(gè)實(shí)例不允許被修改
<cache envicion="LRU" flushinterval="6000" size="1024" readOnly="true" />