这段时间接触很多知识,也逐渐深入到项目整个流程开发,对Linux也有逐步地认识。虽然有去探索,但感觉能力还不足以写出来跟大家分享。撰写本文是了解到有些读者反馈,对于MP(MybatisPlus缩写)不太了解以及如何去使用,但更多还是笔者用完觉得非常强大,有必要share。文章还会主讲Redis配置使用,篇幅有点长,因此分为两节讲解。
新建Maven项目,导入相关依赖包,pom.xml(根据个人需求可以去掉不必要的包)
<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.0modelVersion>
<groupId>com.jekin.examplegroupId>
<artifactId>redis-exampleartifactId>
<version>0.0.1-SNAPSHOTversion>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<spring.boot.version>1.5.3.RELEASEspring.boot.version>
<java.version>1.8java.version>
<redis.version>1.4.7.RELEASEredis.version>
<druid.version>1.0.0druid.version>
<mybatisplus-spring-boot-starter.version>1.0.1mybatisplus-spring-boot-starter.version>
<fastjson.version>1.2.31fastjson.version>
<mysql.version>5.1.42mysql.version>
<commons.lang3.version>3.5commons.lang3.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-dependenciesartifactId>
<version>${spring.boot.version}version>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-redisartifactId>
<version>${redis.version}version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>${fastjson.version}version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>${druid.version}version>
dependency>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatisplus-spring-boot-starterartifactId>
<version>${mybatisplus-spring-boot-starter.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>${commons.lang3.version}version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.1version>
<configuration>
<executable>trueexecutable>
<source>1.8source>
<target>1.8target>
configuration>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<configuration>
<finalName>redisfinalName>
configuration>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-war-pluginartifactId>
<version>2.6version>
<configuration>
<warSourceExcludes>src/main/resources/**warSourceExcludes>
<failOnMissingWebXml>falsefailOnMissingWebXml>
configuration>
plugin>
plugins>
<resources>
<resource>
<directory>src/main/resourcesdirectory>
resource>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.xmlinclude>
includes>
resource>
resources>
build>
project>
SpringBoot配置文件,application.yaml
server:
port: 8080
spring:
main:
banner-mode: "off"
application:
name: redis
profiles:
active: local
thymeleaf:
cache: false #前后端分离,关闭前端模板引擎,官方建议
http:
converters:
preferred-json-mapper: fastjson
redis: #redis配置,不使用可删除
host: 192.168.1.70
password: rs0720$
port: 6379
pool:
max-idle: 10
min-idle: 1
max-active: 1000
max-wait: -1
datasource:
url: jdbc:mysql://192.168.1.70:3306/sharing?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false
username: *** #本地数据库用户名
password: *** #本地数据库密码
filters: mergeStat
logging:
config: classpath:logback-${spring.profiles.active}.xml
################### mybatis-plus配置 ###################
mybatis-plus:
mapper-locations: classpath*:com/jekin/example/**/mapping/*.xml
typeAliasesPackage: com.jekin.example.entity
global-config:
id-type: 3 #1:数据库ID自增 2:用户输入id 3:全局唯一id(IdWorker) 4:全局唯一ID(uuid)
db-column-underline: false
refresh-mapper: true
is-capital-mode: false
configuration:
map-underscore-to-camel-case: true
cache-enabled: true #配置的缓存的全局开关
lazyLoadingEnabled: true #延时加载的开关
jdbcTypeForNull: NULL
multipleResultSetsEnabled: true #开启的话,延时加载一个属性时会加载该对象全部属性,否则按需加载属性
#log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #打印sql语句,调试用
数据源配置文件,DruidProperties.java
package com.jekin.example.properties;
import java.sql.SQLException;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
import com.alibaba.druid.pool.DruidDataSource;
/**
* 数据库数据源配置
* 说明:这个类中包含了许多默认配置,若这些配置符合您的情况,您可以不用管,若不符合,建议不要修改本类,建议直接在"application.yml"中配置即可
*
* @date 2017-05-21 11:18
*/
@Component
@ConfigurationProperties(prefix = "spring.datasource")
public class DruidProperties {
private String url = "jdbc:mysql://127.0.0.1:3306/operation?autoReconnect=true&useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull";
private String username = "root";
private String password = "admin";
private String driverClassName = "com.mysql.jdbc.Driver";
private Integer initialSize = 2;
private Integer minIdle = 1;
private Integer maxActive = 20;
private Integer maxWait = 60000;
private Integer timeBetweenEvictionRunsMillis = 60000;
private Integer minEvictableIdleTimeMillis = 300000;
private String validationQuery = "SELECT 'x' from dual";
private Boolean testWhileIdle = true;
private Boolean testOnBorrow = false;
private Boolean testOnReturn = false;
private Boolean poolPreparedStatements = true;
private Integer maxPoolPreparedStatementPerConnectionSize = 20;
private String filters = "stat";
public void coinfig(DruidDataSource dataSource) {
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
dataSource.setDriverClassName(driverClassName);
dataSource.setInitialSize(initialSize); //定义初始连接数
dataSource.setMinIdle(minIdle); //最小空闲
dataSource.setMaxActive(maxActive); //定义最大连接数
dataSource.setMaxWait(maxWait); //最长等待时间
// 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
// 配置一个连接在池中最小生存的时间,单位是毫秒
dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
dataSource.setValidationQuery(validationQuery);
dataSource.setTestWhileIdle(testWhileIdle);
dataSource.setTestOnBorrow(testOnBorrow);
dataSource.setTestOnReturn(testOnReturn);
// 打开PSCache,并且指定每个连接上PSCache的大小
dataSource.setPoolPreparedStatements(poolPreparedStatements);
dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
try {
dataSource.setFilters(filters);
} catch (SQLException e) {
e.printStackTrace();
}
}
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 Integer getInitialSize() {
return initialSize;
}
public void setInitialSize(Integer initialSize) {
this.initialSize = initialSize;
}
public Integer getMinIdle() {
return minIdle;
}
public void setMinIdle(Integer minIdle) {
this.minIdle = minIdle;
}
public Integer getMaxActive() {
return maxActive;
}
public void setMaxActive(Integer maxActive) {
this.maxActive = maxActive;
}
public Integer getMaxWait() {
return maxWait;
}
public void setMaxWait(Integer maxWait) {
this.maxWait = maxWait;
}
public Integer getTimeBetweenEvictionRunsMillis() {
return timeBetweenEvictionRunsMillis;
}
public void setTimeBetweenEvictionRunsMillis(Integer timeBetweenEvictionRunsMillis) {
this.timeBetweenEvictionRunsMillis = timeBetweenEvictionRunsMillis;
}
public Integer getMinEvictableIdleTimeMillis() {
return minEvictableIdleTimeMillis;
}
public void setMinEvictableIdleTimeMillis(Integer minEvictableIdleTimeMillis) {
this.minEvictableIdleTimeMillis = minEvictableIdleTimeMillis;
}
public String getValidationQuery() {
return validationQuery;
}
public void setValidationQuery(String validationQuery) {
this.validationQuery = validationQuery;
}
public Boolean getTestWhileIdle() {
return testWhileIdle;
}
public void setTestWhileIdle(Boolean testWhileIdle) {
this.testWhileIdle = testWhileIdle;
}
public Boolean getTestOnBorrow() {
return testOnBorrow;
}
public void setTestOnBorrow(Boolean testOnBorrow) {
this.testOnBorrow = testOnBorrow;
}
public Boolean getTestOnReturn() {
return testOnReturn;
}
public void setTestOnReturn(Boolean testOnReturn) {
this.testOnReturn = testOnReturn;
}
public Boolean getPoolPreparedStatements() {
return poolPreparedStatements;
}
public void setPoolPreparedStatements(Boolean poolPreparedStatements) {
this.poolPreparedStatements = poolPreparedStatements;
}
public Integer getMaxPoolPreparedStatementPerConnectionSize() {
return maxPoolPreparedStatementPerConnectionSize;
}
public void setMaxPoolPreparedStatementPerConnectionSize(Integer maxPoolPreparedStatementPerConnectionSize) {
this.maxPoolPreparedStatementPerConnectionSize = maxPoolPreparedStatementPerConnectionSize;
}
public String getFilters() {
return filters;
}
public void setFilters(String filters) {
this.filters = filters;
}
}
MP注解配置,MybatisPlusConfig.java
package com.jekin.example.config;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.alibaba.druid.pool.DruidDataSource;
import com.baomidou.mybatisplus.enums.DBType;
import com.baomidou.mybatisplus.plugins.PaginationInterceptor;
import com.jekin.example.properties.DruidProperties;
/**
* MybatisPlus配置
*
* @author Jekin
* @date 2017年10月31日上午11:36:30
*/
@Configuration
@MapperScan(basePackages = {"com.jekin.example.mapper"})
public class MybatisPlusConfig {
@Autowired
DruidProperties druidProperties;
/**
* mybatis-plus分页插件
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setDialectType(DBType.MYSQL.getDb());
return paginationInterceptor;
}
/**
* druid数据库连接池
*/
@Bean(initMethod = "init")
public DruidDataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
druidProperties.coinfig(dataSource);
return dataSource;
}
}
启动类,RedisExampleApplication.java
package com.jekin.example;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
/**
* 启动类
*
* @author fengjk
* @date 2017年6月27日
* @since 1.0
*/
@SpringBootApplication
public class RedisExampleApplication extends WebMvcConfigurerAdapter{
protected final static Logger logger = LoggerFactory.getLogger(RedisExampleApplication.class);
public static void main(String[] args) {
SpringApplication.run(RedisExampleApplication.class, args);
logger.info("RedisExampleApplication is sussess!");
}
}
至此,SpringBoot集成MP框架就算搭建完成。下面,看下MP封装的常见mapper方法的使用。
创建实体类(略),映射文件(略),UserMapper.java
package com.jekin.example.mapper;
import java.util.List;
import org.apache.ibatis.annotations.Param;
import com.baomidou.mybatisplus.mapper.BaseMapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.jekin.example.entity.User;
/**
* 用户表 数据层
*
*/
public interface UserMapper extends BaseMapper {
List getUserPage(@Param("page") Page page,
@Param("orderByField") String orderByField, @Param("isAsc") boolean isAsc);
}
getUserPage是分页方法,下节会提到。这里主要看下BaseMapper(MP对外mapper封装类)
/**
* Copyright (c) 2011-2020, hubin (jobob@qq.com).
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/
package com.baomidou.mybatisplus.mapper;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.RowBounds;
/**
*
* Mapper 继承该接口后,无需编写 mapper.xml 文件,即可获得CRUD功能
*
*
* 这个 Mapper 支持 id 泛型
*
*
* @author hubin
* @Date 2016-01-23
*/
public interface BaseMapper {
/**
*
* 插入一条记录
*
*
* @param entity
* 实体对象
* @return int
*/
Integer insert(T entity);
/**
*
* 插入一条记录
*
*
* @param entity
* 实体对象
* @return int
*/
Integer insertAllColumn(T entity);
/**
*
* 根据 ID 删除
*
*
* @param id
* 主键ID
* @return int
*/
Integer deleteById(Serializable id);
/**
*
* 根据 columnMap 条件,删除记录
*
*
* @param columnMap
* 表字段 map 对象
* @return int
*/
Integer deleteByMap(@Param("cm") Map columnMap);
/**
*
* 根据 entity 条件,删除记录
*
*
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return int
*/
Integer delete(@Param("ew") Wrapper wrapper);
/**
*
* 删除(根据ID 批量删除)
*
*
* @param idList
* 主键ID列表
* @return int
*/
Integer deleteBatchIds(List extends Serializable> idList);
/**
*
* 根据 ID 修改
*
*
* @param entity
* 实体对象
* @return int
*/
Integer updateById(T entity);
/**
*
* 根据 ID 修改
*
*
* @param entity
* 实体对象
* @return int
*/
Integer updateAllColumnById(T entity);
/**
*
* 根据 whereEntity 条件,更新记录
*
*
* @param entity
* 实体对象
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return
*/
Integer update(@Param("et") T entity, @Param("ew") Wrapper wrapper);
/**
*
* 根据 ID 查询
*
*
* @param id
* 主键ID
* @return T
*/
T selectById(Serializable id);
/**
*
* 查询(根据ID 批量查询)
*
*
* @param idList
* 主键ID列表
* @return List
*/
List selectBatchIds(List extends Serializable> idList);
/**
*
* 查询(根据 columnMap 条件)
*
*
* @param columnMap
* 表字段 map 对象
* @return List
*/
List selectByMap(@Param("cm") Map columnMap);
/**
*
* 根据 entity 条件,查询一条记录
*
*
* @param entity
* 实体对象
* @return T
*/
T selectOne(@Param("ew") T entity);
/**
*
* 根据 Wrapper 条件,查询总记录数
*
*
* @param wrapper
* 实体对象
* @return int
*/
Integer selectCount(@Param("ew") Wrapper wrapper);
/**
*
* 根据 entity 条件,查询全部记录
*
*
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List
*/
List selectList(@Param("ew") Wrapper wrapper);
/**
*
* 根据 Wrapper 条件,查询全部记录
*
*
* @param wrapper
* 实体对象封装操作类(可以为 null)
* @return List
*/
List
就如作者说的,只要继承该接口,就可以使用里面的CURD,用起来十分方便快捷。
单元测试(使用例子),RedisTest.java
package com.jekin.example.test;
import java.util.List;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.boot.test.context.SpringBootTest.WebEnvironment;
import org.springframework.test.context.ActiveProfiles;
import org.springframework.test.context.junit4.SpringRunner;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.jekin.example.RedisExampleApplication;
import com.jekin.example.entity.User;
import com.jekin.example.mapper.UserMapper;
import com.jekin.example.service.RedisService;
@RunWith(SpringRunner.class)
@SpringBootTest(classes = RedisExampleApplication.class,webEnvironment=WebEnvironment.RANDOM_PORT)
@ActiveProfiles("local")
public class RedisTest {
private static final Logger LOGGER = LoggerFactory.getLogger(RedisTest.class);
@Autowired
RedisService redisService;
@Autowired
UserMapper userMapper;
/*@Test
public void testRedis(){
redisService.set("haha", "1");
String str = redisService.get("haha");
LOGGER.info(str);
}*/
@Test
public void testMapper(){
// 新增
User use = new User();
userMapper.insert(use);
// 根据主键删除
userMapper.deleteById(898474800007831552L);
// 条件删除
userMapper.delete(new EntityWrapper().eq("name", "Jekin"));
// 根据ID修改
userMapper.updateById(use);
// 条件修改
userMapper.update(use, new EntityWrapper().eq("name", "Jekin"));
// 主键查询
User user = userMapper.selectById(898474800007831552L);
LOGGER.info("get user object:{}", JSON.toJSONString(user));
// 条件查询
List users = userMapper.selectList(new EntityWrapper().eq("name", "Jekin"));
LOGGER.info("get users list:{}", JSON.toJSONString(users));
// 多条件查询
List users1 = userMapper.selectList(new EntityWrapper().notIn("type", 1).eq("name", "Jekin"));
LOGGER.info("get users1 list:{}", JSON.toJSONString(users1));
}
}
当存在多个环境时,才需要使用@ActiveProfiles来指定加载文件,此处可省略。以上基本覆盖了常用的方法,还有个别笔者没有一一列举,但都是大同小异,相信大家都可以举一反三。
日志文件,logback-local.xml
<configuration debug="true">
<contextName>logbackcontextName>
<property name="log.path" value="logs/redis.log" />
<appender name="console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>debuglevel>
filter>
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n
pattern>
encoder>
appender>
<appender name="file" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${log.path}file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${log.path}.%d{yyyy-MM-dd}.zipfileNamePattern>
rollingPolicy>
<encoder>
<pattern>%date %level [%thread] %logger{36} [%file : %line] %msg%n
pattern>
encoder>
appender>
<root level="debug">
<appender-ref ref="console" />
root>
<logger name="org.springframework" level="error" />
<logger name="org.apache.http" level="error" />
<logger name="org.mybatis" level="debug" />
<logger name="java.sql" level="error" />
configuration>
本章主要讲的是MP的集成,框架搭建,至此,如果只想学习SpringBoot项目搭建的话,可以到此止步,不必看下节内容,去掉Redis依赖包就完事了。下节讲解MP的分页以及Redis的配置使用。
如有问题或笔误,可以评论留言,亦可加Q群讨论学习:583138104。笔者每篇文章源码都会上传上去。
源码下载