spring boot学习4之mybatis+redis缓存整合 - Go语言中文社区

spring boot学习4之mybatis+redis缓存整合


       上篇博文学习了spring boot+mybatis+PageHelper分页插件的整合,在此基础上继续扩展,使用redis做数据库的二级缓存。对于用redis做数据库的缓存的必要性,就不多说了,特别是在少写多读的场景下(比如类似全国地区码配置表等常量配置表,或用户信息、角色、权限查询)。直接从缓存拿数据比从数据库(数据库要I/O操作)拿要快得多。


      例子源码是在上篇博文的例子上修改的,就不全部贴出源码了,这只贴出和redis相关的。完整代码,在github上可下载,点击下载


pom.xml

 <parent>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-parent</artifactId>
            <version>1.5.2.RELEASE</version>
     </parent>
     
	<dependencies>
	    <dependency>
	        <groupId>org.springframework.boot</groupId>
	        <artifactId>spring-boot-starter-web</artifactId>
	    </dependency>
		
		  <dependency>
   			 <groupId>org.mybatis.spring.boot</groupId>
    		 <artifactId>mybatis-spring-boot-starter</artifactId>
   			 <version>1.3.0</version>
		</dependency> 

		<dependency>  
    	   <groupId>org.springframework.boot</groupId>
    		<artifactId>spring-boot-starter-redis</artifactId>
    		<version>1.4.3.RELEASE</version>
		</dependency>
		
		<dependency>
    			<groupId>mysql</groupId>
    			<artifactId>mysql-connector-java</artifactId>
		</dependency>
		<dependency>
    		<groupId>com.alibaba</groupId>
    		<artifactId>druid</artifactId>
    		<version>1.0.29</version>
		</dependency>
		
		<!-- 分页插件 -->
		<dependency>
    		<groupId>com.github.pagehelper</groupId>
    		<artifactId>pagehelper</artifactId>
    		<version>4.1.6</version>
		</dependency>

		</dependencies>



application.yml

在spring.datasource后面多加上redis相关的

spring:
    datasource:
        name: db
        type: com.alibaba.druid.pool.DruidDataSource
        url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8
        username: root
        password: root
        driver-class-name: com.mysql.jdbc.Driver
        minIdle: 5
        maxActive: 100
        initialSize: 10
        maxWait: 60000
        timeBetweenEvictionRunsMillis: 60000
        minEvictableIdleTimeMillis: 300000
        validationQuery: select 'x'
        testWhileIdle: true
        testOnBorrow: false
        testOnReturn: false
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 50
        removeAbandoned: true
        filters: stat
        cachePrepStmts: true  # 开启二级缓存
    redis:
        database:  0
        host:  127.0.0.1
        port:  6379
        password: 
        pool:
           max-active: 8
           max-wait: -1
           max-idle: 8
           min-idle: 0
        timeout: 0

UserMapper.java

package com.fei.springboot.dao;

import java.util.List;

import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import com.fei.springboot.domain.User;

@Mapper
public interface UserMapper {

	@Insert("insert sys_user(id,user_name) values(#{id},#{userName})")
	void insert(User u);
	
	@Update("update sys_user set user_name = #{userName} where id=#{id} ")
	void update(User u);
	
	@Delete("delete from sys_user where id=#{id} ")
	void delete(@Param("id")String id);
	
	@Select("select id,user_name from sys_user where id=#{id} ")
	User find(@Param("id")String id);
	
	//注:方法名和要UserMapper.xml中的id一致
	List<User> query(@Param("userName")String userName);
	
	@Delete("delete from sys_user")
	void deleteAll();
}


UserService.java
package com.fei.springboot.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Isolation;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import com.fei.springboot.dao.UserMapper;
import com.fei.springboot.domain.User;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;

@Service
@CacheConfig(cacheNames="userCache") // 本类内方法指定使用缓存时,默认的名称就是userCache
@Transactional(propagation=Propagation.REQUIRED,readOnly=false,rollbackFor=Exception.class)
public class UserService {

	@Autowired
	private UserMapper userMapper;
	
	// 因为必须要有返回值,才能保存到数据库中,如果保存的对象的某些字段是需要数据库生成的,
   //那保存对象进数据库的时候,就没必要放到缓存了
	@CachePut(key="#p0.id")  //#p0表示第一个参数
	//必须要有返回值,否则没数据放到缓存中
	public User insertUser(User u){
		this.userMapper.insert(u);
		//u对象中可能只有只几个有效字段,其他字段值靠数据库生成,比如id
		return this.userMapper.find(u.getId());
	}
	
	
	@CachePut(key="#p0.id")
	public User updateUser(User u){
		this.userMapper.update(u);
		//可能只是更新某几个字段而已,所以查次数据库把数据全部拿出来全部
		return this.userMapper.find(u.getId());
	}
	
	@Cacheable(key="#p0") // @Cacheable 会先查询缓存,如果缓存中存在,则不执行方法
	public User findById(String id){
		System.err.println("根据id=" + id +"获取用户对象,从数据库中获取");
		return this.userMapper.find(id);
	}
	
	@CacheEvict(key="#p0")  //删除缓存名称为userCache,key等于指定的id对应的缓存
	public void deleteById(String id){
		this.userMapper.delete(id);
	}
	
	//清空缓存名称为userCache(看类名上的注解)下的所有缓存
	//如果数据失败了,缓存时不会清除的
	@CacheEvict(allEntries = true)  
	public void deleteAll(){
		this.userMapper.deleteAll();
	}
	
	public PageInfo<User> queryPage(String userName,int pageNum,int pageSize){
		Page<User> page = PageHelper.startPage(pageNum, pageSize);
		//PageHelper会自动拦截到下面这查询sql
		this.userMapper.query(userName);
		return page.toPageInfo();
	}
	
	
	
}

用到了注解@CacheConfig,@CachePut,@Cacheable

@CachePut 是先执行方法,然后把返回值保存或更新到缓存中

@Cacheable 是先查询缓存,如果缓存有值,则不执行方法了;否则执行方法,然后把返回值保存到缓存

更多的信息可自行百度


UserController.java

package com.fei.springboot.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fei.springboot.domain.User;
import com.fei.springboot.service.UserService;
import com.github.pagehelper.PageInfo;

@Controller
@RequestMapping("/user")
public class UserController {

	
	@Autowired
	private UserService userService;
	
	@RequestMapping("/hello")
	@ResponseBody
	public String hello(){
		return "hello";
	}
	/**
	 * 测试插入
	 * @return
	 */
	@RequestMapping("/add")
	@ResponseBody
	public String add(String id,String userName){
		User u = new User();
		u.setId(id);
		u.setUserName(userName);
		this.userService.insertUser(u);
		return u.getId()+"    " + u.getUserName();
	}
	
	/**
	 * 测试根据id查询
	 * @return
	 */
	@RequestMapping("/get/{id}")
	@ResponseBody
	public String findById(@PathVariable("id")String id){
		User u = this.userService.findById(id);
		return u== null ? "找不到对象" :( u.getId()+"    " + u.getUserName());
	}
	
	
	/**
	 * 测试修改
	 * @return
	 */
	@RequestMapping("/update")
	@ResponseBody
	public String update(String id,String userName){
		User u = new User();
		u.setId(id);
		u.setUserName(userName);
		this.userService.updateUser(u);
		return u.getId()+"    " + u.getUserName();
	}
	
	/**
	 * 测试删除
	 * @return
	 */
	@RequestMapping("/delete/{id}")
	@ResponseBody
	public String delete(@PathVariable("id")String id){
		this.userService.deleteById(id);
		return "success";
	}
	
	/**
	 * 测试全部
	 * @return
	 */
	@RequestMapping("/deleteAll")
	@ResponseBody
	public String deleteAll(){
		this.userService.deleteAll();
		return "success";
	}
	
	
	
	/**
	 * 测试分页插件
	 * @return
	 */
	@RequestMapping("/queryPage")
	@ResponseBody
	public String queryPage(){
		PageInfo<User> page = this.userService.queryPage("tes", 1, 2);
		System.out.println("总页数=" + page.getPages());
		System.out.println("总记录数=" + page.getTotal()) ;
		for(User u : page.getList()){
			System.out.println(u.getId() + " t " + u.getUserName());
		}
		return page.toString();
	}
}

使用redisClient对redis进行查看


测试:

1.新增用户123  test123时,redis中查看到数据

2.更新用户123,redis和数据库都看到变更后的信息

3.查询用户123 时,控制台没看到查询方法中写的打印信息,说明走的是缓存

4.删除用户123,redisClient、和数据库都没看到记录了

5.查询用户123,控制台有看到查询方法中写的打印信息,说明缓存中没有,执行了方法,企图从数据库中拿数据

6.新增用户123,456,redis和数据库中都看到数据

7.删除全部,redis和数据库都清空了


经过上面的测试,发现redis达到了想要的效果。

例子完整源码,git上下载




版权声明:本文来源CSDN,感谢博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
原文链接:https://blog.csdn.net/dream_broken/article/details/72602218
站方申明:本站部分内容来自社区用户分享,若涉及侵权,请联系站方删除。
  • 发表于 2020-03-01 17:52:30
  • 阅读 ( 1527 )
  • 分类:Redis

0 条评论

请先 登录 后评论

官方社群

GO教程

推荐文章

猜你喜欢