This project, I intend to be a seed project, as a seed project, must be “out of the box”, must contain most of the web development related functions, all the later Spring Boot projects are to take this project, simple modification of the configuration, can be quickly developed.
The source code
Github
1.0.0 Creating a project
The IDE I use is IDEA
Create a project
Select Spring Initializr, maybe if Next keeps going around in circlesstart.spring.io/In foreign countries, access is slower. You can go scientific or you can use customstart.spring.io/
Change the organization name, project name and project description
When I created the project, the latest stable release of Spring Boot was 2.1.9. Use the latest!! Dependence is not checked first, later a plus
Project folder name and location
Adding a Maven Image
Add Maven images to speed up dependency downloads
<repository> <name> Maven Repository </name> <id> Huawei </ ID > <url>https://mirrors.huaweicloud.com/repository/maven/</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <name> <id> Huawei_plugin </id> <url>https://mirrors.huaweicloud.com/repository/maven/</url> </pluginRepository> </pluginRepositories>Copy the code
Pom file
The entire.pom file contains the following contents
<? The 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 https://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion > 4.0.0 < / modelVersion > < the parent > < groupId > org. Springframework. Boot < / groupId > The < artifactId > spring - the boot - starter - parent < / artifactId > < version > 2.1.9. RELEASE < / version > < relativePath / > < / parent > < the groupId > com. WQLM < / groupId > < artifactId > boot < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > < name > boot < / name > <description>Spring Boot Demo</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> < name > maven huawei warehouse < / name > < id > huawei < id > < url > https://mirrors.huaweicloud.com/repository/maven/ < / url > < / repository > </ repository > <pluginRepository> <name> huawei maven pluginRepository </name> <id>huawei_plugin</id> <url>https://mirrors.huaweicloud.com/repository/maven/</url> </pluginRepository> </pluginRepositories> </project>Copy the code
Dependent structure diagram
One day
Spring-boot-starter and spring-boot-starter-test do not specify the version. How do they determine the version?
Why can maven dependencies not specify versions
1.1.0 Adding a Web Module
Add a Web module to the POM file
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
Copy the code
Due to thespring-boot-starter-webcontainsspring-boot-starter
You are advised to delete the following spring-boot-starter dependencies to ensure their cleanliness
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
Copy the code
role
With the introduction of spring-boot-starter-Web, we can
- Writing web applications
- You do not need to configure containers to run web applications
- Verify the request parameters
- Returns the business result object converted to joSN
Dependent structure diagram
We can see from the picturespring-boot-starter-webSeveral key dependencies are introduced
- spring-boot-starter
- Spring-boot-starter-tomcat: Spring boot can be started without Tomcat because of it
- spring-webmvc
- spring-web
- spring-boot-starter-jsonWith it, you can use @responseBody to return JSON data
- Jackson: Spring Boot’s default JSON parsing tool
- hibernate-validator: provides annotations for parameter verification, such as@ Range, @ Length
- Javax. validation: annotations that provide validation of parameters, such as @notblank, @notnull, or @pattern
For parameter verification, see Parameter Verification Hibernate-Validator
1.2.0 integration mysql
Spring Boot integration with mysql requires a JDBC driver and mysql driver
Introduction of depend on
<! --JDBC--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <! --mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency>Copy the code
The version number is optional. Spring Boot has a default version number. For example, spring Boot 2.1.9.RELEASE corresponds to mysql-connector-Java version 8.0.17
Configure the mysql
The configuration varies slightly depending on the mysql-connector-Java version
# mysql connector - Java 6.0 x version configuration under spring. The datasource. The driverClassName = com. Mysql.. JDBC Driver spring.datasource.url=jdbc:mysql://localhost:3306/boot? useUnicode=true&characterEncoding=utf-8&useSSL=false spring.datasource.username=root spring.datasource.password=123456Copy the code
# mysql connector - Java 6.0 x and above version configuration spring. The datasource. The driverClassName = com. Mysql. Cj). The JDBC Driver spring.datasource.url=jdbc:mysql://localhost:3306/boot? useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456Copy the code
The following figure,Spring boot 2.1.9. RELEASEThe correspondingmysql-connector-javaVersion for 8.0.17
See MySQL JDBC Connection for more information
Create sample databases and tables
CREATE DATABASE IF NOT EXISTS boot DEFAULT CHARSET UTf8 COLLATE UTf8_bin; -- Select boot database USE boot; SET NAMES utf8mb4; SET FOREIGN_KEY_CHECKS = 0; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` ( `id` INT ( 11 ) NOT NULL AUTO_INCREMENT, `user_name` VARCHAR ( 255 ) COLLATE utf8_bin NOT NULL, `pasword` VARCHAR ( 255 ) COLLATE utf8_bin NOT NULL, `salt` VARCHAR ( 255 ) COLLATE utf8_bin NOT NULL, PRIMARY KEY ( `id` ) ) ENGINE = INNODB DEFAULT CHARSET = utf8 COLLATE = utf8_bin; SET FOREIGN_KEY_CHECKS = 1;Copy the code
1.3.0 Multi-environment Configuration
Refer to Spring Profile and Maven Profile multi-environment management for details
Spring multi-environment configuration
Configure a DEV environment
createapplication-dev.properties
File and migrate the mysql related configuration
Using the Dev environment
Specify the environment to use in application-dev.properties
spring.profiles.active=dev
Copy the code
You can create test and prod environments in the same way, but the general public Settings will be placed in application.properties, and only non-public Settings will be placed in their respective environments
Maven multi-environment configuration
Spring Boot multi-environment configuration has two disadvantages
- Manually change the environment each time
spring.profiles.active
The value of the - When packaging, manually delete configuration files of other environments, otherwise sensitive information of other environments will be packaged
Maven’s profile addresses both of these issues
First question
“Change the environment manually every time you switchspring.profiles.active
The value of the”
This problem can be solved by configuring profiles to be added under the root node of the POM
<profiles> <profile> <id>dev</id> <activation> <! -- If activeByDefault is true, the profile with id dev is activated by default --> <activeByDefault>true</activeByDefault> </activation> <! <properties> <! The value of this node can be referenced elsewhere in Maven, <env>dev</env> </properties> </profile> <profile> <id>test</id> <properties> <env> </properties> </profile> <profile> <id>prod</id> <properties> <env>prod</env> </properties> </profile> </profiles>Copy the code
As shown above, three sets of environments are defined, where dev is the default environment and a “variable” called env is defined.
If you are using the IDEA editor, the Maven control window should have an additional Profiles, where the default value is the dev configured above
With minimal Profiles already configured, you can quickly switch maven’s profile environment by checking Profiles in the figure above.
Maven Profiles can now quickly switch environments by checking Profiles in the image above
Spring profiles also have to manually modify the value of spring.profiles.active to cut the environment
The question now is how to match the Maven profile environment to the Spring Profile environment so that when the Maven profile environment is switched, the Spring Profile environment is also switched
Remember the env “variables” defined in the Maven profile
spring.profiles.active=dev
Copy the code
to
spring.profiles.active=@env@
Copy the code
The Maven profile is associated with the Spring Profile environment
When a Maven profile is set to test, the profile environment defined in the POM with the id of test will be activated. In this environment, env is set to test. The Maven plugin will replace @env@ with test. This changes the environment of the Spring Profile. As you can see from the above, the value of the custom “variable “env should not be scribbled, but should correspond to the Spring Profile environment.
conclusion
- Step one, in
pom
Configure profiles in the file - Step two, in
application.properties
Added to the configuration filespring.profiles.active=@env@
Second question
When packaging, manually delete configuration files of other environments, otherwise sensitive information of other environments will be packaged
To resolve this problem, you need to configure build information under the POM root node
<build> <resources> <resource> <directory>src/main/resources</directory> <excludes> <! --> <exclude> Application *. Yml </exclude> </excludes> </resource> < Resource > <directory>src/main/resources</directory> <! -- Filtering needs to be set to true, so that when included, The maven variable @env@ in the configuration file is replaced with the corresponding value of the current environment --> <filtering>true</filtering> <includes> <! Yml </include> <include> Application -${env}. Yml </include> </includes> </resource> </resources> </build>Copy the code
- Directory: indicates the directory where the resource file resides
- Includes: list of files to be included
- Excludes: List of files to exclude
As above, is configured with two < resource >, first to exclude the SRC/main/resources directory all application configuration file is in the beginning, the second in the first added on the basis of the required configuration file. Note that application-${env}. Yml is a dynamic value that changes with the current environment. If the current environment is a profile named dev, then env is dev.
After this configuration, Maven will first exclude the specified configuration file during build, and then add the required configuration file based on the current environment.
Pom file
<? The 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 https://maven.apache.org/xsd/maven-4.0.0.xsd" > < modelVersion > 4.0.0 < / modelVersion > < the parent > < groupId > org. Springframework. Boot < / groupId > The < artifactId > spring - the boot - starter - parent < / artifactId > < version > 2.1.9. RELEASE < / version > < relativePath / > < / parent > < the groupId > com. WQLM < / groupId > < artifactId > boot < / artifactId > < version > 0.0.1 - the SNAPSHOT < / version > < name > boot < / name > <description>Spring Boot Demo</description> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> < project. Reporting. OutputEncoding > utf-8 < / project. Reporting. OutputEncoding > < Java version > 1.8 < / Java version > </properties> <! -- Maven Multi-environment --> <profiles> <profile> <id>dev</id> <activation> <activeByDefault>true</activeByDefault> <! -- True indicates that the profile is activated by default --> </activation> <properties> <! <env>dev</env> <! The value of this node can be referenced elsewhere in Maven, </properties> </profile> <profile> <id>test</id> <properties> </env> </profile> <profile> <id>prod</id> <properties> <env>prod</env> </properties> </profile> </profiles> <dependencies> <! --web--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <! --mysql--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <! --mybatis--> <dependency> <groupId>org.mybatis.spring.boot</groupId> < artifactId > mybatis - spring - the boot - starter < / artifactId > < version > 2.1.0 < / version > < / dependency > <! --test--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> <resources> <resource> <directory>src/main/resources</directory> <excludes> <! --> <exclude> Application *. Yml </exclude> </excludes> </resource> < Resource > <directory>src/main/resources</directory> <! The maven variable @env@ will be replaced with the current value in the include file --> <filtering>true</filtering> <includes> <! Yml </include> <include> Application -${env}. Yml </include> </includes> </resource> </resources> </build> <repository> <name> Huawei Maven </name> <id> Huawei </id> <url>https://mirrors.huaweicloud.com/repository/maven/</url> </repository> </repositories> <pluginRepositories> <pluginRepository> <name> <id> Huawei_plugin </id> <url>https://mirrors.huaweicloud.com/repository/maven/</url> </pluginRepository> </pluginRepositories> </project>Copy the code
1.4.0 Multi-Module Configuration
Larger projects tend to be managed in a multi-module format. Upgrading a large project to a multi-module format usually requires two steps
- Breaking up existing projects
- Configure multiple Maven modules
For details on how to split existing projects and Maven multi-module configuration, see Maven Multi-module Configuration, Management
Breaking up existing projects
I split the project by function, but since the project itself is not large, I simply split it into the User module and the Common module
Create two new modules under Boot
Pom for submodules
At this point, the content of the parent module’s POM is also changed, adding the following three lines
Create the Common module again, the same process, I will not demonstrate, after the creation of the poM is as follows
The overall project structure is as follows
The next step is to migrate the contents under the original SRC directory to the appropriate submodules
Here I put in the user module, pay attention to the path and naming conventions during the migration process, the process is not shown, after the migration, the structure is as follows.
Multi-module Configuration
The multi-module configuration complies with the following principles
- Common and generic configurations must be configured in the parent POM
- The version number is centrally managed by the parent POM
As shown below, elements with a blue background will all inherit from the quilt project
At present, only the user module uses the following dependencies, and the common module does not need these dependencies. Therefore, copy the dependencies to the user module and delete the dependencies
buildThe configuration is only used by the user module, also copied to the user module, later deleted
Now that the parent project is configured, configure the User module as follows
The common module is configured when used
Multi-module Management
Multi-module environment managementWe configured the Maven multienvironment in the parent POM, and the submodules inherit these configurations. After that, we just need to switch the maven environment in the Maven plugin, and all the sub-modules’ Maven environment will be switched
Multi-module build managementIn the Maven plugin, all submodules are compiled, tested, packaged, cleaned…
1.5.0 integration mybatis
Integrating Mybatis generally requires 5 steps
- Introduction of depend on
- Create the PO layer to hold our data persistence objects
- Create DAO layer to store the add, delete, change and check methods of the database
- Create mapper. XML layer corresponding to add, delete, change and query statements
- Configure @Mapperscan on the startup class
- The other. For example, MyBatis Generator is configured to help us generate PO, DAO and mapper.xml
Add the dependent
There are a few things to note when adding dependencies to a multi-module project
- Do not add a dependency directly to the parent POM, so that all child modules inherit the dependency
- Multiple modules reference the same dependency. It is best to ensure that the version of the dependency is the same
Maven dependencyManagement is an easy way to manage multi-module dependencies
For maven dependencyManagement, see maven dependency version management
I’m not going to explain it, I’m going to apply it
-
Define the mybatis-spring-boot-starter version variable in properties
< mybatis - spring - the boot - starter. Version > 2.1.0 < / mybatis - spring - the boot - starter. Version >Copy the code
-
Declare the Mybatis dependency at the root of the parent POM
<dependencyManagement> <dependencies> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>${mybatis-spring-boot-starter.version}</version> </dependency> </dependencies> </dependencyManagement> Copy the code
-
Introduce the MyBatis dependency in the POM file of the User module
<dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> Copy the code
-
Because mybatis-spring-boot-starter contains spring-boot-starter- JDBC, delete the spring-boot-starter- JDBC dependency to ensure that the dependency is clean
Dependent structure diagram
Create the corresponding folder
As shown in figure
com.wqlm.boot
- Controller: indicates the control layer
- Po: Stores Java objects corresponding to tables in the database
- Dto: Stores data transfer objects, such as registration, registration information can be received with a DTO object
- Dao: Interface for storing operation database
- Service: indicates the service layer
- Vo: stores the service result object
- Qo: encapsulates query parameters
resources
- Mapper: stores the mapper. XML file
Configure mybatis
Mybatis needs to know which classes are mapper! There are two ways to tell Mybatis.
The first kind of
Configure @Mapperscan on the startup class
Dao = MapperScan("com.wqlm.boot.user.dao")Copy the code
The second,Add to the interface@Mapper
Notes, as follows
If I had to choose, I’d choose the first configuration once and for all
Also tell Mybatis, where is your mapper. XML file
Mybatis. Mapper-locations =classpath*:mapper/*.xmlCopy the code
Since the configuration here is environment-independent, it should be configured inapplication.properties 中
1.5.1 Configuring MyBatis Generator
MyBatis Generator is a code generation tool provided by MyBatis. It can help us generate persistent objects (Po) for tables, interfaces to manipulate databases (DAO), XML for CRUD SQL (Mapper).
The usage method is divided into three steps
- Introduce and configure the MyBatis Generator plug-in
- Configure the MyBatis Generator Config file
- Use the MyBatis Generator plug-in
For details, see MyBatis Generator HyperDetailed Configuration
Only one final configuration is given here
Introduce and configure the MyBatis Generator plug-in
Add the following configuration under the root node of the USER project poM file
<build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> < artifactId > mybatis generator - maven plugin - < / artifactId > < version > 1.3.7 < / version > < configuration > <! - mybatis code generator configuration file - > < configurationFile > SRC/main/resources/mybatis generator - config. XML < / configurationFile > <! -- Allow overwriting generated files --> <overwrite>true</overwrite> <! Add the current POM dependencies to the generator's classpath --> <! --<includeCompileDependencies>true</includeCompileDependencies>--> </configuration> <dependencies> <! -- Mybatis -Generator plugin dependencies --> <! --<dependency>--> <! --<groupId>org.mybatis.generator</groupId>--> <! --<artifactId>mybatis-generator-core</artifactId>--> <! - < version > 1.3.7 < / version > -- > <! --</dependency>--> <! <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.17</version> </dependency> </dependencies> </plugin> </plugins> <build>Copy the code
Configure the MyBatis Generator Config file
In the Resources directory of the User project, create mybatis-generator-config.xml as follows
<? The XML version = "1.0" encoding = "utf-8"? > <! Mybatis code generator configuration --> <! DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <! --> <properties resource="application-dev.properties"/> <! A database has a context, and the children of the context must be in the order they are given. Property *,plugin*,commentGenerator? ,jdbcConnection,javaTypeResolver? , javaModelGenerator,sqlMapGenerator? ,javaClientGenerator? ,table+ --> <context id="myContext" targetRuntime="MyBatis3" defaultModelType="flat"> <! -- This plugin adds equals and hashCode methods to generated Java model objects --> <! --<plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin"/>--> <! -- Comments --> <commentGenerator> <! <property name="suppressAllComments" value="true"/> <! -- Do not want generated comments to contain timestamps --> <! --<property name="suppressDate" value="true"/>--> <! Add comments for db table fields only if suppressAllComments is false --> <! --<property name="addRemarkComments" value="true"/>--> </commentGenerator> <! - a JDBC connection - > < jdbcConnection driverClass = "${spring. The datasource. DriverClassName}" connectionURL="${spring.datasource.url}" userId="${spring.datasource.username}" password="${spring.datasource.password}"> <! NullCatalogMeansCurrent =true--> <property name="nullCatalogMeansCurrent" value="true"/> </jdbcConnection> <! --> <javaTypeResolver> <! -- Whether to use bigDecimal, default is false. False, resolves the JDBC DECIMAL and NUMERIC types to Integer true, Parse JDBC DECIMAL and NUMERIC types to java.math.BigDecimal--> <property name="forceBigDecimals" value="true"/> <! -- Default false false, parse all JDBC time types to java.util.Date true, DATE -> java.time.LocalDate time -> java.time.LocalTime TIMESTAMP -> java.time.LocalDateTime TIME_WITH_TIMEZONE -> java.time.OffsetTime TIMESTAMP_WITH_TIMEZONE -> java.time.OffsetDateTime --> <! --<property name="useJSR310Types" value="false"/>--> </javaTypeResolver> <! <javaModelGenerator targetPackage="com.wqlm.boot.user. Po "targetProject=" SRC /main/ Java "> <! -- Whether to use schema as package suffix. Default is false --> <! --<property name="enableSubPackages" value="false"/>--> <! <property name="trimStrings" value="true"/> </javaModelGenerator> <! <sqlMapGenerator targetPackage=" Mapper "targetProject=" SRC /main/resources"> <! --<property name="enableSubPackages" value="false"/>--> </sqlMapGenerator> <! <javaClientGenerator targetPackage="com.wqlm.boot.user.dao" targetProject=" SRC /main/ Java" type="XMLMAPPER"> <! --<property name="enableSubPackages" value="false"/>--> </javaClientGenerator> <! -- Schema indicates the name of the database. Oracle needs to be configured, but mysql does not. TableName specifies the name of the corresponding database table. DomainObjectName specifies the name of the entity class to be generated. By default, the PASCAL naming method converts the tableName to the class name. True generates an Example helper class to help you with conditional queries, --> <table schema="" tableName="user" domainObjectName=" user" enableCountByExample="false" enableDeleteByExample="false" enableSelectByExample="false" enableUpdateByExample="false" selectByExampleQueryId="false"> <! -- Whether to use actual column names, default is false--> <! --<property name="useActualColumnNames" value="false" />--> </table> </context> </generatorConfiguration>Copy the code
Application – dev. The properties of the configuration
The external configuration file referenced by MyBatis Generator Config is as follows
# mysql spring.datasource.driverClassName=com.mysql.cj.jdbc.Driver spring.datasource.url=jdbc:mysql://localhost:3306/boot? useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456Copy the code
Use the MyBatis Generator plug-in
Once configured, double-click MyBatis Generator in Maven to run it
1.5.2 Integration of Tk.Mybatis (Universal Mapper)
In the previous section, MyBatis Generator generated some common methods for manipulating databases. This can also be done by integrating tk.mybatis (universal mapper), which will provide more common methods that do not require mapper.xml configuration.
Springboot integration with Tk.mybatis (general mapper) generally requires 3 steps
- Introduction of depend on
- Configure the Mybatis Generator plug-in for Tk.mybatis
- The DAO path configured to scan on the startup class
- Configure the universal Mapper
Tk. Mybatis dead simple
Introduction of depend on
As usual, configure the tk.mybatis version in the parent POM and declare the tk.mybatis dependency
. < the properties > < tk. Mybatis mapper - spring - the boot - starter. Version > 2.1.5 < / tk, mybatis mapper - spring - the boot - starter. Version > </properties> <! <dependencyManagement> <dependencies> <! Tk.mybatis mapper--> <dependency> <groupId> Tk.mybatis </groupId> <artifactId> <version>${tk.mybatis.mapper-spring-boot-starter.version}</version> </dependency> </dependencies> </dependencyManagement>Copy the code
Dependencies are then introduced into the POM of the User module
<dependencies> <! Tk.mybatis mapper--> <dependency> <groupId> Tk.mybatis </groupId> <artifactId> </dependency> </dependencies>Copy the code
Configure the Mybatis Generator plug-in for Tk.mybatis
Tk.mybatis has developed a plugin for Mybatis Generator to change the original generation strategy of MyBatis Generator. Once configured, the generated files are more concise and the comments are more meaningful.
The entire configuration process consists of two steps
- Introducing plug-in dependencies
- Modify MyBatis Generator Config
Introducing plug-in dependencies
In the original MyBatis Generator plugindependenciesAdd the following dependencies
<! Mybatis </groupId> <artifactId>mapper</artifactId> <version>4.1.5</version> </dependency>Copy the code
Modify MyBatis Generator Config
There are a few major changes
The first istargetRuntimeTo change the value ofMyBatis3Simple.defaultModelTypeSet toflat
iftargetRuntime="MyBatis3"
The resulting mapper.xml will have an extra piece of useless code like this
Then add the tk.mybatis plug-in
<plugin type="tk.mybatis.mapper.generator.MapperPlugin"> <! - the dao to inherit the interface - > < property name = "mappers" value = "tk.mybatis.mapper.com mon. Mapper" / > <! <property name="caseSensitive" value="true"/> </plugin>Copy the code
Nothing else needs to be changed. Once configured, run the MyBatis Generator plugin to generate the following file
po As you can see, the annotations generated by tk.mybatis are much simpler and easier to understand than those generated by MyBatis Generator. In addition, it has a few additional notes
- @table (name = “user”) : indicates that the Po corresponds to the user Table of the database
- @id: indicates the primary key of the user table
- @column (name = “user_name”) : indicates that the attribute corresponds to the user_name field of the user table
dao MyBatis Generator has fewer interfaces than the code generated by MyBatis Generator, but inherits one more class that you configure in the tk.mybatis pluginAs you might guess, the missing interfaces are all inherited from this onetk.mybatis.mapper.common.Mapper
In the class shown below, userMapper inherits so many methods that they can be used directly
mapper.xml Much less code than MyBatis Generator
The DAO path configured to scan on the startup class
This step was already configured when we integrated MyBatis
However, after integrating tk.mybatis, you need to use the tk.mybatis package@MapperScan
, so it needs to be modified@MapperScan
The package path
import tk.mybatis.spring.annotation.MapperScan;
Copy the code
Configure the universal Mapper
Mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity = mysql.identity Mapper. not-empty=trueCopy the code
Tk.mybatis is now fully integrated
1.5.3 Integrate the PageHelper paging plug-in
Paging query is a very common function in Web development, although Mybatis can also achieve paging, but that is based on memory paging, that is, to find out all the data at one time, and then put in memory for several times to return.
The PageHelper paging plug-in is physical paging and is implemented by SQL keywords. For example, limit in mysql, Rownum in Oracle, etc.
The PageHelper page plugin and tk.mybatis are all addresses of the PageHelper project written by the same author
Integrating PageHelper requires two steps
- Introduce the PageHelper dependency
- Configuration pagehelper
Introduce the PageHelper dependency
As usual, the parent POM defines the dependency version and declares the dependency
< the properties > < pagehelper - spring - the boot - starter. Version > 1.2.12 < / pagehelper - spring - the boot - starter. Version > < / properties >Copy the code
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
<version>${pagehelper-spring-boot-starter.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
Copy the code
Submodules introduce dependencies
<dependencies>
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper-spring-boot-starter</artifactId>
</dependency>
</dependencies>
Copy the code
Configuration pagehelper
Mysql > select * from pagehelperdialect where pagehelperdialect =mysql > select * from pagehelperdialect where pagehelperdialect =mysql > select * from pagehelperdialect where pageNum<1 If pageNum>pages does not support pagerhelper (' pagerhelper ', 'pagerhelper'). Reasonable =true # The default false. # pagehelper supportMethodsArguments = true pagehelper. Params = count = countSqlCopy the code
For more configurations, please refer to the official website
1.6.0 Introduces lombok
Lombok is a plug-in for simplifying code that generates get, set, toString, hash… Methods.
Integrating Lombok is simple
- Introduce lombok dependencies
- Install the Lombok plug-in for the IDE
See this article for the Lombok plugin to use Lombok
Introduce lombok dependencies
Since the Lombok dependency is already declared in spring-boot-starter-parent, we just need to introduce it in the submodule
<! --lombok--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>Copy the code
Install the Lombok plug-in for the IDE
I’m using IDEA, so take IDEA as an example
1.7.0 integrate redis
As the most commonly used NOSQL database, Spring Boot has excellent support for Redis and is easy to integrate in just four steps
- Introduction of depend on
- Configure redis
- Custom RedisTemplate (recommended)
- Custom Redis action classes (recommended)
Detailed integration steps I have written a separate article, address below
Spring Boot 2.0 integrates with Redis
1.7.1 Integrating Spring Cache
Spring Cache is a Spring solution for caching scenarios. Use @cacheput, @cacheevict, and @cacheable annotations to store, query, and delete the cache
Since we have introduced Redis, spring Cache can be used with a simple configuration
I wrote a separate article detailing the integration steps as follows (in the Spring Cache section)
Spring Boot 2.0 integrates with Redis
Of course, you can choose not to integrate
1.8.0 Develop user module
Different systems correspond to different user designs. Nuggets user system and Taobao user system are certainly different. Therefore, although this project is a seed project, it is difficult to give a general user module design.
So INSTEAD of going for a generic user module, I went for a module that incorporated all of the technologies.
In this way, in the future use of one of the above technologies, also have a reference.
The users table
Build predicative sentences inConfigure the mysqlThe chapter
Add controller, Service, and DTO
Create controller, Service, and DTO directories first
Start with the registered interface
Note that the verification parameter must be added@Valid
annotations
Among them@Data
The Lombok plug-in was used
The data store is a salty hash of the password, meaning that even we can’t see the user’s password
1.8.1 Customizing the Global Status Code and Service Result Classes
While there’s nothing wrong with returning success or failure, it’s not very elegant because other interfaces may not return simple strings.
In fact, we can customize a business result class, all the interfaces, return the business result object, this business result class, in addition to business results, business execution status, business messages, etc.
In addition to the business result class, I also suggest creating a global status code class. Just like the API interface of Ant Financial, a status code will be returned if the call fails, which is convenient for error detection
Custom global status code
Create an enums directory
Create the ApplicationEnum global status code class. I’ve only written a few here so you can add them later
Create the business result class
As follows, create the result directory under the VO directory and create the business result class in it
Create a SuccessResult and a FailResult for ease of use
Modify registration interface
1.8.2 Unified Exception Handling
It is a common requirement for all Web projects to deal with all kinds of exceptions that may occur during business execution. Spring provides @RestControllerAdvice, @ExceptionHandler annotations to help us handle exceptions.
There is no unified standard on how to design specific exception handling. Here is my design for reference only.
What I do is define a custom exception class, throw it when the business fails, and then handle it in a custom exception handling class.
For more information, see Unified Spring-based exception handling
Custom exception classes
Each exception applies to an ApplicationEnum
Custom exception handling classes
If an Exception can match more than one @ExceptionHandler, select the Exception with the least depth of matching (that is, the Exception that best matches).
Use custom exceptions
1.8.3 Parameter verification and exception handling
Parameter calibration
First append to the object to be verified@valid
annotations
Then use the appropriate annotations in the object you want to validate
Please refer to the details
Hibernate-Validator Spring parameter verification
Exception handling
If the parameter binding is unsuccessful or the validation fails, an exception will be thrown! But the exception thrown by default contains a lot of sensitive information, such as:Therefore, common exceptions should be captured and then encapsulated.
Extends ResponseEntityExceptionHandler is to rewrite a few common anomalies are handled by default. Of course, you can also directly through the @ ExceptionHandler intercept (), instead of extends ResponseEntityExceptionHandler
Handling these three exceptions generally covers most scenarios that require manual handling of parameter exceptions
- org.springframework.validation.BindException
- org.springframework.web.bind.MethodArgumentNotValidException
- javax.validation.ConstraintViolationException
Please refer to the details
Exception handling of Spring parameter verification
1.8.4 Adding interfaces for logging in, changing passwords, and obtaining user information
Mainly some business logic, no what refers to say, specific code reference project source code! The only thing that refers to lifting a mouth is use@Value("${}")
Annotations get attributes in the configuration file
1.8.5 Adding an Authentication Interceptor
Some interfaces we want to be accessible only to logged-in users, and the general solution is to add a logged-in interceptor.
The method is also very simple, mainly divided into 3 steps
- Define which interfaces require authentication (login to access) or which do not
- The custom
HandlerInterceptor
To intercept the interface before accessing it - The custom
WebMvcConfigurer
To define which interfaces need to be intercepted
1. Determine the authentication exempt URL
2. CustomHandlerInterceptor
To verify the token validity of intercepted requests
3. The customWebMvcConfigurer
Block all requests except the list of authentication-exempt urls
1.8.6 Unified Mapping User-defined configuration
Where did we need to use it beforeproperties
That’s where the configuration is used@Value("${}")
In order to get. The following
We can also create a custom configuration class that will allproperties
All the custom attributes are mapped to the corresponding attributes, as follows
Then when used, access the class directly
1.9.0 Configuring Logs
Spring Boot already has the logging system configured by default, but further configuration is required if you want to display SQL or export logs to files.
Please refer to the details
Logging framework in the Java ecosystem Java Logging implementation framework Logback Logback Configuration example Spring Boot Logging
According to the SQL
Configure it in application.properties
# the dao (com) WQLM) boot. User. Dao) to display the SQL logging.level.com.wqlm.boot.user.dao=debug layer set the debug levelCopy the code
Output logs to files
Configure it in application.properties
Loging.file.name =logs/user/user.log # Maximum number of days to keep logs logging.file.max-history=30 # Maximum size of a single log file logging.file.max-size=10MBCopy the code
Fine configuration
There is only a limited amount of configuration that can be done in application.properties, and if you want to go further, you need to use the corresponding logging framework configuration file!
Spring Boot uses Logback as the logging implementation framework, and it is recommended that logback-spring. XML be used as the name of the configuration file.
The following is a reference configuration example
<! -- scan: enable "hot update" scanPeriod: enable "hot update" scan period: 60 seconds -->
<configuration scan="true" scanPeriod="300 seconds">
<! -- Add color converter -->
<conversionRule conversionWord="clr" converterClass="org.springframework.boot.logging.logback.ColorConverter"/>
<! Source: which attribute to use defaultValue: defaultValue if not found -->
<springProperty name="env" scope="context" source="spring.profiles.active" defaultValue="env"/>
<! -- Application name -->
<property name="APP_NAME" value="user"/>
<! -- Custom variable used to configure the log output format, which is as close as possible to the spring Boot default output style %date: Date, default format YYYY-MM-DD HHH: MM: SS,SSS default to use the local time zone, defined by % D {YYYY-MM-DD HHH: MM: SS,SSS} %-5level: Log levels with five placeholders, such as "info" and "error" % Thread: log output thread %class: fully qualified name of the log output class, inefficient %method: method name of the log output %line: line number of the log output, inefficient % MSG: Log message content %n: newline -->
<property name="LOG_PATTERN" value="%date %-5level ${PID:- } --- [%thread] %class.%method/%line : %msg%n"/>
<! -- Color log format -->
<property name="LOG_PATTERN_COLOUR"
value="${env} %date %clr(%-5level) %magenta(${PID:- }) --- [%thread] %cyan(%class.%method/%line) : %msg%n"/>
<! - log output. Ch. Qos. Logback. Core. The ConsoleAppender: output to the console - >
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<! -- Configure log output format -->
<pattern>${LOG_PATTERN_COLOUR}</pattern>
<! Character set -->
<charset>UTF-8</charset>
</encoder>
</appender>
<! -- Log output. Ch. Qos. Logback. Core. Rolling. The RollingFileAppender: rolling output to file - >
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<! Active log file names (absolute and relative paths supported) -->
<file>logs/${APP_NAME}/${APP_NAME}.log</file>
<! - rolling strategy. Ch. Qos. Logback. Core. Rolling. SizeAndTimeBasedRollingPolicy: according to the size and time rolling -- >
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<! When to trigger scrolling, how to scroll, and the naming format of the scrolling file %d: date, default format YYYY-MM-DD, custom format %d{YYYY-MM-dd HHH: MM :ss} % I: indicates the sequence number of the log file within a single scrolling period. Zip: compresses the log file into a ZIP. Logs /app1/backup will be stored in a zip package named app1_%d_% I.ZIP --> after the first log request after 0 o 'clock every day.
<fileNamePattern>logs/${APP_NAME}/backup/${APP_NAME}_%d{yyyy-MM-dd}_%i.zip</fileNamePattern>
<! Maximum size of a single log file -->
<maxFileSize>10MB</maxFileSize>
<! Delete log files from n scroll cycles (at most, keep history of the first n scroll cycles)-->
<maxHistory>30</maxHistory>
<! MaxHistory limits the total size of all log files, and deletes them from the oldest log file.
<totalSizeCap>1GB</totalSizeCap>
</rollingPolicy>
<encoder>
<! -- Log output format -->
<pattern>${LOG_PATTERN}</pattern>
<! Character set -->
<charset>UTF-8</charset>
</encoder>
</appender>
<! -- Use the following configuration for non-PROD environments -->
<springProfile name=! "" prod">
<! -- logger name: package name or class name, level: start log level, additivity: whether to append the appender of the parent class -->
<logger name="com.wqlm.boot.dao" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLING"/>
</logger>
</springProfile>
<! -- root logger -->
<root level="info">
<! -- STDOUT, ROLLING --
<appender-ref ref="STDOUT"/>
<appender-ref ref="ROLLING"/>
</root>
</configuration>
Copy the code
Relative path position