八、通用Mapper的二级缓存
8.1 通用Mapper缓存测试
在PorscheMapperTest测试类中增加一个testCache测试方法
@Test public void testCache(){ // 第一次执行selectAll List<Porsche> porscheList = porscheMapper.selectAll(); for (int i = 0; i < 3; i++) { System.out.println("第一次查询到的前三条:" + porscheList.get(i).getPorName()); } // 第二次执行selectAll List<Porsche> porsches = porscheMapper.selectAll(); for (int i = 0; i < 3; i++) { System.out.println("第二次查询到的前三条:" + porsches.get(i).getPorName()); } } 复制代码
执行测试
调用了两次selectAll方法,控制台输出了两条SQL语句,说明并没有直接从缓存中提取数据
8.2 通用Mapper二级缓存配置
通用Mapper二级缓存的开启与原生MyBatis二级缓存的开启有相同的地方也有不同的地方
相同点:
- 都需要在MyBatis全局配置文件中开启二级缓存
<settings> <setting name="cacheEnabled" value="true"/> </settings> 复制代码
- 都需要Entity实体类实现Serializable接口
不同点
- 原生MyBatis还需要在Mapper XML中的mapper标签下添加cache标签
- 通用Mapper由于没有Mapper XML,所以他的做法是在Mapper接口上增加@CacheNamespace,以实现同样的效果
原生MyBatis的一级缓存和二级缓存可以参考QA 由浅入深持久层框架(七)- MyBatis Cache
配置完成之后再次对PorscheMapperTest中的testCache方法执行测试
九、通用Mapper的TypeHandler
9.1 简单类型和复杂类型
基本数据类型与引用数据类型
- 基本数据类型:byte、short、int、long、double、float、char、boolean
- 引用数据类型:接口、类、数组、枚举
简单类型与复杂类型
- 简单类型:只有一个值的类型
- 复杂类型:多个简单类型组合起来
9.2 通用Mapper处理复杂类型数据
9.2.1 搭建common-mapper-typehandler项目
新建一个项目common-mapper-typehandler,项目依赖以及配置文件可以参考common-mapper项目。
创建table_user表,并插入一条数据
DROP TABLE IF EXISTS `table_user`; CREATE TABLE `table_user` ( `user_id` int(11) NOT NULL AUTO_INCREMENT, `user_name` varchar(100) DEFAULT NULL, `address` varchar(100) DEFAULT NULL, `season` varchar(100) DEFAULT NULL, PRIMARY KEY (`user_id`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8; -- ---------------------------- -- Records of table_user -- ---------------------------- BEGIN; INSERT INTO `table_user` VALUES (1, 'stark', 'State of New York,New York City,Marbury Street', 'SPRING'); COMMIT; SET FOREIGN_KEY_CHECKS = 1; 复制代码
entity中创建User、Address实体类以及SeasonEnum枚举类
@Data @Table(name = "table_user") public class User { @Id private Integer userId; private String userName; private Address address; private SeasonEnum season; } 复制代码
@Data public class Address { private String province; private String city; private String street; } 复制代码
public enum SeasonEnum { SPRING("spring"),SUMMER("summer"),AUTUMN("autumn"),WINTER("winter"); private String seasonName; private SeasonEnum(String seasonName){ this.seasonName = seasonName; } public String getSeasonName(){ return this.seasonName; } public String toString(){ return this.seasonName; } } 复制代码
User实体类中Integer和String可以称作简单类型,Address和SeasonEnum属性可以称为复杂类型。
新建mapper包,增加UserMapper接口并继承通用Mapper的Mapper接口
public interface UserMapper extends Mapper<User> { } 复制代码
新建service及impl包,增加UserService接口以及UserServiceImpl实现类,新增getUserById方法
public interface UserService { User getUserById(Integer id); } 复制代码
@Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getUserById(Integer id) { return userMapper.selectByPrimaryKey(id); } } 复制代码
在test包中新增UserServiceTest,对UserService中的getUserById方法进行测试
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration("classpath:application.xml") public class UserServiceTest { @Autowired private UserService userService; @Test public void getUserById() { User user = userService.getUserById(1); System.out.println("查询到的内容为:" + user); } } 复制代码
执行测试
输出的User对象address属性和season属性都是空的
这是因为通用Mapper默认把复杂类型Address和SeasonEnum忽略掉了,默认只处理简单类型
再来试试insert方法,在UserServiceTest中增加saveUser方法的测试
@Test public void saveUser(){ User use = new User(); use.setUserName("banner"); Address address = new Address(); address.setProvince("State of New York"); address.setCity("New York City"); address.setStreet("Unkown"); use.setAddress(address); use.setSeason(SeasonEnum.SPRING); userService.saveUser(use); } 复制代码
执行测试
INSERT语句中address字段和season字段的值是null
通用Mapper默认情况下会忽略复杂类型,对复杂类型不进行“从类到表”的映射