springboot2.0.1版本相对之前的版本来说有较大的改动,所以在配置的时候不太一样。
1.pom.xml
<?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>cn.fx2</groupId>
<artifactId>fx2Back</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<name>fx2Back</name>
<description>后台管理系统</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.1.RELEASE</version>
<relativePath /> <!-- lookup parent from repository -->
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>
<dependencies>
<!-- 分页插件 -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>1.2.3</version>
</dependency>
<!--热部署 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
<!-- 引入freeMarker的依赖包. -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
<!-- Spring-Mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency>
<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Redis配置 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
</dependency>
<!--solr -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-solr</artifactId>
</dependency>
<!--逆向工程 -->
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.application.yml
server:
#服务端口号
port: 8080
debug: true
#spring配置
spring:
#数据源配置
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/manager
username: root
password: 123456
#freemaker配置
freemarker:
allow-request-override: false
cache: true
check-template-location: true
charset: UTF-8
content-type: text/html
expose-request-attributes: false
expose-session-attributes: false
expose-spring-macro-helpers: false
#solr配置
data:
solr:
host: http://localhost:9080/solr
#redis集群配置
redis:
# Redis服务器连接密码(默认为空)
password: *****
jedis:
pool:
# 连接池最大连接数(使用负值表示没有限制)
max-active: 5000
# 连接池最大阻塞等待时间(使用负值表示没有限制)
max-wait: -1
# 连接池中的最大空闲连接
max-idle: 30
# 连接池中的最小空闲连接
min-idle: 5
# 连接超时时间(毫秒)
timeout: 50000
commandTimeout: 50000
#集群
cluster:
nodes: 192.168.0.159:7001,192.168.0.159:7002,192.168.0.159:7003,192.168.0.159:7004,192.168.0.159:7005,192.168.0.159:7006
#mybatis配置
mybatis:
mapper-locations: classpath:mybatis/mapper/*.xml,mybatis/mapper/customize/*.xml
config-location: classpath:mybatis/mybatis-config.xml
3.mybatis-config.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
4.mapper.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="cn.fx2.mapper.BannerMapper">
<cache type="cn.fx2.utils.MybatisRedisCache"></cache>
<select>省略</select>
</mapper>
5.入口类Application.java
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cache.annotation.EnableCaching;
@SpringBootApplication
@MapperScan({"cn.gdq.mapper.customize","cn.gdq.mapper"})
@EnableCaching
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
6.redis集群配置类
import java.net.UnknownHostException;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
/**
* Title: RedisProperties
* @author: gdq
* @date 2018年5月7日
* @version V1.0 Description: redis集群实体类
*/
@Configuration
@ConditionalOnClass({ JedisCluster.class })
public class RedisConfig {
@Value("${spring.redis.cluster.nodes}")
private String clusterNodes;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private long maxWaitMillis;
@Value("${spring.redis.commandTimeout}")
private int commandTimeout;
@Value("${spring.redis.password}")
private String password;
@Bean
public JedisCluster getJedisCluster() {
String[] cNodes = clusterNodes.split(",");
Set<HostAndPort> nodes = new HashSet<HostAndPort>();
// 分割出集群节点
for (String node : cNodes) {
String[] hp = node.split(":");
nodes.add(new HostAndPort(hp[0], Integer.parseInt(hp[1])));
}
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
/*GenericObjectPoolConfig jedisPoolConfig=new GenericObjectPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);*/
// 创建集群对象
// JedisCluster jedisCluster = new JedisCluster(nodes,commandTimeout);
JedisCluster jedisCluster = new JedisCluster(nodes,commandTimeout,timeout,maxIdle,password,jedisPoolConfig);
//JedisCluster jedisCluster=new JedisCluster(nodes,commandTimeout,jedisPoolConfig);
return jedisCluster;
}
/**
* 设置数据存入 redis 的序列化方式 </br>
* redisTemplate 序列化默认使用的jdkSerializeable, 存储二进制字节码, 导致key会出现乱码,所以自定义 序列化类
*
* @param redisConnectionFactory
*/
@Bean
public RedisTemplate<Object, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory)
throws UnknownHostException {
RedisTemplate<Object, Object> redisTemplate = new RedisTemplate<>();
redisTemplate.setConnectionFactory(redisConnectionFactory);
Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
ObjectMapper objectMapper = new ObjectMapper();
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
jackson2JsonRedisSerializer.setObjectMapper(objectMapper);
redisTemplate.setValueSerializer(jackson2JsonRedisSerializer);
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.afterPropertiesSet();
return redisTemplate;
}
}
7.redis作mybatis二级缓存工具类
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import redis.clients.jedis.JedisCluster;
/**
* Title: JedisUtils
* @author: gdq
* @date 2018年5月10日
* @version V1.0 Description: redis做mybatis二级缓存工具类
*/
@Component
public class JedisUtils {
@Autowired
public JedisCluster jedisCluster;
private static String PREFIX="FX2_CACHE";
private static JedisUtils jedisUtils;
@PostConstruct
public void init() {
jedisUtils=this;
jedisUtils.jedisCluster=this.jedisCluster;
}
public static void set(Object key, Object value) {
try {
jedisUtils.jedisCluster.hset(SerializingUtils.serialize(PREFIX),SerializingUtils.serialize(key), SerializingUtils.serialize(value));
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object get(Object key) {
try {
byte[] keyBytes = SerializingUtils.serialize(key);
byte[] prefixBytes = SerializingUtils.serialize(PREFIX);
if (jedisUtils.jedisCluster.hexists(prefixBytes, keyBytes)) {
return SerializingUtils.deserialize(jedisUtils.jedisCluster.hget(prefixBytes,keyBytes));
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
public static void del(Object key) {
try {
byte[] prefixBytes = SerializingUtils.serialize(PREFIX);
jedisUtils.jedisCluster.hdel(prefixBytes,SerializingUtils.serialize(key));
} catch (Exception e) {
e.printStackTrace();
}
}
public static void clear() {
byte[] prefixBytes = SerializingUtils.serialize(PREFIX);
jedisUtils.jedisCluster.del(prefixBytes);
}
public static int getSize() {
return jedisUtils.jedisCluster.dbSize().intValue();
}
}
8.二级缓存实现cache类
import java.util.concurrent.locks.ReadWriteLock;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.CacheException;
import cn.fx2.utils.JedisUtils;
/**
* Title: MybatisRedisCache
* @author: gdq
* @date 2018年5月10日
* @version V1.0
* Description: 二级缓存实现
*/
/**
* Cache为缓存接口,给缓存供应商的SPI(Service Provider Interface)
* Cache接口的实现类必须有一个具有String类型参数的构造方法,该参数作为实现类对象的id,对其进行唯一标识
*/
public class MybatisRedisCache implements Cache {
private String id;
public MybatisRedisCache(String id) {
this.id = id;
}
/**
* 清空缓存
*/
@Override
public void clear() {
JedisUtils.clear();
}
/**
* 获取缓存对象的唯一标识
*/
@Override
public String getId() {
return this.id;
}
/**
* 从缓存对象中获取key对应的value
*/
@Override
public Object getObject(Object key) {
return JedisUtils.get(key);
}
/**
* 获取读写锁 可选的方法,从3.2.6起这个方法不再被框架核心调用 任何需要的锁,都必须由缓存供应商提供
*/
@Override
public ReadWriteLock getReadWriteLock() {
return null;
}
/**
* 获取缓存对象中存储的键/值对的数量 可选的方法,没有被框架核心调用
*/
@Override
public int getSize() {
return JedisUtils.getSize();
}
/**
* 保存key/value到缓存对象中 key可以是任何对象
*/
@Override
public void putObject(Object key, Object value) {
JedisUtils.set(key, value);
}
/**
* 可选的方法,没有被核心框架调用,移除key对应的value
*/
@Override
public Object removeObject(Object key) {
return null;
}
/**
* 重新equals方法
*/
@Override
public boolean equals(Object o) {
if (getId() == null)
throw new CacheException("Cache instances require an ID.");
if (this == o)
return true;
if (!(o instanceof Cache))
return false;
Cache otherCache = (Cache) o;
return getId().equals(otherCache.getId());
}
/**
* 重新hashCode方法
*/
@Override
public int hashCode() {
if (getId() == null)
throw new CacheException("Cache instances require an ID.");
return getId().hashCode();
}
}
9.序列化redis的键值对工具类(将object类型数据转换为字节存入redis)
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/**
* Title: SerializingUtils
* @author: gdq
* @date 2018年5月10日
* @version V1.0
* Description: redis序列化
*/
public class SerializingUtils {
public static byte[] serialize(Object obj) {
ByteArrayOutputStream bos = null;
ObjectOutputStream out = null;
try {
bos = new ByteArrayOutputStream();
out = new ObjectOutputStream(bos);
out.writeObject(obj);
out.flush();
}
catch (IOException e) {
e.printStackTrace();
}finally {
try {
if(out!=null)out.close();
}catch (IOException e) {
e.printStackTrace();
}
}
return bos.toByteArray();
}
public static Object deserialize(byte[] data) {
ObjectInputStream in = null;
Object obj = null;
try {
ByteArrayInputStream byteIn = new ByteArrayInputStream(data);
in = new ObjectInputStream(byteIn);
obj = in.readObject();
}catch (Exception e) {
e.printStackTrace();
}finally {
try {
if(in!=null)in.close();
}catch (IOException e) {
e.printStackTrace();
}
}
return obj;
}
}
10.测试:
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import org.apache.solr.client.solrj.SolrClient;
import org.apache.solr.client.solrj.SolrQuery;
import org.apache.solr.client.solrj.SolrServerException;
import org.apache.solr.client.solrj.response.QueryResponse;
import org.apache.solr.common.SolrDocument;
import org.apache.solr.common.SolrDocumentList;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.fx2.mapper.BannerMapper;
import cn.fx2.pojo.Banner;
import cn.fx2.service.BannerService;
import redis.clients.jedis.JedisCluster;
/**
* Title: BannerServiceImpl
*
* @author: gdq
* @date 2018年5月5日
* @version V1.0 Description: 测试
*/
@Service
public class BannerServiceImpl implements BannerService {
@Autowired
private BannerMapper bannerMapper;
@Autowired
private JedisCluster jedisCluster;
@Autowired
private SolrClient solrClient;
/**
* Title: getBanners
* @author: gdq
* @date 2018年5月5日
* @version V1.0 Description: 测试
*/
@Override
public List<Banner> getBanners() {
jedisCluster.set("test", "778797");
// 组织查询条件
SolrQuery query = new SolrQuery();
// 设置查询关键字
query.setQuery("红烧肉");
// 设置分页条件
query.setStart(0);
query.setRows(10);
List<String> books = new ArrayList<>();
// 设置查询的域
query.set("df", "book_name");
// 组装查询结果
QueryResponse response = null;
try {
response = solrClient.query("collection1", query);//solr多索引库操作只需要变换第一个参数(索引库名字)即可
} catch (SolrServerException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SolrDocumentList results = response.getResults();
for (SolrDocument doc : results) {
books.add((String) doc.get("dataName"));
}
for (String book : books) {
System.err.println(book);
}
return bannerMapper.selectByExample(null);
}
}
有问题可以联系我qgeniu@foxmail.com
本文介绍如何使用Spring Boot 2.0搭建一个包含MyBatis、FreeMarker、Redis等技术的后台管理系统,并实现二级缓存功能。
1407

被折叠的 条评论
为什么被折叠?



