springboot+redis+jpa+mysql 搭建

之前项目中用到redis缓存,这个在互联网企业中非常常用,这边就建立一个工程基于springboot,数据库用的是mysql连接方式采用的是jpa(也可以是mybits),缓存用的是redis。

Springboot整合Redis有两种方式,分别是Jedis和RedisTemplate,这两者有何区别?

Jedis是Redis官方推荐的面向Java的操作Redis的客户端,而RedisTemplate是SpringDataRedis中对JedisApi的高度封装。其实在Springboot的官网上我们也能看到,官方现在推荐的是SpringDataRedis形式,相对于Jedis来说可以方便地更换Redis的Java客户端,其比Jedis多了自动管理连接池的特性,方便与其他Spring框架进行搭配使用如:SpringCache。

在这之前我在低版本的Springboot项目中一直使用Jedis操作Redis,但是我也意识到这种做法已经过时了,所以在升级了Springboot版本后特地在此篇中详细梳理一下,以后项目都会使用这个版本的整合方案,不再使用Jedis方式,不过我还是会再写一篇使用Jedis操作Redis的文章,因为从中能很清楚的看到其基本的工作方式,对Redis连接池的手动管理都能更清晰地体现出来。

工程源码github地址:源码地址

我这边现在自己mysql中建立一个数据库test_data,建立表user_info;表结构:

CREATE TABLE `user_info` (
  `id` varchar(20) NOT NULL,
  `name` varchar(200) DEFAULT NULL,
  `age` varchar(20) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC

然后使用idea建立spring boot工程,加入redis依赖,mysql依赖,jpa依赖,我这边最终使用的pom.xml是:



    4.0.0
    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.3.RELEASE
         
    
    com.test
    redis
    0.0.1-SNAPSHOT
    redis
    Demo project for Spring Boot

    
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            org.springframework.boot
            spring-boot-starter-data-redis
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            mysql
            mysql-connector-java
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        
        
            commons-io
            commons-io
            2.5
        

        
            org.apache.httpcomponents
            httpclient
        

        
            org.apache.httpcomponents
            httpmime
        


        
            org.apache.poi
            poi
            3.13
        
        
            org.apache.poi
            poi-ooxml
            3.13
        
        
            org.apache.poi
            ooxml-schemas
            1.1
        
        
            com.google.code.gson
            gson
            2.8.4
        
        
            com.alibaba
            druid
            1.1.9
        
        
            junit
            junit
        
        
            junit
            junit
            test
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    


这边配置本地redis 端口号在7006 ,ip是127.0.0.1

对应的配置文件是:

#服务启动端口
server :
  port :  9980

#数据库配置
spring:
  datasource:
    name: test
    url: jdbc:mysql://127.0.0.1:3306/test_data?useUnicode=true&characterEncoding=utf-8&autoReconnect=true&allowMultiQueries=true&useSSL=false&zeroDateTimeBehavior=convertToNull
    username: root
    password: 123456
    driver-class-name: com.mysql.jdbc.Driver
    filters: stat
    maxActive: 20
    initialSize: 1
    maxWait: 60000
    minIdle: 1
    timeBetweenEvictionRunsMillis: 60000
    minEvictableIdleTimeMillis: 300000
    validationQuery: select 'x'
    testWhileIdle: true
    testOnBorrow: false
    testOnReturn: false
    poolPreparedStatements: true
    maxOpenPreparedStatements: 20
  redis:
    host: 127.0.0.1
    #redis密码,没有密码的可以用~表示
    password: ~
    port: 7006
#    pool:
#      max-active: 100
#      max-idle: 10
#      max-wait: 100000

# 日志输出
#logging:
#  file: ~/boot.log
#  level:
#    com.ibatis:DEBUG
#    root:DEBUG

task:
  cron:0 0/5 * * * ?

几个比较核心的类有,redisService对外接口,UserInfo,UserInfoService,RedisServiceImpl对redis操作主要依赖于redisTemplate这个工具类。

具体代码如下:

redisService:

package com.test.redis.service;

import java.util.List;

public interface RedisService {

     boolean set(String key, String value) throws Exception;

     String get(String key) throws Exception;

     boolean expire(String key, long expire) throws Exception;

      boolean setList(String key, List list) throws Exception;

      List getList(String key, Class clz) throws Exception;

     long lpush(String key, Object obj) throws Exception;

     long rpush(String key, Object obj) throws Exception;

     void hmset(String key, Object obj) throws Exception;

      T hget(String key, Class clz) throws Exception;


     void del(String key) throws Exception;

      List  hmGetAll(String key, Class clz) throws Exception;

     String lpop(String key) throws Exception;
}

 RedisServiceImpl

package com.test.redis.service.impl;

import com.test.redis.service.RedisService;
import com.test.redis.utils.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.Assert;

import java.util.*;
import java.util.concurrent.TimeUnit;

/**
 * Created by xiaour.github.com on 2017/11/8.
 */
@Service("redisService")
@Transactional(rollbackFor = Exception.class)
public class RedisServiceImpl implements RedisService {

    private static int seconds=3600*24;

    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public boolean set(final String key, final String value) throws Exception {
        Assert.hasText(key,"Key is not empty.");
        boolean result = redisTemplate.execute(new RedisCallback() {
            @Override
            public Boolean doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                connection.set(serializer.serialize(key), serializer.serialize(value));
                return true;
            }
        });
        return result;
    }

    public String get(final String key) throws Exception {
        Assert.hasText(key,"Key is not empty.");
        String result = redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                byte[] value =  connection.get(serializer.serialize(key));
                return serializer.deserialize(value);
            }
        });
        return result;
    }

    public void del(final String key) throws Exception {
        Assert.hasText(key,"Key is not empty.");

        redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection conn) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                return conn.del(serializer.serialize(key));
            }
        });
    }



    @Override
    public boolean expire(final String key, long expire) {
        return redisTemplate.expire(key, expire, TimeUnit.SECONDS);
    }

    @Override
    public  boolean setList(String key, List list) throws Exception {
        Assert.hasText(key,"Key is not empty.");

        String value = JsonUtil.getJsonString(list);
        return set(key,value);
    }

    @Override
    public  List getList(String key,Class clz)  throws Exception{

        Assert.hasText(key,"Key is not empty.");

        String json = get(key);
        if(json!=null){
            List list = JsonUtil.readJson2Array(json,clz);
            return list;
        }
        return null;
    }

    @Override
    public long lpush(final String key, Object obj)throws Exception {
        Assert.hasText(key,"Key is not empty.");

        final String value = JsonUtil.getJsonString(obj);
        long result = redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                long count = connection.lPush(serializer.serialize(key), serializer.serialize(value));
                return count;
            }
        });
        return result;
    }

    @Override
    public long rpush(final String key, Object obj) throws Exception{
        Assert.hasText(key,"Key is not empty.");

        final String value = JsonUtil.getJsonString(obj);
        long result = redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                long count = connection.rPush(serializer.serialize(key), serializer.serialize(value));
                return count;
            }
        });
        return result;
    }

    @Override
    public void hmset(String key, Object obj)  throws Exception{
        Assert.hasText(key,"Key is not empty.");

        Map data=JsonUtil.readJsonByteMap(JsonUtil.getJsonString(obj));
        redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                connection.hMSet(serializer.serialize(key),data);
                return "";
            }
        });
    }

    @Override
    public  T hget(String key, Class clz)  throws Exception{
        Assert.hasText(key,"Key is not empty.");

        return redisTemplate.execute(new RedisCallback() {

            @Override
            public T doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();

                Map result;

                Map data=connection.hGetAll(serializer.serialize(key));
                result= new HashMap<>();
                for (Map.Entry entry: data.entrySet()) {
                    result.put(serializer.deserialize(entry.getKey()),serializer.deserialize(entry.getValue()));
                }

                return JsonUtil.json2Obj(JsonUtil.getJsonString(result),clz);
            }
        });
    }

    @Override
    public List  hmGetAll(String key,Class clz) throws Exception{
        Assert.hasText(key,"Key is not empty.");

        List> dataList= new ArrayList<>();
        return redisTemplate.execute(new RedisCallback>() {
            @Override
            public List doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();

                Set keysSet=redisTemplate.keys(key);
                Map data;
                Map result;
                for(String newKey:keysSet) {
                    data=connection.hGetAll(serializer.serialize(newKey));
                    result= new HashMap<>();
                    for (Map.Entry entry: data.entrySet()) {
                        result.put(serializer.deserialize(entry.getKey()),serializer.deserialize(entry.getValue()));
                    }
                    dataList.add(result);
                }
                return JsonUtil.readJson2Array(JsonUtil.getJsonString(dataList),clz);
            }
        });
    }

    @Override
    public String lpop(final String key) throws Exception{
        Assert.hasText(key,"Key is not empty.");

        String result = redisTemplate.execute(new RedisCallback() {
            @Override
            public String doInRedis(RedisConnection connection) throws DataAccessException {
                RedisSerializer serializer = redisTemplate.getStringSerializer();
                byte[] res =  connection.lPop(serializer.serialize(key));
                return serializer.deserialize(res);
            }
        });
        return result;
    }
}

UserInfo 

package com.test.redis.domain;


import javax.persistence.Entity;
import javax.persistence.*;
import java.io.Serializable;

@Entity
@Table(name="UserInfo")
public class UserInfo {

    @Id
    private String id;

    private String name;

    private int age;

    public UserInfo() {
    }

    public UserInfo(String id, String name, int age) {
        this.id = id;
        this.name = name;
        this.age = age;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }


}
UserInfoRepository:
package com.test.redis.domain;

import org.springframework.data.repository.PagingAndSortingRepository;

public interface UserInfoRepository extends PagingAndSortingRepository {
    public UserInfo findOneById(String id);

}

对外测试接口

package com.test.redis.web;


import com.test.redis.domain.UserInfo;
import com.test.redis.service.UserInfoService;
import com.test.redis.service.RedisService;
import com.test.redis.utils.JsonUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;

@RestController
@RequestMapping(value="/test")
public class TestController {
	
	@Autowired
	private RedisService redisService;
	
	@Autowired  
    private UserInfoService userInfoService;

    @RequestMapping(value="/index")
    public String index(){
        return "hello world";
    }
    
    /**
     * 向redis存储值
     * @param key
     * @param value
     * @return
     * @throws Exception
     */
    @RequestMapping("/set/{key}/{value}")
    public String set(@PathVariable("key")String key, @PathVariable("value")String value) throws Exception{

        redisService.set(key, value);
        return "success";  
    }  
    
    /**
     * 获取redis中的值
     * @param key
     * @return
     */
    @RequestMapping("/get/{key}")
    public String get(@PathVariable("key")String key){
        try {
			return redisService.get(key);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";  
    }  
    
    /**
     * 获取数据库中的用户
     * @param id
     * @return
     */
    @RequestMapping("/getUser/{id}")  
    public String getUser(@PathVariable String id){
        try {
        	UserInfo user= userInfoService.findById(id);
			return JsonUtil.getJsonString(user);
		} catch (Exception e) {
			e.printStackTrace();
		}
		return "";  
    }

    @GetMapping( "/getdata")
    public String getData()
    {
        System.out.println("info has been gotten");
        return "info got";
    }


    @RequestMapping(value = "/saveUser/{name}/{age}" , method = RequestMethod.POST)
    public String putUser(@PathVariable String name,@PathVariable int age){
        try {
            userInfoService.saveData(name,age);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }


    public static void main(String[] args) {
        Map keyMap= new HashMap<>();
        keyMap.put("id","编号");
        keyMap.put("name","名称");

        String [] cnCloumn={"编号","名称"};

        System.out.println(Arrays.asList(convertMap(keyMap, cnCloumn)));

    }

    public static String[] convertMap(Map keyMap,String [] dataList){

        for(int i=0;i m:keyMap.entrySet()){
                if(m.getValue().equals(dataList[i])){
                   dataList[i]=m.getKey();
                }
            }
        }

        return dataList;
    }


    public static String getName(String name,String add){
        return null;
    }

    public static void testGetClassName() {
        // 方法1:通过SecurityManager的保护方法getClassContext()
        String clazzName = new SecurityManager() {
            public String getClassName() {
                return getClassContext()[1].getName();
            }
        }.getClassName();
        System.out.println(clazzName);
        // 方法2:通过Throwable的方法getStackTrace()
        String clazzName2 = new Throwable().getStackTrace()[1].getClassName();
        System.out.println(clazzName2);
        // 方法3:通过分析匿名类名称()
        String clazzName3 = new Object() {
            public String getClassName() {
                String clazzName = this.getClass().getName();
                return clazzName.substring(0, clazzName.lastIndexOf('$'));
            }
        }.getClassName();
        System.out.println(clazzName3);
        //方法4:通过Thread的方法getStackTrace()
        String clazzName4 = Thread.currentThread().getStackTrace()[2].getClassName();
        System.out.println(clazzName4);
    }



}

测试在mysql中存储数据:postman或者浏览器中输入: localhost:9980/test/saveUser/xxm/89

springboot+redis+jpa+mysql 搭建_第1张图片

测试在redis中存储数据:postman或者浏览器中输入:http://localhost:9980/test/set/558/666

我这边通过rdm工具可以看到redis中数据:

springboot+redis+jpa+mysql 搭建_第2张图片

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(redis,mysql,spring,boot)