前面提到了,使用mybatis cache,一般是结合redis使用。
一、demo
1、数据表
create table demo.t_address
(id int auto_incrementprimary key,address_name varchar(200) null,address_code varchar(20) null,address_type int null
);
项目结构:
2、pom
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>plus-mybatis-cache</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.2.4</version><relativePath/></parent><dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--尽量不要同时导入mybatis 和 mybatis_plus,避免版本差异--><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.13</version></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId></dependency></dependencies>
</project>
3、配置文件
server.port=1112
server.servlet.context-path=/mybatisCacheDemo
#mysql
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3308/demo?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=wtyy
#mybatis
mybatis.mapper-locations=classpath*:mapper/*Mapper.xml
#打印日志
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 开启二级缓存
mybatis-plus.configuration.cache-enabled=true
#redis
spring.data.redis.host=127.0.0.1
spring.data.redis.port=6379
spring.data.redis.password=
spring.data.redis.lettuce.pool.max-active=8
spring.data.redis.lettuce.pool.max-wait=-1
spring.data.redis.lettuce.pool.max-idle=8
spring.data.redis.lettuce.pool.min-idle=0
spring.data.redis.lettuce.pool.enabled=true
spring.data.redis.lettuce.pool.time-between-eviction-runs=30s
4、util
package com.pluscache.demo.util;import org.springframework.aop.support.AopUtils;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;import java.lang.annotation.Annotation;
import java.util.Map;@Component
public class ApplicationContextUtil implements ApplicationContextAware {private static ApplicationContext applicationContext ;@Overridepublic void setApplicationContext(ApplicationContext applicationContext) throws BeansException {ApplicationContextUtil.applicationContext = applicationContext;}public static Object getBean(String name) {return ApplicationContextUtil.applicationContext.getBean(name);}public static <T> T getBean(String name, Class<T> clazz) {return applicationContext.getBean(name, clazz);}public static <T> T getBean(Class<T> clazz) {return applicationContext.getBean(clazz);}public static <T> Map<String, T> getBeansOfType(Class<T> clazz) {return applicationContext.getBeansOfType(clazz);}public static ApplicationContext getApplicationContext() {return applicationContext;}public static <T extends Annotation> T getAnnotation(Object bean, Class<T> annotationClass) {T annotation = bean.getClass().getAnnotation(annotationClass);if (annotation == null) {annotation = AopUtils.getTargetClass(bean).getAnnotation(annotationClass);}return annotation;}}
5、config
package com.pluscache.demo.config;import com.pluscache.demo.util.ApplicationContextUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.cache.Cache;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import org.springframework.stereotype.Component;@Slf4j
//@Component
public class MybatisRedisCache implements Cache {/* * id是必须的带上的,这里的id会指定当前放入缓存的mapper的namespace* 如这里的id就是com.sample.dao.IEmployeeDao*/private final String id;private RedisTemplate redisTemplate;public MybatisRedisCache(final String id) {//获取redis实例//redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate");//指定key的序列化方式//redisTemplate.setKeySerializer(new StringRedisSerializer());//redisTemplate.setHashKeySerializer(new StringRedisSerializer());this.id = id;}@Overridepublic String getId() {return id;}@Overridepublic void putObject(Object key, Object value) {this.getRedisTemplate();redisTemplate.opsForHash().put(id.toString(),key.toString(),value);}private void getRedisTemplate() {if (redisTemplate == null) {//由于启动期间注入失败,只能运行期间注入,这段代码可以删除redisTemplate = (RedisTemplate) ApplicationContextUtil.getBean("redisTemplate");}}@Overridepublic Object getObject(Object key) {this.getRedisTemplate();return redisTemplate.opsForHash().get(id.toString(),key.toString());}@Overridepublic Object removeObject(Object key) {return null;}@Overridepublic void clear() {this.getRedisTemplate();redisTemplate.delete(id.toString());}@Overridepublic int getSize() {this.getRedisTemplate();return redisTemplate.opsForHash().size(id.toString()).intValue();}
}
6、dto
package com.pluscache.demo.dto;import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;import java.io.Serializable;@Data
@TableName("t_address")
public class AddressDTO implements Serializable {private Integer id;private String addressName;private String addressCode;public Integer addressType;
}
7、dao
(1)repository
可以省略,移到service中
package com.pluscache.demo.repository;import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.pluscache.demo.dto.AddressDTO;
import com.pluscache.demo.mapper.AddressMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;import java.util.List;@Repository
@Slf4j
public class AddressRepository {@Autowiredprivate AddressMapper addressMapper;//plus新增public void insert(AddressDTO addressDTO) {addressMapper.insert(addressDTO);}//手动SQL新增public void save(AddressDTO addressDTO) {addressMapper.save(addressDTO);}public AddressDTO getById(Integer id) {LambdaQueryWrapper<AddressDTO> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(AddressDTO::getId, id);return addressMapper.selectOne(queryWrapper);}public List<AddressDTO> listByType(Integer type) {LambdaQueryWrapper<AddressDTO> queryWrapper = new LambdaQueryWrapper<>();queryWrapper.eq(AddressDTO::getAddressType, type);return addressMapper.selectList(queryWrapper);}public List<AddressDTO> listByTypeRecord(Integer type) {return addressMapper.listByTypeRecord(type);}
}
(2)mapper
在这里做的缓存
package com.pluscache.demo.mapper;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.pluscache.demo.config.MybatisRedisCache;
import com.pluscache.demo.dto.AddressDTO;
import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Param;import java.util.List;@CacheNamespace(implementation = MybatisRedisCache.class, eviction = MybatisRedisCache.class)
public interface AddressMapper extends BaseMapper<AddressDTO> {void save(@Param("record") AddressDTO addressDTO);List<AddressDTO> listByTypeRecord(@Param("type") Integer type);
}
(3)xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.pluscache.demo.mapper.AddressMapper"><cache-ref namespace="com.pluscache.demo.mapper.AddressMapper"/><insert id="save">insert into t_address(address_name,address_code,address_type) values (#{record.addressName},#{record.addressCode},#{record.addressType})</insert><select id="listByTypeRecord" resultType="com.pluscache.demo.dto.AddressDTO">select address_name,address_code from t_address where address_type =#{type}</select></mapper>
8、service
package com.pluscache.demo.service.impl;import com.pluscache.demo.dto.AddressDTO;
import com.pluscache.demo.repository.AddressRepository;
import com.pluscache.demo.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service("addressService")
public class AddressServiceImpl implements AddressService {@Autowiredprivate AddressRepository addressRepository;@Overridepublic void insert(AddressDTO addressDTO) {addressRepository.insert(addressDTO);}@Overridepublic void save(AddressDTO addressDTO) {addressRepository.save(addressDTO);}@Overridepublic AddressDTO getById(Integer id) {return addressRepository.getById(id);}@Overridepublic List<AddressDTO> listByType(Integer type) {return addressRepository.listByType(type);}@Overridepublic List<AddressDTO> listByTypeRecord(Integer type) {return addressRepository.listByTypeRecord(type);}
}
9、controller
package com.pluscache.demo.controller;import com.pluscache.demo.dto.AddressDTO;
import com.pluscache.demo.service.AddressService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/address")
public class AddressController {@Autowiredprivate AddressService addressService;@RequestMapping("/insert")public void insert(AddressDTO addressDTO) {addressService.insert(addressDTO);}@RequestMapping("/save")public void save(AddressDTO addressDTO) {addressService.save(addressDTO);}@RequestMapping("/getById")public AddressDTO getById(Integer id) {return addressService.getById(id);}@RequestMapping("/listByType")public List<AddressDTO> listByType(Integer type) {return addressService.listByType(type);}@RequestMapping("/listByTypeRecord")public List<AddressDTO> listByTypeRecord(Integer type) {return addressService.listByTypeRecord(type);}}
10、启动类
package com.pluscache.demo;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@MapperScan("com.pluscache.demo.mapper")
@SpringBootApplication
public class MybatisPlusApplication {public static void main(String[] args) {SpringApplication.run(MybatisPlusApplication.class, args);}
}
11、测试
(1)新增数据
新增了几条数据
(2)