springboot2.0+mybatis多数据源集成
最近在学springboot,把学的记录下来。主要有springboot2.0+mybatis多数据源集成,logback日志集成,springboot单元测试。
一、代码结构如下
二、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.0</modelVersion> <groupId>spring-boot-2</groupId>
<artifactId>spring-boot-2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging> <name>spring-boot-2</name>
<url>http://maven.apache.org</url> <properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties> <dependencies>
<!-- spring boot依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.0.3.RELEASE</version>
</dependency> <!-- spring boot测试 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<version>2.0.3.RELEASE</version>
<scope>test</scope>
</dependency> <!-- spring boot热启动 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
<optional>true</optional>
<version>2.0.3.RELEASE</version>
</dependency> <!-- mysql -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency> <!-- mybatis -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>1.3.2</version>
</dependency> <!-- alibaba的druid数据库连接池 -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.9</version>
</dependency>
</dependencies> <build>
<plugins>
<!-- 规避检查src/main/webapp/WEB-INF下没有web.xml文件 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>2.3</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
<!-- maven热启动 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
</configuration>
</plugin>
<!-- 跳过单元测试 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<configuration>
<skip>true</skip>
</configuration>
</plugin> <!-- 指定jdk版本 -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
</project>
三、编写application.yml文件,springboot支持properties和yml两种格式的配置文件,我使用的是yml文件。使用yml文件需要注意的是只支持空格,不支持tab等,可以下个eclipse的yml插件。
配置文件如下
# 数据源
spring:
datasource:
# master数据源配置
master:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
username: root
password: root
# cluster数据源配置
cluster:
driverClassName: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test2?useUnicode=true&characterEncoding=utf-8
username: root
password: root
四、编写主从库的配置代码,代码差不多一样,只不过主库配置类的方法上需要加@Primary注解,用来告诉spring默认使用这个配置,主库配置类代码如下
package com.spring.boot.config; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
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.jdbc.datasource.DataSourceTransactionManager; /**
* mysql从库配置类
* @日期: 2018年7月5日 下午10:05:25
* @作者: Chendb
*/
@Configuration
@MapperScan(basePackages = "com.spring.boot.master.mapper",sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class MasterDataSourceConfig { /**
* 创建数据源
*@return DataSource
*/
@Bean(name = "masterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.master")
@Primary
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
} /**
* 创建工厂
*@param dataSource
*@throws Exception
*@return SqlSessionFactory
*/
@Bean(name = "masterSqlSessionFactory")
@Primary
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/master/*.xml"));
return bean.getObject();
} /**
* 创建事务
*@param dataSource
*@return DataSourceTransactionManager
*/
@Bean(name = "masterTransactionManager")
@Primary
public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} /**
* 创建模板
*@param sqlSessionFactory
*@return SqlSessionTemplate
*/
@Bean(name = "masterSqlSessionTemplate")
@Primary
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
} }
从库配置类代码如下
package com.spring.boot.config; import javax.sql.DataSource; import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager; /**
* mysql主库配置类
* @日期: 2018年7月5日 下午10:05:25
* @作者: Chendb
*/
@Configuration
@MapperScan(basePackages = "com.spring.boot.mapper.cluster",sqlSessionTemplateRef = "clusterSqlSessionTemplate")
public class ClusterDataSourceConfig { /**
* 创建数据源
*@return DataSource
*/
@Bean(name = "clusterDataSource")
@ConfigurationProperties(prefix = "spring.datasource.cluster")
public DataSource masterDataSource() {
return DataSourceBuilder.create().build();
} /**
* 创建工厂
*@param dataSource
*@throws Exception
*@return SqlSessionFactory
*/
@Bean(name = "clusterSqlSessionFactory")
public SqlSessionFactory masterSqlSessionFactory(@Qualifier("clusterDataSource") DataSource dataSource) throws Exception {
SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
bean.setDataSource(dataSource);
bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper/cluster/*.xml"));
return bean.getObject();
} /**
* 创建事务
*@param dataSource
*@return DataSourceTransactionManager
*/
@Bean(name = "clusterTransactionManager")
public DataSourceTransactionManager masterDataSourceTransactionManager(@Qualifier("clusterDataSource") DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
} /**
* 创建模板
*@param sqlSessionFactory
*@return SqlSessionTemplate
*/
@Bean(name = "clusterSqlSessionTemplate")
public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("clusterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
return new SqlSessionTemplate(sqlSessionFactory);
} }
五、配置mybatis的mapper文件,主库的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.spring.boot.mapper.cluster.ClusterUserMapper" >
<!-- 结果映射 -->
<resultMap id="BaseMap" type="com.spring.boot.model.UserModel">
<id column="userId" property="userId" jdbcType="INTEGER" />
<result column="userName" property="userName" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="phone" property="phone" jdbcType="VARCHAR" />
</resultMap> <!-- 表所有字段 -->
<sql id="allColumns">
userId, userName, password, phone
</sql> <!-- 查询所有数据 -->
<select id="getAll" resultMap="BaseMap">
SELECT
<include refid="allColumns" />
FROM T_USER
</select> <!-- 根据主键查询数据 -->
<select id="get" resultMap="BaseMap" parameterType="java.util.Map">
SELECT
<include refid="allColumns" />
FROM
t_user u
WHERE
1 = 1
AND userId = #{userId}
</select> <!-- 插入数据 -->
<insert id="insert" parameterType="java.util.Map">
<!--获取最新更新的主键-->
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="userId">
SELECT LAST_INSERT_ID() AS userId
</selectKey>
INSERT INTO T_USER (<include refid="allColumns" />)
VALUES (
#{userId},
#{userName},
#{password},
#{phone}
)
</insert> <!-- 修改数据 -->
<update id="update" parameterType="java.util.Map">
UPDATE T_USER SET
userName = #{userName},
PASSWORD = #{password},
PHONE = #{phone}
WHERE userId = #{userId}
</update> <!-- 根据主键删除数据 -->
<delete id="delete" parameterType="Integer">
DELETE FROM T_USER WHERE userId = #{userId}
</delete> </mapper>
从库的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.spring.boot.mapper.master.MasterUserMapper" >
<!-- 结果映射 -->
<resultMap id="BaseMap" type="com.spring.boot.model.UserModel">
<id column="userId" property="userId" jdbcType="INTEGER" />
<result column="userName" property="userName" jdbcType="VARCHAR" />
<result column="password" property="password" jdbcType="VARCHAR" />
<result column="phone" property="phone" jdbcType="VARCHAR" />
</resultMap> <!-- 表所有字段 -->
<sql id="allColumns">
userId, userName, password, phone
</sql> <!-- 查询所有数据 -->
<select id="getAll" resultMap="BaseMap">
SELECT
<include refid="allColumns" />
FROM T_USER
</select> <!-- 根据主键查询数据 -->
<select id="get" resultMap="BaseMap" parameterType="java.util.Map">
SELECT
<include refid="allColumns" />
FROM
t_user u
WHERE
1 = 1
AND userid = #{userId}
</select> <!-- 插入数据,返回主键 -->
<insert id="insert" parameterType="java.util.Map" useGeneratedKeys="true" keyProperty="userId" keyColumn="userId">
INSERT INTO T_USER (userName,password,phone)
VALUES (
#{userName},
#{password},
#{phone}
)
</insert> <!-- 修改数据 -->
<update id="update" parameterType="java.util.Map">
UPDATE T_USER SET
userName = #{userName},
PASSWORD = #{password},
PHONE = #{phone}
WHERE userId = #{userId}
</update> <!-- 根据主键删除数据 -->
<delete id="delete" parameterType="Integer">
DELETE FROM T_USER WHERE userId = #{userId}
</delete> </mapper>
六、编写mybatis的dao层,这里不需要编写具体的dao层实现,只写接口类,只要保证mapper配置文件的命名空间和接口类的全限定名一致并且接口方法名和mapper文件的sql标识符对应即可
主库的接口类如下
package com.spring.boot.mapper.master; import java.util.List; import com.spring.boot.model.UserModel; public interface MasterUserMapper { /**
* 获取全部用户数据
*@return List<UserModel> 用户列表
*/
List<UserModel> getAll(); /**
* 获取用户数据
*@param userId 用户id
*@return UserModel 用户数据
*/
UserModel get(Integer userId); /**
* 保存用户
*@param userModel 用户数据
*@return Integer 是否成功,1成功,0失败
*/
Integer insert(UserModel userModel); /**
* 更新用户
*@param userModel 用户数据
*@return Integer 是否成功,1成功,0失败
*/
Integer update(UserModel userModel); /**
* 删除用户
*@param userId 用户id
*@return Integer 是否成功,1成功,0失败
*/
Integer delete(Integer userId);
}
从库的接口类如下
package com.spring.boot.mapper.cluster; import java.util.List; import com.spring.boot.model.UserModel; public interface ClusterUserMapper {
/**
* 获取全部用户数据
*@return List<UserModel> 用户列表
*/
List<UserModel> getAll(); /**
* 获取用户数据
*@param userId 用户id
*@return UserModel 用户数据
*/
UserModel get(Integer userId); /**
* 保存用户
*@param userModel 用户数据
*@return Integer 是否成功,1成功,0失败
*/
Integer insert(UserModel userModel); /**
* 更新用户
*@param userModel 用户数据
*@return Integer 是否成功,1成功,0失败
*/
Integer update(UserModel userModel); /**
* 删除用户
*@param userId 用户id
*@return Integer 是否成功,1成功,0失败
*/
Integer delete(Integer userId);
}
七、springboot启动类
package com.spring.boot; import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; /**
* springboot启动类
* @日期: 2018年7月5日 下午10:03:36
* @作者: Chendb
*/
@SpringBootApplication
@MapperScan("com.spring.boot.mapper")
public class Application { public static void main(String[] args) {
SpringApplication.run(Application.class, args);
} }
八、实体类和数据库表
package com.spring.boot.model; import java.io.Serializable; public class UserModel implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L; /**
* 用户id
*/
private Integer userId; /**
* 用户名称
*/
private String userName; /**
* 用户密码
*/
private String password; /**
* 电话
*/
private String phone; /**
* 获取用户id
*@return Integer 用户id
*/
public Integer getUserId() {
return userId;
} /**
* 设置用户id
*@param userId 用户id
*@return void
*/
public void setUserId(Integer userId) {
this.userId = userId;
} /**
* 获取用户名称
*@return String 用户名称
*/
public String getUserName() {
return userName;
} /**
* 设置用户名称
*@param userName 用户名称
*@return void
*/
public void setUserName(String userName) {
this.userName = userName;
} /**
* 获取用户密码
*@return String 用户密码
*/
public String getPassword() {
return password;
} /**
* 设置用户密码
*@param password 用户密码
*@return void
*/
public void setPassword(String password) {
this.password = password;
} /**
* 获取电话
*@return String 电话
*/
public String getPhone() {
return phone;
} /**
* 设置电话
*@param phone 电话
*@return void
*/
public void setPhone(String phone) {
this.phone = phone;
}
}
/*
Navicat MySQL Data Transfer Source Server : local
Source Server Version : 50713
Source Host : localhost:3306
Source Database : test2 Target Server Type : MYSQL
Target Server Version : 50713
File Encoding : 65001 Date: 2018-07-06 23:14:03
*/ SET FOREIGN_KEY_CHECKS=0; -- ----------------------------
-- Table structure for t_user
-- ----------------------------
DROP TABLE IF EXISTS `t_user`;
CREATE TABLE `t_user` (
`userId` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id',
`userName` varchar(255) NOT NULL COMMENT '用户名称',
`password` varchar(255) NOT NULL COMMENT '用户密码',
`phone` varchar(255) NOT NULL COMMENT '电话',
PRIMARY KEY (`userId`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC;
九、控制层以及单元测试类
package com.spring.boot.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController; import com.spring.boot.mapper.cluster.ClusterUserMapper;
import com.spring.boot.mapper.master.MasterUserMapper;
import com.spring.boot.model.UserModel; /**
* 用户控制层
* @日期: 2018年7月5日 下午11:18:04
* @作者: Chendb
*/
@RestController
public class UserController { @Autowired
private MasterUserMapper masterUserMapper; @Autowired
private ClusterUserMapper clusterUserMapper; /************************主库控制层接口-start******************************/
@RequestMapping("user/getAllMaster")
public List<UserModel> getAllMaster() {
return masterUserMapper.getAll();
} @RequestMapping("user/getMaster")
public UserModel getUserMaster(Integer userId) {
return masterUserMapper.get(userId);
} @RequestMapping("user/insertMaster")
public Integer insertMaster(UserModel userModel) {
masterUserMapper.insert(userModel);
// 必须使用对象获取id,否则无法获取到主键,而是获取到0(插入失败)或者1(插入成功)
return userModel.getUserId();
} @RequestMapping("user/updateMaster")
public Integer updateMaster(UserModel userModel) {
return masterUserMapper.update(userModel);
} @RequestMapping("user/deleteMaster")
public Integer deleteMaster(Integer userId) {
return masterUserMapper.delete(userId);
}
/************************主库控制层接口-end******************************/ /************************从库控制层接口-start******************************/
@RequestMapping("user/getAllCluster")
public List<UserModel> getAllCluster() {
return clusterUserMapper.getAll();
} @RequestMapping("user/getCluster")
public UserModel getUserCluster(Integer userId) {
return clusterUserMapper.get(userId);
} @RequestMapping("user/insertCluster")
public Integer insertCluster(UserModel userModel) {
clusterUserMapper.insert(userModel);
// 必须使用对象获取id,否则无法获取到主键,而是获取到0(插入失败)或者1(插入成功)
return userModel.getUserId();
} @RequestMapping("user/updateCluster")
public Integer updateCluster(UserModel userModel) {
return clusterUserMapper.update(userModel);
} @RequestMapping("user/deleteCluster")
public Integer deleteCluster(Integer userId) {
return clusterUserMapper.delete(userId);
}
/************************从库控制层接口-end******************************/
}
package com.spring.boot; import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.http.MediaType;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.ResultActions;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultHandlers;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext; @RunWith(SpringRunner.class)
@SpringBootTest
public class UserControllerTest { @Autowired
private WebApplicationContext context; private MockMvc mvc; @Before
public void setUp() throws Exception {
this.mvc = MockMvcBuilders.webAppContextSetup(context).build();
} /************************主库控制层接口测试-start******************************/
@Test
public void testInsertMaster() throws Exception {
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertMaster")
.param("userName", "testName")
.param("password", "password")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
String userId = action.andReturn().getResponse().getContentAsString(); System.out.println("userId:" + userId);
} @Test
public void testGetAllMaster() throws Exception { // 先保存,确保有数据
mvc.perform(MockMvcRequestBuilders
.post("/user/insertMaster")
.param("userName", "testName")
.param("password", "password")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); mvc.perform(MockMvcRequestBuilders
.get("/user/getAllMaster")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testGetMaster() throws Exception {
// 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertMaster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.get("/user/getMaster")
.param("userId", userId)
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testUpdateMaster() throws Exception {
// 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertMaster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.post("/user/updateMaster")
.param("userName", "修改")
.param("password", "password")
.param("phone", "13578236975")
.param("userId", userId)
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testDeleteMaster() throws Exception { // 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertMaster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.delete("/user/deleteMaster")
.param("userId", userId)
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
/************************主库控制层接口测试-end******************************/ /************************从库控制层接口测试-start******************************/ @Test
public void testInsertCluster() throws Exception {
mvc.perform(MockMvcRequestBuilders
.post("/user/insertCluster")
.param("userName", "testName")
.param("password", "password")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testGetAllCluster() throws Exception {
// 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertCluster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.get("/user/getAllCluster")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testGetCluster() throws Exception {
// 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertCluster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.get("/user/getCluster")
.param("userId", userId)
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testUpdateCluster() throws Exception {
// 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertCluster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.post("/user/updateCluster")
.param("userName", "testName修改")
.param("password", "password")
.param("phone", "13578236975")
.param("userId", userId)
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
} @Test
public void testDeleteCluster() throws Exception { // 先保存,确保有数据
ResultActions action = mvc.perform(MockMvcRequestBuilders
.post("/user/insertCluster")
.param("userName", "testName1")
.param("password", "password1")
.param("phone", "13578236975")
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print()); String userId = action.andReturn().getResponse().getContentAsString();
System.out.println("userId:" + userId); mvc.perform(MockMvcRequestBuilders
.delete("/user/deleteCluster")
.param("userId", userId)
.content(MediaType.APPLICATION_JSON_UTF8_VALUE)
.accept(MediaType.APPLICATION_JSON))
.andExpect(MockMvcResultMatchers.status().isOk())
.andDo(MockMvcResultHandlers.print());
}
/************************从库控制层接口测试-end******************************/
}
十、springboot已经包含了logback的相关jar包,只要在类路径下有名为“logback-spring”的xml文件即可进行日志打印,具体配置如下
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="10 seconds">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<!-- do not add line number output , it will slow down the execution speed -->
<pattern>%d{HH:mm:ss.SSS} [%thread] %level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 按天来回滚,如果需要按小时来回滚,则设置为{yyyy-MM-dd_HH} -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--文件路径和文件名称-->
<fileNamePattern>${catalina.base}/logs/test.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- 如果按天来回滚,则最大保存时间为1天,1天之前的都将被清理掉 -->
<maxHistory>30</maxHistory>
</rollingPolicy>
<!-- 日志输出格式 -->
<layout class="ch.qos.logback.classic.PatternLayout">
<Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} -%msg%n</Pattern>
</layout>
</appender>
<!-- 异步输出 -->
<!--输出文件-->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="FILE"/>
</appender>
<!--输出控制台-->
<appender name="ASYNC_STD" class="ch.qos.logback.classic.AsyncAppender">
<!-- 不丢失日志.默认的,如果队列的80%已满,则会丢弃TRACT、DEBUG、INFO级别的日志 -->
<discardingThreshold>0</discardingThreshold>
<!-- 更改默认的队列的深度,该值会影响性能.默认值为256 -->
<queueSize>512</queueSize>
<!-- 添加附加的appender,最多只能添加一个 -->
<appender-ref ref="STDOUT"/>
</appender> <root level="DEBUG">
<!-- 输出到控制台 -->
<appender-ref ref="ASYNC_STD"/>
<!-- 输出到文件 -->
<!-- <appender-ref ref="ASYNC"/> -->
</root> </configuration>
github地址:https://github.com/1053531172/springboot2
参考:http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html
springboot2.0+mybatis多数据源集成的更多相关文章
- spring-boot-2.0.3之quartz集成,数据源问题,源码探究
前言 开心一刻 着火了,他报警说:119吗,我家发生火灾了. 119问:在哪里? 他说:在我家. 119问:具体点. 他说:在我家的厨房里. 119问:我说你现在的位置. 他说:我趴在桌子底下. 11 ...
- spring-boot-2.0.3之quartz集成,不是你想的那样哦!
前言 开心一刻 晚上回家,爸妈正在吵架,见我回来就都不说话了,看见我妈坐在那里瞪着我爸,我就问老爸“你干什么了惹我妈生这么大气?” 我爸说“没有什么啊,倒是你,这么大了还没有媳妇,要是你有媳妇给我们 ...
- spring-boot-2.0.3之quartz集成,最佳实践
前言 开心一刻 快过年了,大街上,爷爷在给孙子示范摔炮怎么放,嘴里还不停念叨:要像这样,用劲甩才能响.示范了一个,两个,三个... 孙子终于忍不住了,抱着爷爷的腿哭起来:爷呀,你给我剩个吧! 新的一年 ...
- springboot2.0动态多数据源切换
摘要:springboot1.x到springboot2.0配置变化有一点变化,网上关于springboot2.0配置多数据源的资料也比较少,为了让大家配置多数据源从springboot1.x升级到s ...
- SpringBoot2 + Druid + Mybatis 多数据源动态配置
在大数据高并发的应用场景下,为了更快的响应用户请求,读写分离是比较常见的应对方案.读写分离会使用多数据源的使用.下面记录如何搭建SpringBoot2 + Druid + Mybatis 多数据源配 ...
- SpringBoot2.x+mybatis plus3.x集成Activit7版本
最近在写一个开源项目ruoyi-vue-pro,暂时负责Activiti7工作流的搭建,接这个任务一个原因,是比较好奇Activiti7版本与先前的5.6版本究竟有什么区别,因为先前在工作当中,最开始 ...
- SpringBoot2.0+Mybatis+PageHelper+Redis实现缓存
1.在maven引入相关的依赖 <parent> <groupId>org.springframework.boot</groupId> <artifactI ...
- springboot学习入门简易版九---springboot2.0整合多数据源mybatis mysql8+(22)
一个项目中配置多个数据源(链接不同库jdbc),无限大,具体多少根据内存大小 项目中多数据源如何划分:分包名(业务)或注解方式.分包名方式类似多个不同的jar,同业务需求放一个包中. 分包方式配置多数 ...
- SpringBoot2.0之八 多数据源配置
在开发的过程中我们可能都会遇到对接公司其他系统等需求,对于外部的系统可以采用接口对接的方式,对于一个公司开发的两个系统,并且知道相关数据库结构的情况下,就可以考虑使用多数据源来解决这个问题.Spri ...
随机推荐
- Linux测试硬盘读性能的常用工具-hdparm
通常情况下可以使用fdisk.df等命令查看硬盘的分区情况以及当前已使用空间大小.剩余空间大小等信息.但是如果要查看硬盘的硬件信息如 硬盘型号.序列号.已运行时间等信息该用什么工具查看呢? 在Linu ...
- Javascript事件派发-dispatchEvent
事件派发的作用: 1.派发数据,将一个封闭模块中的数据传递给另一个封闭模块.2.事件完成了较为复杂的解耦. 事件和回调函数不同在于: 1.事件可以在任意地方去获取,而回调函数只能在一个地方存在,如果需 ...
- eclipse remote system explorer operation
Remote System Explorer Operation卡死Eclipse解决方案 - 披萨大叔的博客 - CSDN博客https://blog.csdn.net/qq_27258799/ar ...
- 为什么vue组件的属性,有的需要加冒号“:”,有的不用?
https://segmentfault.com/q/1010000010929963/a-1020000010930077 <tab :line-width="2" act ...
- Dart接口
/* 和Java一样,dart也有接口,但是和Java还是有区别的. 首先,dart的接口没有interface关键字定义接口,而是普通类或抽象类都可以作为接口被实现. 同样使用implements关 ...
- 如何发布H5界面可以让公网访问
本文链接:https://blog.csdn.net/u013310119/article/details/81233560问题背景:手机APP里的H5界面要发布到公网,提供给第三方APP调用. 解决 ...
- Linux下文件乱码问题
通常编码会在windows环境下进行,当把windows下的代码拷贝到linux环境时,会出现 error: “build.sh /bin/bash^M: 坏的解释器:没有那个文件或目录” 等等类似问 ...
- Spring MVC 验证表单
在实际工作中,得到数据后的第一步就是检验数据的正确性,如果存在录入上的问题,一般会通过注解校验,发现错误后返回给用户,但是对于一些逻辑上的错误,比如购买金额=购买数量×单价,这样的规则就很难使用注 ...
- AI佳作解读系列(五) - 目标检测二十年技术综述
计算机视觉中的目标检测,因其在真实世界的大量应用需求,比如自动驾驶.视频监控.机器人视觉等,而被研究学者广泛关注. 上周四,arXiv新出一篇目标检测文献<Object Detection ...
- MySQL 8中使用全文检索示例
首先建议张册测试用的表test,并使用fulltext说明将title和body两列的数据加入全文检索的索引列中: drop table if exists test; create table te ...