Spring Boot + MyBatis + Druid + Redis + Thymeleaf 整合小結
這兩天閑着沒事想利用**Spring Boot**加上阿里的開源數據連接池**Druid**搭建個簡單的框架,主要是想了解一下**Druid**的可視化數據監控,無奈水平受限只能一邊 Google 一邊 整合,后來發現網上的一些整合資源太差強人意,於是我想把我得一些整合思路分享出來,供大家瀏覽,哪里不合適希望可以提出來,一起進步!
特別感謝一下我的朋友 [@碼農界的苦逼猿](https://blog.csdn.net/qq_38011415)
開始
環境:jdk1.8,idea, maven 3.5.0
1、項目結構:
2、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>org.yliu</groupId>
<artifactId>mui</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mui</name>
<description>org.yliu.mui</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.6.RELEASE</version>
<relativePath/>
</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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<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.2</version>
</dependency>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.10</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-configuration-processor</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
到了這一步,項目的基本依賴就算結束了。
3、在這個Demo項目中我用的是application.properties,可根據個人喜好改為application.yml
# 訪問端口
server.port=2088
# 數據庫配置
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.name=demo
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/demo
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.initialSize=1
spring.datasource.minIdle=3
spring.datasource.maxActive=20
spring.datasource.maxWait=60000
spring.datasource.timeBetweenEvictionRunsMillis=60000
spring.datasource.minEvictableIdleTimeMillis=30000
spring.datasource.validationQuery=select 'x'
spring.datasource.testWhileIdle=true
spring.datasource.testOnBorrow=false
spring.datasource.testOnReturn=false
spring.datasource.poolPreparedStatements=true
spring.datasource.maxPoolPreparedStatementPerConnectionSize=20
spring.datasource.filters=stat,wall,slf4j
spring.datasource.connectionProperties=druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
spring.datasource.useGlobalDataSourceStat=true
# redis 配置
spring.redis.port=6379
spring.redis.host=127.0.0.1
spring.redis.password=123456
# thymeleaf 配置
spring.thymeleaf.prefix=classpath:/templates/
spring.thymeleaf.suffix=.html
spring.thymeleaf.cache=false
spring.thymeleaf.check-template-location=true
spring.thymeleaf.encoding=UTF-8
# 日志相關
logging.pattern.console=%d --> %msg%n
# 此處配置sql打印
logging.pattern.level=org.yliu.mui.mapper: debug
4、數據庫創建sql我就不放出來了,可隨意創建數據進行測試
5、創建好表數據 可以使用 mybatis generator 自動生成代碼,
假設我有一張 **User** 表,那么生成的相關文件為:
對應數據庫的實體:
package org.yliu.mui.pojo.po;
import java.util.Date;
public class MallUserPo {
private Integer id;
private String guid;
private String avatars;
private String openId;
private String userName;
private Integer sex;
private String phone;
private String targetPhone;
private Date createTime;
private Date updateTime;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getGuid() {
return guid;
}
public void setGuid(String guid) {
this.guid = guid == null ? null : guid.trim();
}
public String getAvatars() {
return avatars;
}
public void setAvatars(String avatars) {
this.avatars = avatars == null ? null : avatars.trim();
}
public String getOpenId() {
return openId;
}
public void setOpenId(String openId) {
this.openId = openId == null ? null : openId.trim();
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName == null ? null : userName.trim();
}
public Integer getSex() {
return sex;
}
public void setSex(Integer sex) {
this.sex = sex;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone == null ? null : phone.trim();
}
public String getTargetPhone() {
return targetPhone;
}
public void setTargetPhone(String targetPhone) {
this.targetPhone = targetPhone == null ? null : targetPhone.trim();
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getUpdateTime() {
return updateTime;
}
public void setUpdateTime(Date updateTime) {
this.updateTime = updateTime;
}
}
持久層接口:
package org.yliu.mui.mapper;
import org.yliu.mui.pojo.po.MallUserPo;
import org.yliu.mui.pojo.po.MallUserPoExample;
import java.util.List;
import org.apache.ibatis.annotations.Param;
public interface MallUserPoMapper {
int countByExample(MallUserPoExample example);
int deleteByExample(MallUserPoExample example);
int deleteByPrimaryKey(Integer id);
int insert(MallUserPo record);
int insertSelective(MallUserPo record);
List<MallUserPo> selectByExample(MallUserPoExample example);
MallUserPo selectByPrimaryKey(Integer id);
int updateByExampleSelective(@Param("record") MallUserPo record, @Param("example") MallUserPoExample example);
int updateByExample(@Param("record") MallUserPo record, @Param("example") MallUserPoExample example);
int updateByPrimaryKeySelective(MallUserPo record);
int updateByPrimaryKey(MallUserPo record);
}
映射文件:
<?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="org.yliu.mui.mapper.MallUserPoMapper" >
<resultMap id="BaseResultMap" type="org.yliu.mui.pojo.po.MallUserPo" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="guid" property="guid" jdbcType="VARCHAR" />
<result column="avatars" property="avatars" jdbcType="VARCHAR" />
<result column="open_id" property="openId" jdbcType="VARCHAR" />
<result column="user_name" property="userName" jdbcType="VARCHAR" />
<result column="sex" property="sex" jdbcType="INTEGER" />
<result column="phone" property="phone" jdbcType="VARCHAR" />
<result column="target_phone" property="targetPhone" jdbcType="VARCHAR" />
<result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
<result column="update_time" property="updateTime" jdbcType="TIMESTAMP" />
</resultMap>
<sql id="Example_Where_Clause" >
<where >
<foreach collection="oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Update_By_Example_Where_Clause" >
<where >
<foreach collection="example.oredCriteria" item="criteria" separator="or" >
<if test="criteria.valid" >
<trim prefix="(" suffix=")" prefixOverrides="and" >
<foreach collection="criteria.criteria" item="criterion" >
<choose >
<when test="criterion.noValue" >
and ${criterion.condition}
</when>
<when test="criterion.singleValue" >
and ${criterion.condition} #{criterion.value}
</when>
<when test="criterion.betweenValue" >
and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
</when>
<when test="criterion.listValue" >
and ${criterion.condition}
<foreach collection="criterion.value" item="listItem" open="(" close=")" separator="," >
#{listItem}
</foreach>
</when>
</choose>
</foreach>
</trim>
</if>
</foreach>
</where>
</sql>
<sql id="Base_Column_List" >
id, guid, avatars, open_id, user_name, sex, phone, target_phone, create_time, update_time
</sql>
<select id="selectByExample" resultMap="BaseResultMap" parameterType="org.yliu.mui.pojo.po.MallUserPoExample" >
select
<if test="distinct" >
distinct
</if>
<include refid="Base_Column_List" />
from mall_user
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
<if test="orderByClause != null" >
order by ${orderByClause}
</if>
</select>
<select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Integer" >
select
<include refid="Base_Column_List" />
from mall_user
where id = #{id,jdbcType=INTEGER}
</select>
<delete id="deleteByPrimaryKey" parameterType="java.lang.Integer" >
delete from mall_user
where id = #{id,jdbcType=INTEGER}
</delete>
<delete id="deleteByExample" parameterType="org.yliu.mui.pojo.po.MallUserPoExample" >
delete from mall_user
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</delete>
<insert id="insert" parameterType="org.yliu.mui.pojo.po.MallUserPo" >
insert into mall_user (id, guid, avatars,
open_id, user_name, sex,
phone, target_phone, create_time,
update_time)
values (#{id,jdbcType=INTEGER}, #{guid,jdbcType=VARCHAR}, #{avatars,jdbcType=VARCHAR},
#{openId,jdbcType=VARCHAR}, #{userName,jdbcType=VARCHAR}, #{sex,jdbcType=INTEGER},
#{phone,jdbcType=VARCHAR}, #{targetPhone,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP},
#{updateTime,jdbcType=TIMESTAMP})
</insert>
<insert id="insertSelective" parameterType="org.yliu.mui.pojo.po.MallUserPo" >
insert into mall_user
<trim prefix="(" suffix=")" suffixOverrides="," >
<if test="id != null" >
id,
</if>
<if test="guid != null" >
guid,
</if>
<if test="avatars != null" >
avatars,
</if>
<if test="openId != null" >
open_id,
</if>
<if test="userName != null" >
user_name,
</if>
<if test="sex != null" >
sex,
</if>
<if test="phone != null" >
phone,
</if>
<if test="targetPhone != null" >
target_phone,
</if>
<if test="createTime != null" >
create_time,
</if>
<if test="updateTime != null" >
update_time,
</if>
</trim>
<trim prefix="values (" suffix=")" suffixOverrides="," >
<if test="id != null" >
#{id,jdbcType=INTEGER},
</if>
<if test="guid != null" >
#{guid,jdbcType=VARCHAR},
</if>
<if test="avatars != null" >
#{avatars,jdbcType=VARCHAR},
</if>
<if test="openId != null" >
#{openId,jdbcType=VARCHAR},
</if>
<if test="userName != null" >
#{userName,jdbcType=VARCHAR},
</if>
<if test="sex != null" >
#{sex,jdbcType=INTEGER},
</if>
<if test="phone != null" >
#{phone,jdbcType=VARCHAR},
</if>
<if test="targetPhone != null" >
#{targetPhone,jdbcType=VARCHAR},
</if>
<if test="createTime != null" >
#{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
#{updateTime,jdbcType=TIMESTAMP},
</if>
</trim>
</insert>
<select id="countByExample" parameterType="org.yliu.mui.pojo.po.MallUserPoExample" resultType="java.lang.Integer" >
select count(*) from mall_user
<if test="_parameter != null" >
<include refid="Example_Where_Clause" />
</if>
</select>
<update id="updateByExampleSelective" parameterType="map" >
update mall_user
<set >
<if test="record.id != null" >
id = #{record.id,jdbcType=INTEGER},
</if>
<if test="record.guid != null" >
guid = #{record.guid,jdbcType=VARCHAR},
</if>
<if test="record.avatars != null" >
avatars = #{record.avatars,jdbcType=VARCHAR},
</if>
<if test="record.openId != null" >
open_id = #{record.openId,jdbcType=VARCHAR},
</if>
<if test="record.userName != null" >
user_name = #{record.userName,jdbcType=VARCHAR},
</if>
<if test="record.sex != null" >
sex = #{record.sex,jdbcType=INTEGER},
</if>
<if test="record.phone != null" >
phone = #{record.phone,jdbcType=VARCHAR},
</if>
<if test="record.targetPhone != null" >
target_phone = #{record.targetPhone,jdbcType=VARCHAR},
</if>
<if test="record.createTime != null" >
create_time = #{record.createTime,jdbcType=TIMESTAMP},
</if>
<if test="record.updateTime != null" >
update_time = #{record.updateTime,jdbcType=TIMESTAMP},
</if>
</set>
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByExample" parameterType="map" >
update mall_user
set id = #{record.id,jdbcType=INTEGER},
guid = #{record.guid,jdbcType=VARCHAR},
avatars = #{record.avatars,jdbcType=VARCHAR},
open_id = #{record.openId,jdbcType=VARCHAR},
user_name = #{record.userName,jdbcType=VARCHAR},
sex = #{record.sex,jdbcType=INTEGER},
phone = #{record.phone,jdbcType=VARCHAR},
target_phone = #{record.targetPhone,jdbcType=VARCHAR},
create_time = #{record.createTime,jdbcType=TIMESTAMP},
update_time = #{record.updateTime,jdbcType=TIMESTAMP}
<if test="_parameter != null" >
<include refid="Update_By_Example_Where_Clause" />
</if>
</update>
<update id="updateByPrimaryKeySelective" parameterType="org.yliu.mui.pojo.po.MallUserPo" >
update mall_user
<set >
<if test="guid != null" >
guid = #{guid,jdbcType=VARCHAR},
</if>
<if test="avatars != null" >
avatars = #{avatars,jdbcType=VARCHAR},
</if>
<if test="openId != null" >
open_id = #{openId,jdbcType=VARCHAR},
</if>
<if test="userName != null" >
user_name = #{userName,jdbcType=VARCHAR},
</if>
<if test="sex != null" >
sex = #{sex,jdbcType=INTEGER},
</if>
<if test="phone != null" >
phone = #{phone,jdbcType=VARCHAR},
</if>
<if test="targetPhone != null" >
target_phone = #{targetPhone,jdbcType=VARCHAR},
</if>
<if test="createTime != null" >
create_time = #{createTime,jdbcType=TIMESTAMP},
</if>
<if test="updateTime != null" >
update_time = #{updateTime,jdbcType=TIMESTAMP},
</if>
</set>
where id = #{id,jdbcType=INTEGER}
</update>
<update id="updateByPrimaryKey" parameterType="org.yliu.mui.pojo.po.MallUserPo" >
update mall_user
set guid = #{guid,jdbcType=VARCHAR},
avatars = #{avatars,jdbcType=VARCHAR},
open_id = #{openId,jdbcType=VARCHAR},
user_name = #{userName,jdbcType=VARCHAR},
sex = #{sex,jdbcType=INTEGER},
phone = #{phone,jdbcType=VARCHAR},
target_phone = #{targetPhone,jdbcType=VARCHAR},
create_time = #{createTime,jdbcType=TIMESTAMP},
update_time = #{updateTime,jdbcType=TIMESTAMP}
where id = #{id,jdbcType=INTEGER}
</update>
</mapper>
到了這一步和MyBatis整合完成了一半了,下面完成下一半。
6、首先需要配置Druid連接池
package org.yliu.mui.config;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.servlet.Filter;
import javax.servlet.Servlet;
/**
* Druid連接池配置
*/
@Configuration
public class DruidConfiguration {
private static final Logger LOGGER = LoggerFactory.getLogger(DruidConfiguration.class);
/**
* 訪問路徑及用戶名、密碼
*/
@Bean
public ServletRegistrationBean<Servlet> druidConfig() {
LOGGER.info("init Druid Servlet Configuration ");
final ServletRegistrationBean<Servlet> srb = new ServletRegistrationBean<Servlet>();
srb.setServlet(new StatViewServlet());
srb.addUrlMappings("/druid/*");
srb.addInitParameter("loginUsername", "admin");
srb.addInitParameter("loginPassword", "admin");
return srb;
}
/**
* 配置過濾器
*/
@Bean
public FilterRegistrationBean filterRegistrationBean() {
final FilterRegistrationBean<Filter> filterRegistrationBean = new FilterRegistrationBean<Filter>();
filterRegistrationBean.setFilter(new WebStatFilter());
filterRegistrationBean.addUrlPatterns("/*");
filterRegistrationBean.addInitParameter("exclusions", "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*");
return filterRegistrationBean;
}
}
7、配置完連接池,下面為持久層相關配置(分頁插件也在此類配置)
package org.yliu.mui.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.github.pagehelper.PageInterceptor;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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.yliu.mui.properties.DBProperties;
import javax.sql.DataSource;
import java.sql.SQLException;
import java.util.Properties;
/**
* 持久層相關配置
*/
@Configuration
public class SessionFactoryConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(SessionFactoryConfig.class);
private final DBProperties db;
@Autowired
public SessionFactoryConfig(DBProperties db) {
this.db = db;
}
/**
* 創建數據源
*/
@Bean
@Primary
public DataSource dataSource() {
DruidDataSource datasource = new DruidDataSource();
datasource.setUrl(db.getUrl());
datasource.setUsername(db.getUsername());
datasource.setPassword(db.getPassword());
datasource.setDriverClassName(db.getDriverClassName());
datasource.setInitialSize(db.getInitialSize());
datasource.setMinIdle(db.getMinIdle());
datasource.setMaxActive(db.getMaxActive());
datasource.setMaxWait(db.getMaxWait());
datasource.setTimeBetweenEvictionRunsMillis(db.getTimeBetweenEvictionRunsMillis());
datasource.setMinEvictableIdleTimeMillis(db.getMinEvictableIdleTimeMillis());
datasource.setValidationQuery(db.getValidationQuery());
datasource.setTestOnReturn(db.isTestOnReturn());
datasource.setPoolPreparedStatements(db.isPoolPreparedStatements());
datasource.setMaxPoolPreparedStatementPerConnectionSize(db.getMaxPoolPreparedStatementPerConnectionSize());
datasource.setUseGlobalDataSourceStat(db.isUseGlobalDataSourceStat());
try {
datasource.setFilters(db.getFilters());
} catch (SQLException e) {
LOGGER.info("druid configuration initialization filter: " + e);
}
datasource.setConnectionProperties(db.getConnectionProperties());
return datasource;
}
/**
* 配置分頁插件
*/
@Bean(name = "pageInterceptor")
public PageInterceptor pageHelperConfig() {
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
properties.setProperty("reasonable", "true");
properties.setProperty("supportMethodsArguments", "true");
properties.setProperty("returnPageInfo", "check");
properties.setProperty("params", "count=countSql");
pageInterceptor.setProperties(properties);
return pageInterceptor;
}
/**
* 配置mybatis
*/
@Bean(name = "sqlSessionFactory")
public SqlSessionFactory sqlSessionFactory(
@Qualifier("dataSource") final DataSource dataSource,
@Qualifier("pageInterceptor") final PageInterceptor pageInterceptor) throws Exception {
final SqlSessionFactoryBean sqlSessionFactory = new SqlSessionFactoryBean();
sqlSessionFactory.setDataSource(dataSource);
final PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
resolver.getResources("classpath*:mapper/**/*.xml");
sqlSessionFactory.setMapperLocations(resolver.getResources("classpath*:mapper/**/*.xml"));
// 具體參考自己設置,參考 xml 參數說明或源碼注釋
sqlSessionFactory.setPlugins(new Interceptor[]{pageInterceptor});
return sqlSessionFactory.getObject();
}
}
這里需要說明一下的是,DBProperties 類是對應 application.properties 配置文件中的數據庫相關配置屬性
DBProperties.java :
package org.yliu.mui.properties;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ConfigurationProperties(prefix = "spring.datasource")
public class DBProperties {
private String url;
private String username;
private String password;
private String driverClassName;
private int initialSize;
private int minIdle;
private int maxActive;
private int maxWait;
private int timeBetweenEvictionRunsMillis;
private int minEvictableIdleTimeMillis;
private String validationQuery;
private boolean testWhileIdle;
private boolean testOnBorrow;
private boolean testOnReturn;
private boolean poolPreparedStatements;
private int maxPoolPreparedStatementPerConnectionSize;
private String filters;
private String connectionProperties;
private boolean useGlobalDataSourceStat;
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
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;
}
public String getDriverClassName() {
return driverClassName;
}
public void setDriverClassName(String driverClassName) {
this.driverClassName = driverClassName;
}
public int getInitialSize() {
return initialSize;
}
public void setInitialSize(int initialSize) {
this.initialSize = initialSize;
}
public int getMinIdle() {
return minIdle;
}
public void setMinIdle(int minIdle) {
this.minIdle = minIdle;
}
public int getMaxActive() {
return maxActive;
}
public void setMaxActive(int maxActive) {
this.maxActive = maxActive;
}
public int getMaxWait() {
return maxWait;
}
public void setMaxWait(int maxWait) {
this.maxWait = maxWait;
}
public int getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(int timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public int getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(int minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public boolean isTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public boolean isTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public boolean isTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public boolean isPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public int getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(int maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
public String getConnectionProperties() {
return connectionProperties;
}
public void setConnectionProperties(String connectionProperties) {
this.connectionProperties = connectionProperties;
}
public boolean isUseGlobalDataSourceStat() {
return useGlobalDataSourceStat;
}
public void setUseGlobalDataSourceStat(boolean useGlobalDataSourceStat) {
this.useGlobalDataSourceStat = useGlobalDataSourceStat;
}
}
8、配置完這些,小伙伴不要心急,還有一項重要的配置,那就是掃描 mapper 接口!!!
package org.yliu.mui.config;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/**
* 掃描Mybatis接口
*/
@Configuration
// 在持久層相關配置成功注入后加載
@AutoConfigureAfter(SessionFactoryConfig.class)
public class MyBatisMapperScannerConfig {
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer();
mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactory");
// 需要掃描的包路徑
mapperScannerConfigurer.setBasePackage("org.yliu.mui.mapper");
return mapperScannerConfigurer;
}
}
如果不寫掃描配置類,也可以在Spring Boot 入口類main方法上加入 @MapperScan("XX.XXX.mapper")注解進行掃描,個人習慣。
9、redis:(redis這里我沒有選用 Spring 提供的 RedisTemplate,還是習慣 jedis )
package org.yliu.mui.config;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.data.redis.RedisProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* Redis配置
*/
@Configuration
// RedisProperties 為Spring內部默認提供的關於redis配置的屬性綁定類
@AutoConfigureAfter(RedisProperties.class)
public class RedisConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisConfig.class);
private final RedisProperties redisProperties;
@Autowired
public RedisConfig(RedisProperties redisProperties) {
this.redisProperties = redisProperties;
}
@Bean
public JedisPool redisPoolFactory(){
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
int port = redisProperties.getPort();
String host = redisProperties.getHost();
int timeout = 2000;
String password = redisProperties.getPassword();
JedisPool jedisPool = new JedisPool(jedisPoolConfig,host,port,timeout,password);
LOGGER.info("JedisPool注入成功!");
LOGGER.info("redis地址:" + host + ":" + port);
return jedisPool;
}
}
我封裝了一個 JedisClient 的接口,方面操作和后期增加新命令。
package org.yliu.mui.redis;
import java.util.List;
public interface JedisClient {
String set(String key, String value);
String get(String key);
Boolean exists(String key);
Long expire(String key, int seconds);
Long ttl(String key);
Long incr(String key);
Long hset(String key, String field, String value);
String hget(String key, String field);
Long hdel(String key, String... field);
Boolean hexists(String key, String field);
List<String> hvals(String key);
Long del(String key);
}
JedisClient 實現類
package org.yliu.mui.redis.impl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.yliu.mui.redis.JedisClient;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
/**
* Redis實現
*/
@Configuration
public class JedisClientPool implements JedisClient {
private final JedisPool jedisPool;
@Autowired
public JedisClientPool(JedisPool jedisPool) {
this.jedisPool = jedisPool;
}
@Override
public String set(String key, String value) {
Jedis jedis = jedisPool.getResource();
String result = jedis.set(key, value);
jedis.close();
return result;
}
@Override
public String get(String key) {
Jedis jedis = jedisPool.getResource();
String result = jedis.get(key);
jedis.close();
return result;
}
@Override
public Boolean exists(String key) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.exists(key);
jedis.close();
return result;
}
@Override
public Long expire(String key, int seconds) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.expire(key, seconds);
jedis.close();
return result;
}
@Override
public Long ttl(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.ttl(key);
jedis.close();
return result;
}
@Override
public Long incr(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.incr(key);
jedis.close();
return result;
}
@Override
public Long hset(String key, String field, String value) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hset(key, field, value);
jedis.close();
return result;
}
@Override
public String hget(String key, String field) {
Jedis jedis = jedisPool.getResource();
String result = jedis.hget(key, field);
jedis.close();
return result;
}
@Override
public Long hdel(String key, String... field) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.hdel(key, field);
jedis.close();
return result;
}
@Override
public Boolean hexists(String key, String field) {
Jedis jedis = jedisPool.getResource();
Boolean result = jedis.hexists(key, field);
jedis.close();
return result;
}
@Override
public List<String> hvals(String key) {
Jedis jedis = jedisPool.getResource();
List<String> result = jedis.hvals(key);
jedis.close();
return result;
}
@Override
public Long del(String key) {
Jedis jedis = jedisPool.getResource();
Long result = jedis.del(key);
jedis.close();
return result;
}
}
至此,整合完畢。。。
結果如何?
我分別貼上 Controller 、UserService 、UserServiceImpl 這里不一一細說了。
Controller :
package org.yliu.mui.controller;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.yliu.mui.pojo.po.MallUserPo;
import org.yliu.mui.pojo.response.ResponseData;
import org.yliu.mui.service.MallUserService;
@RestController
public class DemoController {
private final MallUserService mallUserService;
@Autowired
public DemoController(MallUserService userService) {
this.mallUserService = userService;
}
@RequestMapping("/get/user/all")
ResponseData<PageInfo<MallUserPo>> getUserAll() {
return ResponseData.success("success", mallUserService.findAll());
}
}
UserService :
package org.yliu.mui.service;
import com.github.pagehelper.PageInfo;
import org.yliu.mui.pojo.po.MallUserPo;
public interface MallUserService {
// 使用分頁插件提供的PageInfo包裝一下結果集
PageInfo<MallUserPo> findAll();
}
UserServiceImpl :
package org.yliu.mui.service.impl;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.yliu.mui.mapper.MallUserPoMapper;
import org.yliu.mui.pojo.po.MallUserPo;
import org.yliu.mui.pojo.po.MallUserPoExample;
import org.yliu.mui.redis.JedisClient;
import org.yliu.mui.service.MallUserService;
import java.util.Date;
import java.util.List;
import java.util.UUID;
@Service
public class MallUserServiceImpl implements MallUserService {
private final MallUserPoMapper userMapper;
// 注入Jedis接口用來操作緩存
private final JedisClient jedisClient;
@Autowired
public MallUserServiceImpl(MallUserPoMapper userMapper, JedisClient jedisClient) {
this.userMapper = userMapper;
this.jedisClient = jedisClient;
}
@Override
public PageInfo<MallUserPo> findAll() {
PageHelper.startPage(0, 20);
MallUserPoExample userExample = new MallUserPoExample();
List<MallUserPo> mallUserPos = userMapper.selectByExample(userExample);
// 測試Jedis是否正常
jedisClient.set("user_info", JSON.toJSONString(mallUserPos));
return new PageInfo<>(mallUserPos);
}
}
ok,到了這里可以把項目啟動了,run......
項目運行成功后 輸入 http://127.0.0.1:2088/druid
如果阿里的Druid連接池監控登錄頁面會呈現在你電腦屏幕上,恭喜~ 輸入用戶名、密碼,去登錄嘗鮮吧。
下一步就是測試 持久層 和 redis 了
訪問 http://127.0.0.1:2088/get/user/all
如果響應數據 帶有 分頁信息的json數據的話,恭喜你~整合已經完成了。
再看redis:
OK,一切正常。
注意:如果中間出現什么問題的話,不要着急,有點耐心,仔細排除一下錯誤。
可以在下方留言,積極討論
可以關注微信個人公眾號對我私信(下方二維碼 😃 ):
---恢復內容結束---