In the development of medium and large-scale enterprise projects, environment separation is an essential step. However, today's developers only have this concept. There are still many projects that use ordinary methods, changing a lot of configuration each time they are packaged, released and deployed. If you forget to change one part of the file, it is equivalent to updating the system once. This way of modifying the configuration file to complete the environment replacement has brought us a lot of trouble and wasted a lot of our precious time! As early as the Spring 3.1
version, it has provided us with the relevant understanding configuration method of environment separation, but the configuration in the traditional Spring project is Profile
indeed a bit troublesome. After Spring
the continuous update of the version, it has been able to support the separation of the project configuration environment well SpringBoot
after it grows up .Profile
Objectives of this chapter
Based on SpringBoot
the platform, it completes simple database environment operation separation, and Profile
completes different database operations according to different activations.
SpringBoot enterprise-level core technology learning topic
Topic | Topic name | Thematic description |
---|---|---|
001 | Spring Boot core technology | Explain some core components of SpringBoot at the enterprise level |
002 | Spring Boot core technology chapter source code | Each article in the Spring Boot core technology brief book corresponds to the source code of the code cloud |
003 | Spring Cloud core technology | Comprehensive explanation of the core technologies of Spring Cloud |
004 | Spring Cloud core technology chapter source code | Each article in the Spring Cloud core technology brief book corresponds to the source code |
005 | QueryDSL core technology | Comprehensively explain the core technology of QueryDSL and integrate SpringDataJPA based on SpringBoot |
006 | SpringDataJPA core technology | Comprehensive explanation of the core technology of Spring Data JPA |
Build the project
Use the Idea tool to create a SpringBoot
project, SpringBoot
the current version has been updated to 1.5.8
, we use the latest version to complete the content of this chapter, add related JPA
, MySQL
, Druid
, , Lombok
, Web
, FastJson
etc. The pom.xml dependency configuration is as follows:
....省略部分配置
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.8.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>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--引入druid最新maven依赖-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.4</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.39</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
....省略部分配置
configuration database
We create three databases: project_prod
=> online environment database, project_dev
=> development environment database, => online test environment database, so that we can distinguish the environment well when project_beta
switching , let's create a basic user information table, Profile
The SQL is as follows:
-- ----------------------------
-- Table structure for system_user_info
-- ----------------------------
DROP TABLE IF EXISTS `system_user_info`;
CREATE TABLE `system_user_info` (
`SUI_ID` int(11) NOT NULL AUTO_INCREMENT,
`SUI_NICK_NAME` varchar(50) DEFAULT NULL,
`SUI_LOGIN_NAME` varchar(30) DEFAULT NULL,
`SUI_LOGIN_PASSWORD` varchar(32) DEFAULT NULL,
PRIMARY KEY (`SUI_ID`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
Execute the above SQL in the three databases respectively to ensure that our data structure environment is consistent, and then insert data into the corresponding databases, as follows:
INSERT INTO `system_user_info` VALUES ('1', '线上测试环境用户', 'beta', 'beta_password');
INSERT INTO `system_user_info` VALUES ('1', '开发环境用户', 'dev', 'dev_password');
INSERT INTO `system_user_info` VALUES ('1', '正式环境用户', 'prod', 'prod_password');
This way we can distinguish the specific environment the project is accessing.
Create Entity
Create a data entity corresponding to system_user_info
the data table as follows:
package com.yuqiyu.chapter38.entity;
import lombok.Data;
import javax.persistence.*;
/**
* 用户基本信息实体
* ========================
* Created with IntelliJ IDEA.
* User:恒宇少年
* Date:2017/10/29
* Time:08:25
* 码云:http://git.oschina.net/jnyqy
* ========================
*/
@Entity
@Table(name = "system_user_info")
@Data
public class SystemUserInfoEntity
{
/**
* 主键
*/
@Column(name = "SUI_ID")
@GeneratedValue
@Id
private Integer id;
/**
* 昵称
*/
@Column(name = "SUI_NICK_NAME")
private String nickName;
/**
* 登录名
*/
@Column(name = "SUI_LOGIN_NAME")
private String loginName;
/**
* 登录密码
*/
@Column(name = "SUI_LOGIN_PASSWORD")
private String loginPassword;
}
Next, we create a JPA interface for the above entity, and inherit the JpaRepository<T,PK>
interface to complete Jpa
the action of scanning automatic proxy instances.
Create JPA
SystemUserInfoJPA
The content of the interface is as follows:
package com.yuqiyu.chapter38.jpa;
import com.yuqiyu.chapter38.entity.SystemUserInfoEntity;
import org.springframework.data.jpa.repository.JpaRepository;
/**
* 系统用户信息jpa
* ========================
* Created with IntelliJ IDEA.
* User:恒宇少年
* Date:2017/10/29
* Time:08:30
* 码云:http://git.oschina.net/jnyqy
* ========================
*/
public interface SystemUserInfoJPA
extends JpaRepository<SystemUserInfoEntity,Integer>
{
}
Configure the Profile environment
InSpringBoot
order to agree Profile
on the naming rules of configuration files, that is: application-xxx.properties
Or application-xxx.yml
, we only need to put the configuration files of the corresponding environment in the resources
directory, that is classpath
, we write three different configuration files corresponding to our database environment. .
application-dev.yml
According to our SpringBoot
agreement application-dev.xml
, all configuration files are development environment information, which contains development environment data source configuration information. Of course, in the actual project development process, the configuration information can be arbitrarily agreed. The configuration content is as follows:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/project_dev?characterEncoding=utf8
username: root
password: 123456
#最大活跃数
maxActive: 20
#初始化数量
initialSize: 1
#最大连接等待超时时间
maxWait: 60000
#打开PSCache,并且指定每个连接PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
#通过connectionProperties属性来打开mergeSql功能;慢SQL记录
#connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
#配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
filters: stat, wall, log4j
jpa:
properties:
hibernate:
show_sql: true
format_sql: true
As you can see in the above code, we connect the local project_dev
database as the access data source for the development environment.
application-beta.yml
application-beta.yml
The configuration file is SpringBoot
the online test environment we agreed with. In our actual development process, the online test environment is definitely not the same database as the development environment. At this time, we application-dev.yml
copy the configuration file and modify the database link information. If There are other configurations in yours application-beta.yml
, don't forget to modify them to the relevant environment configuration. The configuration information is as follows:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/project_beta?characterEncoding=utf8
username: root
password: 123456
#最大活跃数
maxActive: 20
#初始化数量
initialSize: 1
#最大连接等待超时时间
maxWait: 60000
#打开PSCache,并且指定每个连接PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
#通过connectionProperties属性来打开mergeSql功能;慢SQL记录
#connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
#配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
filters: stat, wall, log4j
jpa:
properties:
hibernate:
show_sql: true
format_sql: true
application-prod.yml
The application-prod.yml
configuration file is the configuration file SpringBoot
of the online production environment that we agreed with. All the information stored in it is the official environment configuration information. Generally, the online environment configuration information does not need to be changed during the development process. After the configuration is completed, it is only packaged. It spring.profiles.active
is enough to modify prod
it during deployment (Note: It depends on the configuration convention name of the online environment of the actual project). The configuration information is as follows:
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/project_prod?characterEncoding=utf8
username: root
password: 123456
#最大活跃数
maxActive: 20
#初始化数量
initialSize: 1
#最大连接等待超时时间
maxWait: 60000
#打开PSCache,并且指定每个连接PSCache的大小
poolPreparedStatements: true
maxPoolPreparedStatementPerConnectionSize: 20
#通过connectionProperties属性来打开mergeSql功能;慢SQL记录
#connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
minIdle: 1
timeBetweenEvictionRunsMillis: 60000
minEvictableIdleTimeMillis: 300000
validationQuery: select 1 from dual
testWhileIdle: true
testOnBorrow: false
testOnReturn: false
#配置监控统计拦截的filters,去掉后监控界面sql将无法统计,'wall'用于防火墙
filters: stat, wall, log4j
jpa:
properties:
hibernate:
show_sql: true
format_sql: true
In order to facilitate our testing, I created three databases locally. Of course, in the actual project development, you may be a database read-write separation environment, or an environment where multiple servers are completely separated. You only need to modify the corresponding configuration for different conventions. Information will do.
Test Profile
Next, let's create a controller that uses what we have created above to SystemUserInfoJPA
complete the read action from the database.
Create a test controller
In the above, we configure the content of the database table spring.profiles.active for each environment ``都初始化了一条数据,那么我就来编写一个读取数据库的请求方法,根据我们修改的
, whether the request database can be changed. The controller code is as follows:
package com.yuqiyu.chapter38;
import com.yuqiyu.chapter38.entity.SystemUserInfoEntity;
import com.yuqiyu.chapter38.jpa.SystemUserInfoJPA;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* 测试profile环境
* ========================
* Created with IntelliJ IDEA.
* User:恒宇少年
* Date:2017/10/29
* Time:09:02
* 码云:http://git.oschina.net/jnyqy
* ========================
* @author hengyu
*/
@RestController
@RequestMapping(value = "/user")
public class IndexController
{
@Autowired
private SystemUserInfoJPA systemUserInfoJPA;
/**
* 查询用户详情
* @param id
* @return
*/
@RequestMapping(value = "/{id}")
public SystemUserInfoEntity detail(@PathVariable("id") Integer id)
throws Exception
{
return systemUserInfoJPA.findOne(id);
}
}
In the controller, by accessing the /user/{id}
request address, we can obtain the basic information of the user and display it in the form of a string on the page. Json
Next, we will configure the ones that need to be activated, Profile
and visit the request address to view the output effect.
Activate Profile
Since the activated Profile
configuration does not belong to any environment-separated configuration file, we cannot add the activation configuration to any dev
configuration beta
file of , the configuration looks like this:prod
application.yml
SpringBoot
spring:
profiles:
active: dev
We application.yml
activated the development environment in the configuration file, dev
and now we start the project to access the request path http://127.0.0.1:8080/user/1 to view the interface output, as shown below:
{
id: 1,
nickName: "开发环境用户",
loginName: "dev",
loginPassword: "dev_password"
}
As we expected, the user information of the development environment is correctly output, so if we modify the activation environment, will it also program the corresponding output? Let's confirm this by modifying the activation environment to be an online development environment:
spring:
profiles:
active: beta
Restart the project and visit http://127.0.0.1:8080/user/1 to request the path again. The output of the interface is as follows:
{
id: 1,
nickName: "线上测试环境用户",
loginName: "beta",
loginPassword: "beta_password"
}
It can be seen that it has been changed to the effect we need. We just activate different environments, and we can easily separate the environments. The formal environment is the same. Let's activate the formal environment to complete the Package
packaging.
Formal environment packaging
There are many projects that need to change a lot of configuration files, access addresses and other configuration information when they are packaged and deployed online. So what should we do with Profile
post-package?
The answer is: worry.
In the first step, we only need to modify the activation environment to an online environment, as shown below:
spring:
profiles:
active: prod
The second step is to run the packaging command and wait for the packaging to complete. This chapter is Idea
the packaging completed by the development tool. The Idea
tool has its Maven
own command window. You only need to select a different command and double-click to execute it, as shown in Figure 1 below:
We double-click package
the command and wait for the packaging to complete. After completion, jar
it war
will be target
generated in the directory. Next, we use the Windows CMD
command line to enter the jar
existing directory. Before executing the command, we need to turn off Idea
the started project:
java -jar chapter38-0.0.1-SNAPSHOT.jar
After the startup is complete, we visit the request address http://127.0.0.1:8080/user/1 again to view the interface output:
{
id: 1,
nickName: "正式环境用户",
loginName: "prod",
loginPassword: "prod_password"
}
prod
The user information of the official environment is correctly output .
Summarize
Profile
The addition of the config file can save many operation and maintenance personnel a lot of trouble. A few years ago, the deployment was completely by modifying the configuration file. If the modification is wrong, it will lead to rework, which is a waste of time and energy.
It is recommended that you use the environment separation method to build the project as much as possible in the early stage of the project!
The code of this chapter has been uploaded to the code cloud:
SpringBoot supporting source code address: https://gitee.com/hengboy/spring-boot-chapter
SpringCloud supporting source code address: https://gitee.com/hengboy/spring-cloud-chapter
SpringBoot related For the series of articles, please visit: Catalog: SpringBoot Learning Catalogue
QueryDSL related series of articles, please visit: QueryDSL General Query Framework Learning Catalog
Spring DataJPA-related series of articles, please visit: Catalog: Spring DataJPA Learning Catalog
Thank you for reading!
Welcome to join the QQ technical exchange group and make progress together.