2022-1-22 MyBatis 鉴别映射器、自定义类型转换器、缓存


根据查询出来的值的类型,选择不同的映射器。
根据查询结果动态选择。

一、discriminator 动态地选择映射

根据enabled字段的值选择不同的映射器

<!--如果结果是1,就映射到resultMap上来,column是判断的字段(这个映射可以动态变)-->

    <resultMap id="UserMapWithRole3" type="org.kk.mybatis02.model.User" >
        <discriminator javaType="int" column="enabled">
            <case value="1" resultMap="UserMapWithRole"></case>
            <case value="0" resultMap="BaseUserMap"></case>
        </discriminator>
        
    </resultMap>

二、自定义类型转换器

eg.数据库中的User 增加字段favourites,为varchar类型
但是在User对象中增加的是List<>favourites

新建一个包为typehandler

注意注解

@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class Varchar2ListHandler implements TypeHandler<List<String>> 

想要从Varchar类型转换成List类型

定义类型转换器:

package org.kk.mybatis02.typehandler;

import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.MappedJdbcTypes;
import org.apache.ibatis.type.MappedTypes;
import org.apache.ibatis.type.TypeHandler;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;

/**
 * @program: mybatis02
 * @description:
 * @author: zjx
 * @create: 2022-01-22 20:45
 **/
@MappedJdbcTypes(JdbcType.VARCHAR)
@MappedTypes(List.class)
public class Varchar2ListHandler implements TypeHandler<List<String>> {

    @Override
    public void setParameter(PreparedStatement preparedStatement, int i, List<String> strings, JdbcType jdbcType) throws SQLException {
        StringBuffer sb=new StringBuffer();
        for(String s:strings)
        {
            sb.append(s).append(",");
        }
        preparedStatement.setString(i,sb.toString());
    }

    @Override
    public List<String> getResult(ResultSet resultSet, String s) throws SQLException {
        String res = resultSet.getString(s);
        if(res!=null)
        {
            return Arrays.asList(res.split(","));
        }
        
        return null;
    }

    @Override
    public List<String> getResult(ResultSet resultSet, int i) throws SQLException {
        String s = resultSet.getString(i);
        if(s!=null)
        {
            return Arrays.asList(s.split(","));
        }


        return null;
    }

    @Override
    public List<String> getResult(CallableStatement callableStatement, int i) throws SQLException {
        String res = callableStatement.getString(i);
        if(res!=null)
        {
            return Arrays.asList(res.split(","));
        }
        

        return null;
    }
}

数据插入表

插入的时候要加上typeHandler的选项

    <insert id="addUser3" parameterMap="org.kk.mybatis02.model.User">
        insert into t_user(t_username,address,favourites) values(#{username},#{address},#{favourites,typeHandler=org.kk.mybatis02.typehandler.Varchar2ListHandler});
    </insert>

    @Test
    public void test3()
    {
        sqlSession=SqlSessionFactoryUtils.getInstance().openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User u=new User();
        u.setUsername("张三");
        u.setAddress("www.zs.com");
//        List<String> fav=new ArrayList<>();
//        fav.add("aaa");
//        fav.add("bbb");
        u.setFavourites(Arrays.asList("足球","篮球"));
        mapper.addUser3(u);
        sqlSession.commit();


    }

从表中读数据

    <resultMap id="BaseUserMap" type="org.kk.mybatis02.model.User">
        <id property="id" column="id"/>
        <result property="username" column="t_username"/>
        <result property="address" column="address"/>
        <result property="favourites" column="favourites" typeHandler="org.kk.mybatis02.typehandler.Varchar2ListHandler"/>
    </resultMap>

也要增加typeHandler字段

三、MyBatis 一级缓存

sqlsession的生命周期内生效
sqlsession在关闭之前有缓存!!
查询出来后,如果set了一些属性,第二次查出来的也会变化(而不是再从数据库中去查)

四、MyBatis二级缓存

应用生成到应用销毁中都生效
config里面需要先开启缓存,这样后面的配置才会生效:

    <settings>
        <setting name="cacheEnabled" value="true"/>
    </settings>

在UserMapper.xml中添加cache标签就表示开启
在这里插入图片描述
开启二级缓存后,所有select语句查找出来的都会缓存,增删改则会更新。
缓存满了 LRU算法
(同一个sqlSessionFactory就是同一缓存)

cache可以作配置:
<cache eviction="LRU" />
eviction:回收策略 缓存的数据存满之后怎么办?
LRU最长时间未使用 FIFO先进先出 SOFT软引用 WEAK

flushInterval=60000 毫秒 刷新间隔(不必要设置)
size 引用的数目 最多可以缓存多少个对象 默认1024

readOnly=“true”

五、MyBatis使用Redis做缓存

依赖mybatis-redis
(还没学qwq)

六、MyBatis 内存分页

内存分页原理是所有数据都查出来以后在内存中进行分页,效率太低。
最好是物理分页,sql中就写好,查出来是什么就是什么。

因此作了解。

接口如下:

 List<User> getAllUsersByPage(RowBounds rowBounds);
    <select id="getAllUsersByPage" resultMap="UserMap">
        select * from t_user;
    </select>

new RowBounds(1, 2) offset,limit 传递分页参数
需要分页的时候sql中什么都不用写

    @Test
    public  void test2()
    {
        sqlSession= SqlSessionFactoryUtils.getInstance().openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = mapper.getAllUsersByPage(new RowBounds(1, 2));
        for(User u:list)
        {
            System.out.println(u);
        }
    }

默认参数:

 List<User> list = mapper.getAllUsersByPage(RowBounds.DEFAULT);

默认offset 0
limit:max_value
不分页

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值