美文网首页
mybatis自定义变量、$与#、映射器、类型转换器

mybatis自定义变量、$与#、映射器、类型转换器

作者: JackSpeed | 来源:发表于2021-04-26 18:33 被阅读0次

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>

自定义类型转换器

  1. 自定义转换器实现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
    }
}

  1. 当字段作为入参时,加上typeHandler属性
select * from t_test where user_hobbies =#{useHobbies,typeHandler=com.ycj.typehandler.String2ListHandler}
  1. 作为返回字段时,在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下的数据。

  1. 在application.yml配置
mybatis: 
  configuration: 
      cache-enable: true
  1. 在mapper.xml 加上,加上之后,当前mapper.xml的查询会走缓存,更新、删除、新增会自动更新缓存
#LRU——最长时间不用的对象(默认),FIFO——先进先出,SOFT——基于软引用策略, 
#flushinterval——缓存刷新时间间隔(默认没有这个配置,配置之后会导致只有在固定时间间隔才更新缓存)
#size——缓存的数量(默认1024)
#readOnly——保证缓存每次返回的是相同的实例,且这个实例不允许被修改
<cache envicion="LRU"  flushinterval="6000" size="1024"  readOnly="true" />

相关文章

网友评论

      本文标题:mybatis自定义变量、$与#、映射器、类型转换器

      本文链接:https://www.haomeiwen.com/subject/ztlerltx.html