001-Springboot从数据库读取配置文件并启动Redis作为缓存服务器

1、背景:

在正式的开发过程中,我们会有很多不能的环境,用于不同阶段的系统验证。很多时候我们会把一些配置信息配置在数据库的一个表中。先从数据库的表中读取数据,然后再根据配置信息初始化相应的内容。

本示例就讲述如何把Redis集群信息配置在数据库中,通过读取数据库中的Redis配置启动Redis数据库,并且将Redis作为数据库缓存

2、实现

2.1、工程结构

这里写图片描述

2.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>com.example.spring.boot.redis</groupId>
    <artifactId>exapmle-spring-boot-redis</artifactId>
    <version>1.0-SNAPSHOT</version>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <java.version>1.8</java.version>
    </properties>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.3.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis</artifactId>
        </dependency>

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>1.2.0</version>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <version>2.8.4</version>
        </dependency>
    </dependencies>
</project>

2.3、数据准备

-- Redis配置表
DROP TABLE redis_config;
CREATE TABLE redis_config (
  url      CHAR(250) NOT NULL,
  port     INT       NOT NULL,
  username CHAR(64)  NOT NULL,
  password CHAR(250) NOT NULL
);

-- Redis群体地址
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7110', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7111', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7112', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7113', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7114', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7115', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7116', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7117', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7118', 'username', 'password');
INSERT INTO redis_config (url, port, username, password) VALUES ('192.168.241.150', '7119', 'username', 'password');

-- 测试表
DROP TABLE person;
CREATE TABLE person (
  id      INT       NOT NULL PRIMARY KEY  AUTO_INCREMENT,
  name    CHAR(64)  NOT NULL,
  age     INT       NOT NULL,
  address CHAR(250) NOT NULL
);

2.4、应用配置

# 应用上下文根
server.context-path=/redis

# 数据库配置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc\:mysql\://localhost\:3306/springbootredis
spring.datasource.username=root
spring.datasource.password=123456

# 开启调试模式
debug=true

2.5、代码实现

RedisConfig

package com.example.spring.boot.redis.entity;

/**
 * Author: 王俊超
 * Date: 2017-05-07 09:45
 * All Rights Reserved !!!
 */
public class RedisConfig {
    private String url;
    private int port;
    private String username;
    private String password;

    public String getUrl() {
        return url;
    }

    public void setUrl(String url) {
        this.url = url;
    }

    public int getPort() {
        return port;
    }

    public void setPort(int port) {
        this.port = port;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

Person

package com.example.spring.boot.redis.entity;


/**
 * Author: 王俊超
 * Date: 2017-05-07 11:19
 * All Rights Reserved !!!
 */

public class Person {
    private Long id;

    private String name;

    private Integer age;

    private String address;


    public Person() {
        super();
    }

    public Person(Long id, String name, Integer age, String address) {
        super();
        this.id = id;
        this.name = name;
        this.age = age;
        this.address = address;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public Integer getAge() {
        return age;
    }

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

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }


}

RedisConfigMapper

package com.example.spring.boot.redis.mapper;

import com.example.spring.boot.redis.entity.RedisConfig;

import java.util.List;

/**
 * Author: 王俊超
 * Date: 2017-05-07 09:50
 * All Rights Reserved !!!
 */

public interface RedisConfigMapper {

    /**
     * 获取Redis的配置信息
     *
     * @return
     */
    List<RedisConfig> getRedisConfig();
}

PersonMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.spring.boot.redis.mapper.PersonMapper">

    <insert id="save" parameterType="com.example.spring.boot.redis.entity.Person"
            useGeneratedKeys="true" keyProperty="id" >
        INSERT INTO person (name, age, address) VALUES (#{name}, #{age}, #{address})
    </insert>

    <select id="findOne" parameterType="java.lang.Long" resultType="com.example.spring.boot.redis.entity.Person">
        SELECT
            id      id,
            name    name,
            age     age,
            address address
        FROM person t
        WHERE t.id = #{id}
    </select>

    <delete id="delete" parameterType="java.lang.Long">
        DELETE FROM person t
        WHERE t.id = #{id}
    </delete>
</mapper>

RedisConfigMapper.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.spring.boot.redis.mapper.RedisConfigMapper">

    <!-- 选择出所有的redis配置信息 -->
    <select id="getRedisConfig" resultType="com.example.spring.boot.redis.entity.RedisConfig">
        SELECT
            url      url,
            port     port,
            username usename,
            password password
        FROM redis_config
    </select>

</mapper>

RedisService

package com.example.spring.boot.redis.service;

import com.example.spring.boot.redis.entity.Person;

/**
 * Author: 王俊超
 * Date: 2017-05-07 09:57
 * All Rights Reserved !!!
 */
public interface RedisService {
    Person save(Person person);

    void remove(Long id);

    Person findOne(Person person);
}

RedisServiceImpl

package com.example.spring.boot.redis.service.impl;

import com.example.spring.boot.redis.entity.Person;
import com.example.spring.boot.redis.mapper.PersonMapper;
import com.example.spring.boot.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
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.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * Author: 王俊超
 * Date: 2017-05-07 09:58
 * All Rights Reserved !!!
 */
@Service
@Transactional(readOnly = true)
public class RedisServiceImpl implements RedisService {
    @Autowired
    PersonMapper personRepository;

    /**
     * 创建对象,并且将person对象入缓存,key是person对象的id
     * @param person
     * @return
     */
    @Override
    @CachePut(value = "people", key = "#person.id")
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public Person save(Person person) {
        personRepository.save(person);
        System.out.println("为id、key为:" + person.getId() + "数据做了缓存");
        return person;
    }

    /**
     * 从缓存中删除person对象,key是person对象的id
     * @param id
     */
    @Override
    @CacheEvict(value = "people") //2
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void remove(Long id) {
        System.out.println("删除了id、key为" + id + "的数据缓存");
        //这里不做实际删除操作
    }

    /**
     * 更新对象,并且将person对象入缓存,key是person对象的id
     *
     * @param person
     * @return
     */
    @Override
    @Cacheable(value = "people", key = "#person.id") //3
    public Person findOne(Person person) {
        Person p = personRepository.findOne(person.getId());
        System.out.println("为id、key为:" + p.getId() + "数据做了缓存");
        return p;
    }
}

RedisController

package com.example.spring.boot.redis.controller;

import com.example.spring.boot.redis.entity.Person;
import org.springframework.web.bind.annotation.RequestMapping;

/**
 * Author: 王俊超
 * Date: 2017-05-07 09:57
 * All Rights Reserved !!!
 */
public interface RedisController {
    @RequestMapping("/put")
    public Person put(Person person);

    @RequestMapping("/able")
    public Person cacheable(Person person);

    @RequestMapping("/evit")
    public String evit(Long id);
}

RedisControllerImpl

package com.example.spring.boot.redis.controller.impl;

import com.example.spring.boot.redis.controller.RedisController;
import com.example.spring.boot.redis.entity.Person;
import com.example.spring.boot.redis.service.RedisService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * Author: 王俊超
 * Date: 2017-05-07 09:57
 * All Rights Reserved !!!
 */
@RestController
public class RedisControllerImpl implements RedisController{

    @Autowired
    RedisService redisService;


    @RequestMapping("/put")
    public Person put(Person person) {
        return redisService.save(person);
    }


    @RequestMapping("/able")
    public Person cacheable(Person person) {
        return redisService.findOne(person);
    }

    @RequestMapping("/evit")
    public String evit(Long id) {
        redisService.remove(id);
        return "ok";
    }
}

AppConfig

package com.example.spring.boot.redis.common;

import com.example.spring.boot.redis.entity.RedisConfig;
import com.example.spring.boot.redis.mapper.RedisConfigMapper;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.data.redis.connection.RedisClusterConfiguration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import javax.sql.DataSource;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.List;


/**
 * Author: 王俊超
 * Date: 2017-05-07 10:02
 * All Rights Reserved !!!
 */
@Configuration

@MapperScan(basePackages = "com.example.spring.boot.redis.mapper")
public class AppConfig {


    /**
     * 设置mybatis会话工厂
     * @param ds
     * @return
     * @throws Exception
     */
    @Primary
    @Bean("sqlSessionFactory")
    public SqlSessionFactory sqlSessionFactory(DataSource ds) throws Exception {
        SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
        factory.setDataSource(ds);

        // 设置mybatis xml文件扫描路径
        factory.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:mapper/*Mapper.xml"));
        return factory.getObject();
    }

    /**
     * Redis连接工厂
     * @param mapper 这个非常重要,必须在mapper被创建了之后才能创建Redis连接工厂
     * @return
     */
    @Primary
    @Bean("redisConnectionFactory")
    public RedisConnectionFactory redisConnectionFactory(RedisConfigMapper mapper) {

        // 获取redis连接信息
        List<RedisConfig> redisConfigs = mapper.getRedisConfig();
        List<String> clusterNodes = new ArrayList<>();
        for (RedisConfig rc : redisConfigs) {
            clusterNodes.add(rc.getUrl() + ":" + rc.getPort());
        }

        // 获取Redis集群配置信息
        RedisClusterConfiguration rcf = new RedisClusterConfiguration(clusterNodes);

        return new JedisConnectionFactory(rcf);
    }

    /**
     * 创建redis模板
     *
     * @param redisConnectionFactory
     * @return
     * @throws UnknownHostException
     */
    @Primary
    @Bean("redisTemplate")
    public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
            throws UnknownHostException {
        RedisTemplate<Object, Object> template = new RedisTemplate<>();
        template.setConnectionFactory(redisConnectionFactory);

        Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
        ObjectMapper om = new ObjectMapper();
        om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
        om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
        jackson2JsonRedisSerializer.setObjectMapper(om);

        // redis value使用的序列化器
        template.setValueSerializer(jackson2JsonRedisSerializer);
        // redis key使用的序列化器
        template.setKeySerializer(jackson2JsonRedisSerializer);


        template.afterPropertiesSet();
        return template;
    }
}

AppRunner

package com.example.spring.boot.redis;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
import org.springframework.transaction.annotation.EnableTransactionManagement;

/**
 * Author: 王俊超
 * Date: 2017-05-07 10:04
 * All Rights Reserved !!!
 */
@SpringBootApplication
@EnableTransactionManagement
@EnableCaching
public class AppRunner {
    public static void main(String[] args) {
        SpringApplication.run(AppRunner.class, args);
    }
}

3、执行结果

添加一条记录
这里写图片描述
记录入缓存
这里写图片描述
记录存入数据库
这里写图片描述
从缓存中获取数据
这里写图片描述
清除缓存中的数据
这里写图片描述
缓存中的数据被清空
这里写图片描述

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值