文章目录
根据查询出来的值的类型,选择不同的映射器。
根据查询结果动态选择。
一、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
不分页