SpringBoot+MySQL+MyBatis+druid+redis整合 实现功能:初始化商品列表从数据库读取加载至redis中

首先说一下本章的简单需求: 当SpringBoot项目启动的时候,从MySQL初始化数据到Redis中。

我们要实现的功能:

  • 配置redis连接
  • 配置MySQL和Druid连接
  • 编写数据库代码
  • 编写SpringBoot controller,service,dao,mapper以及初始化init方法

一、首先编写SpringBoot相关配置

配置文件application.properties,请注意mybatis.mapper的相关配置中mybatis.mapper-locations扫描的路径

#thymeleaf
spring.thymeleaf.cache=false
spring.thymeleaf.check-template=true
spring.thymeleaf.check-template-location=true
spring.thymeleaf.enabled=true
spring.thymeleaf.enable-spring-el-compiler=false
spring.thymeleaf.encoding=UTF-8
spring.thymeleaf.mode=HTML
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.servlet.content-type=text/html
spring.thymeleaf.suffix=.html

#redis
redis.host=192.168.3.104
redis.port=6379
redis.timeout=10
redis.password=553571
redis.poolMaxTotal=10
redis.poolMaxIdle=5
redis.poolMaxWait=5

#mybatis
mybatis.mapper-locations=classpath:mapping/*.xml


# druid
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/umbrelladatabase?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource

 二、编写SQL库测试Demo数据及相应mybatis mapper

CREATE TABLE `product` (
  `productId` bigint(64) NOT NULL,
  `originalPrice` double(10,2) DEFAULT NULL,
  `productTitle` varchar(500) DEFAULT NULL,
  `productName` varchar(500) DEFAULT NULL,
  `productDescription` varchar(5000) DEFAULT NULL,
  `stockCount` int(255) DEFAULT NULL,
  `saleNum` int(255) DEFAULT NULL,
  `productImg` varchar(500) DEFAULT NULL,
  PRIMARY KEY (`productId`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

测试Demo数据

INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (0, 12.00, 'qwe', 'qwe', 'qwe', 1, 12, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (1, 13.00, 'ewrezdszf', 'sa', 'asdf', 2, 2, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (2, 24.00, 'fsdz', 'sdf', 'sf', 4, 234, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (3, 345.00, 'sdfsdszd', 'adf', 'fasdsdf', 344, 423, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (4, 456.00, 's', 'sad', 'f', 34, 423, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (5, 576.00, 'zfdxf', 'f', 'sdf', 43, 23, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (6, 78.00, 'sdf', 'saf', 'sdf', 4234, NULL, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (7, 456.00, 'df', 'f', 'sad', 3, 234234, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (8, 4.00, 'zfdsadf', 'asdadf', 'asdf', 423, 4234, NULL);
INSERT INTO `umbrelladatabase`.`product`(`productId`, `originalPrice`, `productTitle`, `productName`, `productDescription`, `stockCount`, `saleNum`, `productImg`) VALUES (9, 423123.00, 'sadf', 'sdaf', 'sda', 34543, 234, NULL);

 mybatis Mapper

<?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.umbrella.armsmerchant.product_manage.dao.ProductManageDao" >

    <resultMap id="DefaultProductVOtMap" type="com.umbrella.armsmerchant.product_manage.model.DefaultProductVO" >
        <id column="productId" property="productId" jdbcType="BIGINT" />
        <result column="originalPrice" property="originalPrice" jdbcType="DOUBLE" />
        <result column="productTitle" property="productTitle" jdbcType="VARCHAR" />
        <result column="productImg" property="productImg" jdbcType="VARCHAR" />
        <result column="stockCount" property="stockCount" jdbcType="INTEGER" />
    </resultMap>

    <resultMap id="DefaultProductDetailVOMap" type="com.umbrella.armsmerchant.product_manage.model.DefaultProductDetailVO" >
        <id column="productId" property="productId" jdbcType="BIGINT" />
        <result column="originalPrice" property="originalPrice" jdbcType="DOUBLE" />
        <result column="productTitle" property="productTitle" jdbcType="VARCHAR" />
        <result column="productImg" property="productImg" jdbcType="VARCHAR" />
        <result column="productName" property="productName" jdbcType="VARCHAR" />
        <result column="productDescription" property="productDescription" jdbcType="VARCHAR" />
        <result column="saleNum" property="saleNum" jdbcType="VARCHAR" />
        <result column="stockCount" property="stockCount" jdbcType="INTEGER" />
    </resultMap>

    <sql id="DefaultProduct" >
        productId, originalPrice, productTitle, stockCount, productImg
    </sql>
    <sql id="DefaultProductDetail" >
        productId, originalPrice, productTitle, productName, productDescription, stockCount, saleNum, productImg
    </sql>

    <select id="queryDefaultProducts" resultMap="DefaultProductDetailVOMap">
        select
        <include refid="DefaultProduct" />
        from product
    </select>

    <select id="queryDefaultProductDetails" resultMap="DefaultProductDetailVOMap">
        select
        <include refid="DefaultProductDetail" />
        from product
    </select>
</mapper>

 三、编写相关Controller、Service、Dao

 

相关product_manage目录 相关通用工具类目录

四、关键方法细节展示

4.1 匹配redis连接配置的bean

@PropertySource("application.properties")    即获取配置文件的名称

@ConfigurationProperties("redis") 即配置的前缀

package com.umbrella.armsmerchant.common.redis_manage;

import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.PropertySource;
import org.springframework.context.annotation.PropertySources;
import org.springframework.stereotype.Component;

@Component
@PropertySource("application.properties")
@ConfigurationProperties("redis")
public class RedisConfig {
// 以下成员变量请与配置文件中redis.开头的配置信息保持一致
	private String host;
	private int port;
	private int timeout;//秒
	private String password;
	private int poolMaxTotal;
	private int poolMaxIdle;
	private int poolMaxWait;//秒

	public String getHost() {return host;}
	public void setHost(String host) {this.host = host;}
	public int getPort() {return port;}
	public void setPort(int port) {this.port = port;}
	public int getTimeout() {return timeout;}
	public void setTimeout(int timeout) {this.timeout = timeout;}
	public String getPassword() {return password;}
	public void setPassword(String password) {this.password = password;}
	public int getPoolMaxTotal() {return poolMaxTotal;}
	public void setPoolMaxTotal(int poolMaxTotal) {this.poolMaxTotal = poolMaxTotal;}
	public int getPoolMaxIdle() {return poolMaxIdle;}
	public void setPoolMaxIdle(int poolMaxIdle) {this.poolMaxIdle = poolMaxIdle;}
	public int getPoolMaxWait() {return poolMaxWait;}
	public void setPoolMaxWait(int poolMaxWait) {this.poolMaxWait = poolMaxWait;}
}

4.2 redis连接池相关代码

@Service
public class RedisPoolFactory {

	@Autowired
	RedisConfig redisConfig;
	
	@Bean
	public JedisPool JedisPoolFactory() {
		JedisPoolConfig poolConfig = new JedisPoolConfig();
		poolConfig.setMaxIdle(redisConfig.getPoolMaxIdle());
		poolConfig.setMaxTotal(redisConfig.getPoolMaxTotal());
		poolConfig.setMaxWaitMillis(redisConfig.getPoolMaxWait() * 1000);
		JedisPool jp = new JedisPool(poolConfig, redisConfig.getHost(), redisConfig.getPort(),
				redisConfig.getTimeout()*1000, redisConfig.getPassword(), 0);
		return jp;
	}
	
}

4.3 redis通用接口

前期先实现主要的增删查基础功能接口

package com.umbrella.armsmerchant.common.redis_manage;

import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.alibaba.fastjson.JSON;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.ScanParams;
import redis.clients.jedis.ScanResult;

@Service
public class RedisService {
	
	@Autowired
	JedisPool jedisPool;
    //获取数据
	public <T> T get(String key) {
		 Jedis jedis = null;
		 try {
			 jedis =  jedisPool.getResource();
			 T t = (T) jedis.get(key);
			 return t;
		 }finally {
			 if(jedis != null) {
				 jedis.close();
			 }
		 }
	}
    //保存数据
	public <T> boolean set(String key,  T value) {
		 Jedis jedis = null;
		 try {
			 jedis =  jedisPool.getResource();
			 if(key == null || key.length() <= 0) {
				 return false;
			 }
			jedis.set(key, value.toString());
			 return true;
		 }finally {
			 if(jedis != null) {
				 jedis.close();
			 }
		 }
	}
    //删除数据
	public boolean delete(String key) {
		Jedis jedis = null;
		try {
			jedis = jedisPool.getResource();
			long ret = jedis.del(key);
			return ret > 0;
		} finally {
			if (jedis != null) {
				jedis.close();
			}
		}
	}
}

4.4 redis key生成工具

 由于我们后期将会有多种类型的数据都要存放于redis中,所以为了避免key重复和具有一定的业务性,每个key我们统一加一个前缀,下面代码就是简单实现这种功能。

首先定义前缀常量:

package com.umbrella.armsmerchant.common.common_constant;

public class KeyCodeConstant {
    public static final String DEFAULT_PRODUCT_KEY_PREFIX_CODE = "PROD_";
    public static final String DEFAULT_PRODUCT_DETAIL_KEY_PREFIX_CODE = "PROD_D_";
    public static final String USER_KEY_PREFIX_CODE = "USER_";
}

产品类是PROD_开头,产品详情是PROD_D_开头。

其次我们定义生成key的工具类:

package com.umbrella.armsmerchant.common.common_util;

import com.umbrella.armsmerchant.common.common_constant.KeyCodeConstant;
import com.umbrella.armsmerchant.product_manage.model.DefaultProductDetailVO;
import com.umbrella.armsmerchant.product_manage.model.DefaultProductVO;
import com.umbrella.armsmerchant.user_manage.model.UserVO;

/**
 * @program: com.umbrella.armsmerchant.common.common_util
 * @description:
 * @author: liujinghui
 * @create: 2018-11-24 11:12
 **/
public class RedisKeyGen {
    public static String KeyGen(Class clazz,String key){
        if(null == key || "".equals(key)){
            return "";
        }
        if(clazz == DefaultProductVO.class){
            return KeyCodeConstant.DEFAULT_PRODUCT_KEY_PREFIX_CODE+key;
        }else if(clazz == DefaultProductDetailVO.class){
            return KeyCodeConstant.DEFAULT_PRODUCT_DETAIL_KEY_PREFIX_CODE+key;
        }else if(clazz == UserVO.class){
            return KeyCodeConstant.USER_KEY_PREFIX_CODE+key;
        }else{
            return key;
        }
    }
}

可以看出我们按照传入的类型来生成特定的key,至于mysql关于商品id的生成方式我采用的是snowflake工具。具体自己随意。

4.5 SpringBoot与MyBatis和Redis的集成

ProductManageDao :

package com.umbrella.armsmerchant.product_manage.dao;

import com.umbrella.armsmerchant.product_manage.model.DefaultProductDetailVO;
import com.umbrella.armsmerchant.product_manage.model.DefaultProductVO;
import com.umbrella.armsmerchant.product_manage.model.FastSaleProductVO;
import org.springframework.stereotype.Repository;

import java.util.List;

@Repository
public interface ProductManageDao {

    List<DefaultProductVO> queryDefaultProducts();

    List<DefaultProductDetailVO> queryDefaultProductDetails();
}

 ProductManageServiceImpl :

@Service("ProductManageService")
@Transactional
public class ProductManageServiceImpl implements IProductManageService {

    @Autowired
    ProductManageDao productManageDao;

    @Autowired
    RedisService redisService;

    @Override
    public void initProductsToRedis() {
        List<DefaultProductDetailVO> defaultProductDetailVOlist = productManageDao.queryDefaultProductDetails();
        for (DefaultProductDetailVO defaultProductDetailVO : defaultProductDetailVOlist){
            redisService.set(RedisKeyGen.KeyGen(DefaultProductDetailVO.class,defaultProductDetailVO.getProductId()+""), defaultProductDetailVO.toString());
        }
        for(int i=0;i<10;i++){
            System.out.println((String)redisService.get("PROD_D_"+i));
        }
    }
}

4.6 SpringBoot初始化方法的编写:

所谓初始化方法其实就是SpringBoot加载完资源后,自动调用执行的方法, 只需要实现InitializingBean的afterPropertiesSet方法即可。具体Controller类不过多阐述,不是重点。

package com.umbrella.armsmerchant.init_main;


import com.umbrella.armsmerchant.product_manage.service.IProductManageService;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.stereotype.Component;

/**
 * @program: com.umbrella.armsmerchant.main
 * @description:
 * @author: liujinghui
 * @create: 2018-11-24 12:13
 **/
@Component
public class InitServlet implements InitializingBean {

    @Autowired
    @Qualifier("ProductManageService")
    IProductManageService iProductManageService;


    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("***************");
        iProductManageService.initProductsToRedis();
    }

}

5、测试启动我们的项目

可以看到下图中,******为初始化方法的开始。

猜你喜欢

转载自blog.csdn.net/qq_31615049/article/details/84351145