基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程


前言

在我们在进行微服务或者模块化开发的时候,每次都要不断的创建工程,然后管理模块,创建工程,然后管理模块...... 每个人的项目结构可能不一样。因此我就把我自己平常喜欢的项目结构稍微总结了一下,做成一个脚手架。这样以后创建工程的时候直接参考本文即可。这里强调一下:本文只是个人总结的项目创建的套路,没有任何标准,意在快速开发。你也可以自己总结一下,纯属个人喜好。

本文的脚手架是基于SpirngBoot2.x框架,自己定义dependencis的pom做统一的依赖管理,ORM框架采用的是tkMapper。这样的好处是,依赖版本升级或者变更的时候,只需要在dependencis中管理就好;而tkMapper配合MybatisCodeHelperNewPro插件可以在任意的模块生成(单表或者多表的)pojomappermapper.xml等。

废话不多说,下面开始先看下整体的结构。

1. 结构预览

我们以一个商城的项目为例,快速创建它的工程结构:

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

2. 开始搭建

父工程POM

返回顶部↑

  • 1)、第一步,先在自己的工作目录下面创建一个空文件夹,作为父工程。

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

  • 2)、用idea开发工具open打开此目录。

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

  • 3)、创建pom.xml,把下面配置复制粘贴进去。
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>com.zxx.shop</groupId>
    <artifactId>parent</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <url></url>

    <modules>
        <module>dependencies</module>
        <module>shop-pojo</module>
        <module>shop-api</module>
        <module>shop-common</module>
        <module>shop-user-service</module>
        <module>shop-goods-service</module>
        <module>shop-coupon-service</module>
        <module>shop-order-service</module>
        <module>shop-pay-service</module>
        <module>shop-order-web</module>
        <module>shop-pay-web</module>
    </modules>

    <properties>
        <java.version>1.8</java.version>
        <maven.compiler.source>${java.version}</maven.compiler.source>
        <maven.compiler.target>${java.version}</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
    </properties>

    <licenses>
        <license>
            <name>Apache 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <developers>
        <developer>
            <id>mcl2rock</id>
            <name>mcl2rock</name>
            <email>mcl2rock@yeah.net</email>
        </developer>
    </developers>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>com.zxx.shop</groupId>
                <artifactId>dependencies</artifactId>
                <version>${project.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <profiles>
        <profile>
            <id>default</id>
            <activation>
                <activeByDefault>true</activeByDefault>
            </activation>
            <properties>
                <spring-javaformat.version>0.0.12</spring-javaformat.version>
            </properties>
            <build>
                <plugins>
                    <plugin>
                        <groupId>io.spring.javaformat</groupId>
                        <artifactId>spring-javaformat-maven-plugin</artifactId>
                        <version>${spring-javaformat.version}</version>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-surefire-plugin</artifactId>
                        <configuration>
                            <!-- 设置默认跳过测试 -->
                            <skip>true</skip>
                            <includes>
                                <include>**/*Tests.java</include>
                            </includes>
                            <excludes>
                                <exclude>**/Abstract*.java</exclude>
                            </excludes>
                            <systemPropertyVariables>
                                <java.security.egd>file:/dev/./urandom</java.security.egd>
                                <java.awt.headless>true</java.awt.headless>
                            </systemPropertyVariables>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-enforcer-plugin</artifactId>
                        <executions>
                            <execution>
                                <id>enforce-rules</id>
                                <goals>
                                    <goal>enforce</goal>
                                </goals>
                                <configuration>
                                    <rules>
                                        <bannedDependencies>
                                            <excludes>
                                                <exclude>commons-logging:*:*</exclude>
                                            </excludes>
                                            <searchTransitive>true</searchTransitive>
                                        </bannedDependencies>
                                    </rules>
                                    <fail>true</fail>
                                </configuration>
                            </execution>
                        </executions>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-install-plugin</artifactId>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                    </plugin>
                    <plugin>
                        <groupId>org.apache.maven.plugins</groupId>
                        <artifactId>maven-javadoc-plugin</artifactId>
                        <configuration>
                            <skip>true</skip>
                        </configuration>
                        <inherited>true</inherited>
                    </plugin>
                </plugins>
            </build>
        </profile>
    </profiles>

    <repositories>
        <repository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

.gitattributes文件

返回顶部↑

# Windows-specific files that require CRLF:
*.bat       eol=crlf
*.txt       eol=crlf

# Unix-specific files that require LF:
*.java      eol=lf
*.sh        eol=lf

.gitignore文件

返回顶部↑

target/
!.mvn/wrapper/maven-wrapper.jar

## STS ##
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans

## IntelliJ IDEA ##
.idea
*.iws
*.iml
*.ipr

## JRebel ##
rebel.xml

## MAC ##
.DS_Store

## Other ##
logs/
temp/

LICENSE文件

返回顶部↑

                              Apache License
                        Version 2.0, January 2004
                     http://www.apache.org/licenses/

TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

1. Definitions.

   "License" shall mean the terms and conditions for use, reproduction,
   and distribution as defined by Sections 1 through 9 of this document.

   "Licensor" shall mean the copyright owner or entity authorized by
   the copyright owner that is granting the License.

   "Legal Entity" shall mean the union of the acting entity and all
   other entities that control, are controlled by, or are under common
   control with that entity. For the purposes of this definition,
   "control" means (i) the power, direct or indirect, to cause the
   direction or management of such entity, whether by contract or
   otherwise, or (ii) ownership of fifty percent (50%) or more of the
   outstanding shares, or (iii) beneficial ownership of such entity.

   "You" (or "Your") shall mean an individual or Legal Entity
   exercising permissions granted by this License.

   "Source" form shall mean the preferred form for making modifications,
   including but not limited to software source code, documentation
   source, and configuration files.

   "Object" form shall mean any form resulting from mechanical
   transformation or translation of a Source form, including but
   not limited to compiled object code, generated documentation,
   and conversions to other media types.

   "Work" shall mean the work of authorship, whether in Source or
   Object form, made available under the License, as indicated by a
   copyright notice that is included in or attached to the work
   (an example is provided in the Appendix below).

   "Derivative Works" shall mean any work, whether in Source or Object
   form, that is based on (or derived from) the Work and for which the
   editorial revisions, annotations, elaborations, or other modifications
   represent, as a whole, an original work of authorship. For the purposes
   of this License, Derivative Works shall not include works that remain
   separable from, or merely link (or bind by name) to the interfaces of,
   the Work and Derivative Works thereof.

   "Contribution" shall mean any work of authorship, including
   the original version of the Work and any modifications or additions
   to that Work or Derivative Works thereof, that is intentionally
   submitted to Licensor for inclusion in the Work by the copyright owner
   or by an individual or Legal Entity authorized to submit on behalf of
   the copyright owner. For the purposes of this definition, "submitted"
   means any form of electronic, verbal, or written communication sent
   to the Licensor or its representatives, including but not limited to
   communication on electronic mailing lists, source code control systems,
   and issue tracking systems that are managed by, or on behalf of, the
   Licensor for the purpose of discussing and improving the Work, but
   excluding communication that is conspicuously marked or otherwise
   designated in writing by the copyright owner as "Not a Contribution."

   "Contributor" shall mean Licensor and any individual or Legal Entity
   on behalf of whom a Contribution has been received by Licensor and
   subsequently incorporated within the Work.

2. Grant of Copyright License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   copyright license to reproduce, prepare Derivative Works of,
   publicly display, publicly perform, sublicense, and distribute the
   Work and such Derivative Works in Source or Object form.

3. Grant of Patent License. Subject to the terms and conditions of
   this License, each Contributor hereby grants to You a perpetual,
   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
   (except as stated in this section) patent license to make, have made,
   use, offer to sell, sell, import, and otherwise transfer the Work,
   where such license applies only to those patent claims licensable
   by such Contributor that are necessarily infringed by their
   Contribution(s) alone or by combination of their Contribution(s)
   with the Work to which such Contribution(s) was submitted. If You
   institute patent litigation against any entity (including a
   cross-claim or counterclaim in a lawsuit) alleging that the Work
   or a Contribution incorporated within the Work constitutes direct
   or contributory patent infringement, then any patent licenses
   granted to You under this License for that Work shall terminate
   as of the date such litigation is filed.

4. Redistribution. You may reproduce and distribute copies of the
   Work or Derivative Works thereof in any medium, with or without
   modifications, and in Source or Object form, provided that You
   meet the following conditions:

   (a) You must give any other recipients of the Work or
       Derivative Works a copy of this License; and

   (b) You must cause any modified files to carry prominent notices
       stating that You changed the files; and

   (c) You must retain, in the Source form of any Derivative Works
       that You distribute, all copyright, patent, trademark, and
       attribution notices from the Source form of the Work,
       excluding those notices that do not pertain to any part of
       the Derivative Works; and

   (d) If the Work includes a "NOTICE" text file as part of its
       distribution, then any Derivative Works that You distribute must
       include a readable copy of the attribution notices contained
       within such NOTICE file, excluding those notices that do not
       pertain to any part of the Derivative Works, in at least one
       of the following places: within a NOTICE text file distributed
       as part of the Derivative Works; within the Source form or
       documentation, if provided along with the Derivative Works; or,
       within a display generated by the Derivative Works, if and
       wherever such third-party notices normally appear. The contents
       of the NOTICE file are for informational purposes only and
       do not modify the License. You may add Your own attribution
       notices within Derivative Works that You distribute, alongside
       or as an addendum to the NOTICE text from the Work, provided
       that such additional attribution notices cannot be construed
       as modifying the License.

   You may add Your own copyright statement to Your modifications and
   may provide additional or different license terms and conditions
   for use, reproduction, or distribution of Your modifications, or
   for any such Derivative Works as a whole, provided Your use,
   reproduction, and distribution of the Work otherwise complies with
   the conditions stated in this License.

5. Submission of Contributions. Unless You explicitly state otherwise,
   any Contribution intentionally submitted for inclusion in the Work
   by You to the Licensor shall be under the terms and conditions of
   this License, without any additional terms or conditions.
   Notwithstanding the above, nothing herein shall supersede or modify
   the terms of any separate license agreement you may have executed
   with Licensor regarding such Contributions.

6. Trademarks. This License does not grant permission to use the trade
   names, trademarks, service marks, or product names of the Licensor,
   except as required for reasonable and customary use in describing the
   origin of the Work and reproducing the content of the NOTICE file.

7. Disclaimer of Warranty. Unless required by applicable law or
   agreed to in writing, Licensor provides the Work (and each
   Contributor provides its Contributions) on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
   implied, including, without limitation, any warranties or conditions
   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
   PARTICULAR PURPOSE. You are solely responsible for determining the
   appropriateness of using or redistributing the Work and assume any
   risks associated with Your exercise of permissions under this License.

8. Limitation of Liability. In no event and under no legal theory,
   whether in tort (including negligence), contract, or otherwise,
   unless required by applicable law (such as deliberate and grossly
   negligent acts) or agreed to in writing, shall any Contributor be
   liable to You for damages, including any direct, indirect, special,
   incidental, or consequential damages of any character arising as a
   result of this License or out of the use or inability to use the
   Work (including but not limited to damages for loss of goodwill,
   work stoppage, computer failure or malfunction, or any and all
   other commercial damages or losses), even if such Contributor
   has been advised of the possibility of such damages.

9. Accepting Warranty or Additional Liability. While redistributing
   the Work or Derivative Works thereof, You may choose to offer,
   and charge a fee for, acceptance of support, warranty, indemnity,
   or other liability obligations and/or rights consistent with this
   License. However, in accepting such obligations, You may act only
   on Your own behalf and on Your sole responsibility, not on behalf
   of any other Contributor, and only if You agree to indemnify,
   defend, and hold each Contributor harmless for any liability
   incurred by, or claims asserted against, such Contributor by reason
   of your accepting any such warranty or additional liability.

END OF TERMS AND CONDITIONS

APPENDIX: How to apply the Apache License to your work.

   To apply the Apache License to your work, attach the following
   boilerplate notice, with the fields enclosed by brackets "[]"
   replaced with your own identifying information. (Don‘t include
   the brackets!)  The text should be enclosed in the appropriate
   comment syntax for the file format. We also recommend that a
   file or class name and description of purpose be included on the
   same "printed page" as the copyright notice for easier
   identification within third-party archives.

Copyright [yyyy] [name of copyright owner]

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.

目前工程是这个样子:

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

接着,在pom.xml上右键,Add Maven Project,然后在右边的侧边工具栏中用maven可以看到父工程parent爆红,我们reimport一下。

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

依赖导入完之后,子模块爆红:

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

我们用idea快捷键 alt + enter 创建子模块。

这些子模块是自己定义的,我们可以根据自己的项目需求新建和更改,这里的子模块只是用来样例演示的。

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

dependencies工程POM

返回顶部↑

全部解决爆红之后,我们再管理统一的依赖版本。复制以下代码到dependencies模块的pom.xml里。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.zxx.shop</groupId>
    <artifactId>dependencies</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <url></url>

    <properties>
        <!-- Commons -->
        <okhttp3.version>4.0.1</okhttp3.version>
        <feign-okhttp.version>10.2.3</feign-okhttp.version>
        <mybatis-plus-boot.version>3.1.1</mybatis-plus-boot.version>
        <springfox-swagger2.version>2.9.2</springfox-swagger2.version>
        <swagger-bootstrap-ui.version>1.8.7</swagger-bootstrap-ui.version>
        <fastjson.version>1.2.56</fastjson.version>
        <easypoi.version>3.2.0</easypoi.version>
        <spring-boot-mapper.version>2.1.5</spring-boot-mapper.version>

        <!-- Native Cloud -->
        <dubbo.version>2.7.2</dubbo.version>
        <dubbo-kryo.version>2.7.2</dubbo-kryo.version>
        <dubbo-actuator.version>2.7.1</dubbo-actuator.version>
        <spring-boot-mapper.version>2.1.5</spring-boot-mapper.version>
        <spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
        <spring-cloud-alibaba.verion>0.9.0.RELEASE</spring-cloud-alibaba.verion>
        <alibaba-spring-context-support.version>1.0.2</alibaba-spring-context-support.version>
    </properties>

    <licenses>
        <license>
            <name>Apache 2.0</name>
            <url>https://www.apache.org/licenses/LICENSE-2.0.txt</url>
        </license>
    </licenses>

    <developers>
        <developer>
            <id>mcl2rock</id>
            <name>mcl2rock</name>
            <email>mcl2rock@yeah.net</email>
        </developer>
    </developers>

    <dependencyManagement>
        <dependencies>
            <!-- Spring Cloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                <version>${spring-cloud-alibaba.verion}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>

            <!-- Apache Dubbo -->
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo</artifactId>
                <version>${dubbo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>org.springframework</groupId>
                        <artifactId>spring</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>javax.servlet</groupId>
                        <artifactId>servlet-api</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-spring-boot-actuator</artifactId>
                <version>${dubbo-actuator.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.dubbo</groupId>
                <artifactId>dubbo-serialization-kryo</artifactId>
                <version>${dubbo-kryo.version}</version>
                <exclusions>
                    <exclusion>
                        <groupId>log4j</groupId>
                        <artifactId>log4j</artifactId>
                    </exclusion>
                    <exclusion>
                        <groupId>org.apache.dubbo</groupId>
                        <artifactId>dubbo-common</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>com.alibaba.spring</groupId>
                <artifactId>spring-context-support</artifactId>
                <version>${alibaba-spring-context-support.version}</version>
            </dependency>

            <!-- Commons -->
            <dependency>
                <groupId>com.squareup.okhttp3</groupId>
                <artifactId>okhttp</artifactId>
                <version>${okhttp3.version}</version>
            </dependency>
            <dependency>
                <groupId>io.github.openfeign</groupId>
                <artifactId>feign-okhttp</artifactId>
                <version>${feign-okhttp.version}</version>
            </dependency>
            <!-- 数据库 -->
            <dependency>
                <groupId>com.zaxxer</groupId>
                <artifactId>HikariCP</artifactId>
                <version>${hikaricp.version}</version>
            </dependency>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-jdbc</artifactId>
                <exclusions>
                    <!-- 排除 tomcat-jdbc 以使用 HikariCP -->
                    <exclusion>
                        <groupId>org.apache.tomcat</groupId>
                        <artifactId>tomcat-jdbc</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <!--mybatis-plus-->
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-boot-starter</artifactId>
                <version>${mybatis-plus-boot.version}</version>
            </dependency>
            <dependency>
                <groupId>com.baomidou</groupId>
                <artifactId>mybatis-plus-generator</artifactId>
                <version>${mybatis-plus-boot.version}</version>
            </dependency>
            
            <!--tk-mapper-->
            <dependency>
                <groupId>tk.mybatis</groupId>
                <artifactId>mapper-spring-boot-starter</artifactId>
                <version>${spring-boot-mapper.version}</version>
            </dependency>

            <!-- Lombok -->
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
            </dependency>

            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>fastjson</artifactId>
                <version>${fastjson.version}</version>
            </dependency>

            <!--代码生成器所需模板引擎-->
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-freemarker</artifactId>
            </dependency>

            <!--swagger-->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
                <version>${springfox-swagger2.version}</version>
            </dependency>
            <dependency>
                <groupId>com.github.xiaoymin</groupId>
                <artifactId>swagger-bootstrap-ui</artifactId>
                <version>${swagger-bootstrap-ui.version}</version>
            </dependency>

            <!-- excel -->
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-base</artifactId>
                <version>${easypoi.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-web</artifactId>
                <version>${easypoi.version}</version>
            </dependency>
            <dependency>
                <groupId>cn.afterturn</groupId>
                <artifactId>easypoi-annotation</artifactId>
                <version>${easypoi.version}</version>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <repositories>
        <repository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </repository>
        <repository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <pluginRepositories>
        <pluginRepository>
            <id>spring-milestone</id>
            <name>Spring Milestone</name>
            <url>https://repo.spring.io/milestone</url>
            <snapshots>
                <enabled>false</enabled>
            </snapshots>
        </pluginRepository>
        <pluginRepository>
            <id>spring-snapshot</id>
            <name>Spring Snapshot</name>
            <url>https://repo.spring.io/snapshot</url>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </pluginRepository>
    </pluginRepositories>
</project>

shop-common工程代码生成

common模块是用来放一些项目通用的类。复制下面的配置到pom.xml里。

POM文件

返回顶部↑

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>com.zxx.shop</groupId>
        <artifactId>parent</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <artifactId>shop-common</artifactId>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-tomcat</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- tk-mapper-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>

        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-annotations</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.squareup.okhttp3</groupId>
            <artifactId>okhttp</artifactId>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>com.fasterxml.jackson.core</groupId>
            <artifactId>jackson-databind</artifactId>
            <scope>provided</scope>
        </dependency>

        <!-- excel -->
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-base</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-web</artifactId>
        </dependency>
        <dependency>
            <groupId>cn.afterturn</groupId>
            <artifactId>easypoi-annotation</artifactId>
        </dependency>


    </dependencies>

</project>

tk.mybatis.mapper

MyMapper.java

返回顶部↑

package tk.mybatis.mapper;

import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;

/**
 * 特别注意,该接口不能被扫描到,否则会出错
 */
public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
}

com.zxx.entity

BaseResult.java

返回顶部↑

package com.zxx.entity;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.zxx.constant.ResultCode;

import java.io.Serializable;

/**
 * 返回数据
 */
public class BaseResult<T> implements Serializable {
    private static final long serialVersionUID = 1L;

    private boolean success;//是否成功
    private Integer code;
    private String message;
    @JsonInclude(value = JsonInclude.Include.NON_DEFAULT)
    private T data;


    public static BaseResult ok() {
        return BaseResult.back(ResultCode.SUCCESS);
    }

    public static BaseResult ok(String msg) {
        return new BaseResult(true, ResultCode.SUCCESS.getCode(), msg, null);
    }

    public static BaseResult fail() {
        return BaseResult.back(ResultCode.FAIL);
    }

    public static BaseResult fail(String msg) {
        return new BaseResult(false, ResultCode.FAIL.getCode(), msg, null);
    }

    public static BaseResult error() {
        return BaseResult.back(ResultCode.SERVER_ERROR);
    }


    public static BaseResult back(ResultCode r) {
        return new BaseResult(r.getSuccess(), r.getCode(), r.getMessage(), null);
    }

    public BaseResult<T> put(T t) {
        this.data = t;
        return this;
    }

    public BaseResult(boolean success, Integer code, String message, T data) {
        this.success = success;
        this.code = code;
        this.message = message;
        this.data = data;
    }

    public BaseResult() { }


    public boolean isSuccess() {
        return success;
    }

    public void setSuccess(boolean success) {
        this.success = success;
    }

    public Integer getCode() {
        return code;
    }

    public void setCode(Integer code) {
        this.code = code;
    }

    public String getMessage() {
        return message;
    }

    public void setMessage(String message) {
        this.message = message;
    }

    public T getData() {
        return data;
    }

    public void setData(T data) {
        this.data = data;
    }
}

com.zxx.exception

BaseException.java

返回顶部↑

package com.zxx.exception;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.zxx.constant.ResultCode;
import lombok.Data;

@Data
@JsonInclude(value = JsonInclude.Include.NON_DEFAULT)
public class BaseException extends RuntimeException {

    private static final long serialVersionUID = -7638041501183925225L;

    private String code;
    private String exceptionInfo;
    private Integer debugId;

    public BaseException(String code, String msg) {
        super(msg);
        this.code = code;
        this.exceptionInfo = msg;
    }

    public BaseException(String errorCode) {
        super(errorCode.toString());
    }

    public BaseException(ResultCode resultCode) {
        this(Integer.toString(resultCode.getCode()), resultCode.getMessage());
    }

    public BaseException(ResultCode resultCode, String msg) {
        this(Integer.toString(resultCode.getCode()), msg);
    }

    public BaseException(String exceptionInfo, Integer debugId, Object data) {
        super(exceptionInfo);
        this.exceptionInfo = exceptionInfo;
        this.debugId = debugId;
    }


}

Exceptions.java

返回顶部↑

package com.zxx.exception;

import com.zxx.constant.ResultCode;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class Exceptions {

    public static void newException(String msg){
        log.error(msg);
        throw new BaseException(msg);
    }

    public static void castException(ResultCode resultCode){
        log.error(resultCode.toString());
        throw new BaseException(resultCode);
    }
}

com.zxx.utils

AssertUtil.java

返回顶部↑

package com.zxx.utils;

import com.zxx.constant.ResultCode;
import com.zxx.exception.BaseException;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Collection;

public class AssertUtil {

    public static void throwException(String message) throws BaseException {
        throw new BaseException(ResultCode.FAIL, message);
    }

    public static void throwException(String code, String message) throws BaseException {
        throw new BaseException(code, message);
    }

    public static void isTrue(boolean expression, String message) {
        if (!expression) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void isFalse(boolean expression, String message) {
        if (expression) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void isNull(Object object, String message) throws BaseException {
        if (object != null) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void notNull(Object object, String message) throws BaseException {
        if (object == null) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void isEmpty(String str, String message) throws BaseException {
        if (str == null || ! str.isEmpty()) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void notEmpty(String str, String message) throws BaseException {
        if (str == null || str.isEmpty()) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void notEmpty(Object[] array, String message) throws BaseException {
        if (ObjectUtils.isEmpty(array)) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void notEmpty(Collection<?> collection, String message) throws BaseException {
        if (CollectionUtils.isEmpty(collection)) {
            throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void in(Object[] collection, Object value, String message) throws BaseException {
        for(Object obj : collection){
            if(obj.equals(value)){
                return;
            }
        }
        throw new BaseException(ResultCode.FAIL, message);
    }

    public static void noNullElements(Object[] array, String message) throws BaseException {
        if (array != null) {
            for (Object element : array) {
                if (element == null) {
                    throw new BaseException(ResultCode.FAIL, message);
                }
            }
        }
    }
    public static void nullOrGtMinusOne(Number number, String message) {
        if (number != null && number.intValue() < -1) {
              throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void GtZero(Number number, String message) {
        if ( number == null || number.intValue() < 1 ) {
              throw new BaseException(ResultCode.FAIL, message);
        }
    }

    public static void isSimpleDateFormat(String date, String message){
    	if(date == null || "null".equals(date.toLowerCase()) || date.length() != 10){
            throw new BaseException(ResultCode.FAIL, message);
    	}
    	SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
    	try {
			format.parse(date);
		} catch (ParseException e) {
            throw new BaseException(ResultCode.FAIL, message);
		}
    }

}

JacksonUtil.java

返回顶部↑

package com.zxx.utils;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Jackson 工具类
 */
public class JacksonUtil {
    private final static ObjectMapper objectMapper = new ObjectMapper();

    public static ObjectMapper getInstance() {
        return objectMapper;
    }

    /**
     * 转换为 JSON 字符串
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2json(Object obj) throws Exception {
        return objectMapper.writeValueAsString(obj);
    }

    /**
     * 转换为 JSON 字符串,忽略空值
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static String obj2jsonIgnoreNull(Object obj) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.writeValueAsString(obj);
    }

    /**
     * obj 转换为 Map 字符串,忽略空值
     *
     * @param obj
     * @return
     * @throws Exception
     */
    public static Map<String, Object> obj2mapIgnoreNull(Object obj) throws Exception {
        return json2map(obj2jsonIgnoreNull(obj));
    }

    /**
     * 转换为 JavaBean
     *
     * @param jsonString
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T json2pojo(String jsonString, Class<T> clazz) throws Exception {
        objectMapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true);
        return objectMapper.readValue(jsonString, clazz);
    }

    /**
     * 字符串转换为 Map<String, Object>
     *
     * @param jsonString
     * @return
     * @throws Exception
     */
    public static <T> Map<String, Object> json2map(String jsonString) throws Exception {
        ObjectMapper mapper = new ObjectMapper();
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
        return mapper.readValue(jsonString, Map.class);
    }

    /**
     * 字符串转换为 Map<String, T>
     */
    public static <T> Map<String, T> json2map(String jsonString, Class<T> clazz) throws Exception {
        Map<String, Map<String, Object>> map = objectMapper.readValue(jsonString, new TypeReference<Map<String, T>>() {
        });
        Map<String, T> result = new HashMap<String, T>();
        for (Map.Entry<String, Map<String, Object>> entry : map.entrySet()) {
            result.put(entry.getKey(), map2pojo(entry.getValue(), clazz));
        }
        return result;
    }

    /**
     * 深度转换 JSON 成 Map
     *
     * @param json
     * @return
     */
    public static Map<String, Object> json2mapDeeply(String json) throws Exception {
        return json2MapRecursion(json, objectMapper);
    }

    /**
     * 把 JSON 解析成 List,如果 List 内部的元素存在 jsonString,继续解析
     *
     * @param json
     * @param mapper 解析工具
     * @return
     * @throws Exception
     */
    private static List<Object> json2ListRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        }

        List<Object> list = mapper.readValue(json, List.class);

        for (Object obj : list) {
            if (obj != null && obj instanceof String) {
                String str = (String) obj;
                if (str.startsWith("[")) {
                    obj = json2ListRecursion(str, mapper);
                } else if (obj.toString().startsWith("{")) {
                    obj = json2MapRecursion(str, mapper);
                }
            }
        }

        return list;
    }

    /**
     * 把 JSON 解析成 Map,如果 Map 内部的 Value 存在 jsonString,继续解析
     *
     * @param json
     * @param mapper
     * @return
     * @throws Exception
     */
    private static Map<String, Object> json2MapRecursion(String json, ObjectMapper mapper) throws Exception {
        if (json == null) {
            return null;
        }

        Map<String, Object> map = mapper.readValue(json, Map.class);

        for (Map.Entry<String, Object> entry : map.entrySet()) {
            Object obj = entry.getValue();
            if (obj != null && obj instanceof String) {
                String str = ((String) obj);

                if (str.startsWith("[")) {
                    List<?> list = json2ListRecursion(str, mapper);
                    map.put(entry.getKey(), list);
                } else if (str.startsWith("{")) {
                    Map<String, Object> mapRecursion = json2MapRecursion(str, mapper);
                    map.put(entry.getKey(), mapRecursion);
                }
            }
        }

        return map;
    }

    /**
     * 将 JSON 数组转换为集合
     *
     * @param jsonArrayStr
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> List<T> json2list(String jsonArrayStr, Class<T> clazz) throws Exception {
        JavaType javaType = getCollectionType(ArrayList.class, clazz);
        List<T> list = (List<T>) objectMapper.readValue(jsonArrayStr, javaType);
        return list;
    }


    /**
     * 获取泛型的 Collection Type
     *
     * @param collectionClass 泛型的Collection
     * @param elementClasses  元素类
     * @return JavaType Java类型
     * @since 1.0
     */
    public static JavaType getCollectionType(Class<?> collectionClass, Class<?>... elementClasses) {
        return objectMapper.getTypeFactory().constructParametricType(collectionClass, elementClasses);
    }

    /**
     * 将 Map 转换为 JavaBean
     *
     * @param map
     * @param clazz
     * @return
     */
    public static <T> T map2pojo(Map map, Class<T> clazz) {
        return objectMapper.convertValue(map, clazz);
    }

    /**
     * 将 Map 转换为 JSON
     *
     * @param map
     * @return
     */
    public static String mapToJson(Map map) {
        try {
            return objectMapper.writeValueAsString(map);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return "";
    }

    /**
     * 将 JSON 对象转换为 JavaBean
     *
     * @param obj
     * @param clazz
     * @return
     */
    public static <T> T obj2pojo(Object obj, Class<T> clazz) {
        return objectMapper.convertValue(obj, clazz);
    }

    /**
     * 将指定节点的 JSON 数据转换为 JavaBean
     *
     * @param jsonString
     * @param clazz
     * @return
     * @throws Exception
     */
    public static <T> T json2pojoByTree(String jsonString, String treeNode, Class<T> clazz) throws Exception {
        JsonNode jsonNode = objectMapper.readTree(jsonString);
        JsonNode data = jsonNode.findPath(treeNode);
        return json2pojo(data.toString(), clazz);
    }

    /**
     * 将指定节点的 JSON 数组转换为集合
     *
     * @param jsonStr  JSON 字符串
     * @param treeNode 查找 JSON 中的节点
     * @return
     * @throws Exception
     */
    public static <T> List<T> json2listByTree(String jsonStr, String treeNode, Class<T> clazz) throws Exception {
        JsonNode jsonNode = objectMapper.readTree(jsonStr);
        JsonNode data = jsonNode.findPath(treeNode);
        return json2list(data.toString(), clazz);
    }
}

ResponseUtils.java

返回顶部↑

package com.zxx.utils;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.serializer.SerializerFeature;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletResponse;
import java.io.PrintWriter;

/**
 * @description:返回前台
 */
@Slf4j
public class ResponseUtils {

    public static void write(ServletResponse response, Object o) {
        try {
            response.setContentType("application/json; charset=utf-8");
            PrintWriter out = response.getWriter();
            //json返回
            out.println(JSON.toJSONString(o, SerializerFeature.WriteMapNullValue));
            out.flush();
            out.close();
        } catch (Exception e) {
            log.error("e={}", e);
        }
    }
}

ValidateUtil.java

返回顶部↑

package com.zxx.utils;

import org.apache.commons.lang3.StringUtils;

import java.util.regex.Pattern;

/**
 * 常用的一些验证,如手机、移动号码、联通号码、电信号码、密码、座机、 邮政编码、邮箱、年龄、身份证、URL、QQ、汉字、字母、数字等
 */
public class ValidateUtil {

    /** 手机号规则  */
    public static final String MOBILE_PATTERN="^((13[0-9])|(14[0-9])|(15[0-9])|(17[0-9])|(18[0-9]))(\\d{8})$";
    /** 中国电信号码格式验证 手机段: 133,153,180,181,189,177,1700,173  **/
    private static final String CHINA_TELECOM_PATTERN = "(?:^(?:\\+86)?1(?:33|53|7[37]|8[019])\\d{8}$)|(?:^(?:\\+86)?1700\\d{7}$)";
    /** 中国联通号码格式验证 手机段:130,131,132,155,156,185,186,145,176,1707,1708,1709,175 **/
    private static final String CHINA_UNICOM_PATTERN = "(?:^(?:\\+86)?1(?:3[0-2]|4[5]|5[56]|7[56]|8[56])\\d{8}$)|(?:^(?:\\+86)?170[7-9]\\d{7}$)";
    /** 中国移动号码格式验证 手机段:134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705 **/
    private static final String CHINA_MOVE_PATTERN = "(?:^(?:\\+86)?1(?:3[4-9]|4[7]|5[0-27-9]|7[8]|8[2-478])\\d{8}$)|(?:^(?:\\+86)?1705\\d{7}$)";
    /** 密码规则(6-16位字母、数字) */
    public static final String PASSWORD_PATTERN="^[0-9A-Za-z]{6,16}$";
    /** 固号(座机)规则 */
    public static final String LANDLINE_PATTERN="^(?:\\(\\d{3,4}\\)|\\d{3,4}-)?\\d{7,8}(?:-\\d{1,4})?$";
    /** 邮政编码规则 */
    public static final String POSTCODE_PATTERN = "[1-9]\\d{5}" ;
    /** 邮箱规则 */
    public static final String EMAIL_PATTERN = "^([a-z0-9A-Z]+[-|_|\\.]?)+[a-z0-9A-Z]@([a-z0-9A-Z]+(-[a-z0-9A-Z]+)?\\.)+[a-zA-Z]{2,}$" ;
    /** 年龄规则 1-120之间  */
    public static final String AGE_PATTERN="^(?:[1-9][0-9]?|1[01][0-9]|120)$";
    /** 身份证规则 */
    public static final String IDCARD_PATTERN="^\\d{15}|\\d{18}$" ;
    /** URL规则,http、www、ftp */
    public static final String URL_PATTERN = "http(s)?://([\\w-]+\\.)+[\\w-]+(/[\\w- ./?%&=]*)?" ;
    /** QQ规则 */
    public static final String QQ_PATTERN = "^[1-9][0-9]{4,13}$" ;
    /** 全汉字规则 */
    public static final String CHINESE_PATTERN = "^[\u4E00-\u9FA5]+$" ;
    /** 全字母规则 */
    public static final String STR_ENG_PATTERN="^[A-Za-z]+$";
    /** 整数规则 */
    public static final String INTEGER_PATTERN = "^-?[0-9]+$" ;
    /** 正整数规则 */
    public static final String POSITIVE_INTEGER_PATTERN = "^\\+?[1-9][0-9]*$" ;


    /**
    * @Description: 验证手机号码格式
    * @param mobile 手机号码
    * @return boolean
     */
    public static boolean validateMobile(String mobile) {
        if (StringUtils.isEmpty(mobile)){
            return Boolean.FALSE;
        }
        return mobile.matches(MOBILE_PATTERN);
    }

    /**
     * 验证是否是电信手机号,133、153、180、189、177
     * @param mobile 手机号
     * @return boolean
     */
    public static boolean validateTelecom(String mobile){
        if(StringUtils.isEmpty(mobile)){
            return Boolean.FALSE ;
        }
        return mobile.matches(CHINA_TELECOM_PATTERN) ;
    }

    /**
     * 验证是否是联通手机号 130,131,132,155,156,185,186,145,176,1707,1708,1709,175
     * @param mobile 电话号码
     * @return boolean
     */
    public static boolean validateUnionMobile(String mobile){
        if(StringUtils.isEmpty(mobile)){
            return Boolean.FALSE ;
        }
        return mobile.matches(CHINA_UNICOM_PATTERN) ;
    }

    /**
     * 验证是否是移动手机号
     * @param mobile 手机号 134,135,136,137,138,139,150,151,152,157,158,159,182,183,184,187,188,147,178,1705
     * @return boolean
     */
    public static boolean validateMoveMobile(String mobile){
        if(StringUtils.isEmpty(mobile)){
            return Boolean.FALSE ;
        }
        return mobile.matches(CHINA_MOVE_PATTERN) ;
    }

    /**
    * @Description: 验证密码格式  6-16 位字母、数字
    * @param pwd 密码
    * @return boolean
     */
    public static boolean validatePwd(String pwd) {
        if (StringUtils.isEmpty(pwd)){
            return Boolean.FALSE;
        }
        return Pattern.matches(PASSWORD_PATTERN, pwd);
    }

    /**
     * 验证座机号码,格式如:58654567,023-58654567
     * @param landline 固话、座机
     * @return boolean
     */
    public static boolean validateLandLine(final String landline) {
        if(StringUtils.isEmpty(landline)){
            return Boolean.FALSE;
        }
        return landline.matches(LANDLINE_PATTERN);
     }

    /**
     * 验证邮政编码
     * @param postCode 邮政编码
     * @return boolean
     */
    public static boolean validatePostCode(final String postCode){
        if(StringUtils.isEmpty(postCode)){
            return Boolean.FALSE ;
        }
        return postCode.matches(POSTCODE_PATTERN) ;
    }

    /**
     * 验证邮箱(电子邮件)
     * @param email 邮箱(电子邮件)
     * @return boolean
     */
    public static boolean validateEamil(final String email){
        if(StringUtils.isEmpty(email)){
            return Boolean.FALSE ;
        }
        return email.matches(EMAIL_PATTERN) ;
    }

    /**
     * 判断年龄,1-120之间
     * @param age 年龄
     * @return boolean
     */
    public static boolean validateAge(final String age){
        if(StringUtils.isEmpty(age)){
            return Boolean.FALSE ;
        }
        return age.matches(AGE_PATTERN) ;
    }

    /**
     * 身份证验证
     * @param idCard 身份证
     * @return boolean
     */
    public static boolean validateIDCard(final String idCard){
        if(StringUtils.isEmpty(idCard)){
            return Boolean.FALSE ;
        }
        return idCard.matches(IDCARD_PATTERN) ;
    }

    /**
     * URL地址验证
     * @param url URL地址
     * @return boolean
     */
    public static boolean validateUrl(final String url){
        if(StringUtils.isEmpty(url)){
            return Boolean.FALSE ;
        }
        return url.matches(URL_PATTERN) ;
    }

    /**
     * 验证QQ号
     * @param qq QQ号
     * @return boolean
     */
    public static boolean validateQq(final String qq){
        if(StringUtils.isEmpty(qq)){
            return Boolean.FALSE ;
        }
        return qq.matches(QQ_PATTERN) ;
    }

    /**
     * 验证字符串是否全是汉字
     * @param str 字符串
     * @return boolean
     */
    public static boolean validateChinese(final String str){
        if(StringUtils.isEmpty(str)){
            return Boolean.FALSE ;
        }
        return str.matches(CHINESE_PATTERN) ;
    }

    /**
     * 判断字符串是否全字母
     * @param str 字符串
     * @return boolean
     */
    public static boolean validateStrEnglish(final String str){
        if(StringUtils.isEmpty(str)){
            return Boolean.FALSE ;
        }
        return str.matches(STR_ENG_PATTERN) ;
    }

    /**
     * 判断是否是整数,包括负数
     * @param str 字符串
     * @return boolean
     */
    public static boolean validateInteger(final String str){
        if(StringUtils.isEmpty(str)){
            return Boolean.FALSE ;
        }
        return str.matches(INTEGER_PATTERN) ;
    }

    /**
     * 判断是否是大于0的正整数
     * @param str 字符串
     * @return boolean
     */
    public static boolean validatePositiveInt(final String str){
        if(StringUtils.isEmpty(str)){
            return Boolean.FALSE ;
        }
        return str.matches(POSITIVE_INTEGER_PATTERN) ;
    }

}

3. 代码生成

MybatisCodeHelperNewPro插件

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

选择Mybait逆向生成

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

按照下图中的步骤:

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

生成好了之后,把实体类拷贝到shop-pojo模块下,接口类拷贝到shop-api模块下。这个就不用说了,大家都会就不贴出来了。

下面以CouponServiceApplication为例测试一下:

返回顶部↑

补充POM依赖

    <dependencies>
        <dependency>
            <groupId>com.zxx.shop</groupId>
            <artifactId>shop-common</artifactId>
            <version>${project.parent.version}</version>
        </dependency>

        <!-- 数据库 -->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <exclusions>
                <!-- 排除 tomcat-jdbc 以使用 HikariCP -->
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-jdbc</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
        </dependency>
        <!-- Lombok -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>

        <!-- Junit-->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

    </dependencies>

返回顶部↑

补充application.yml配置文件

spring:
  application:
    name: CouponServiceApplication
  datasource:
    type: com.zaxxer.hikari.HikariDataSource
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhsot:3306/trade?useUnicode=true&characterEncoding=utf-8&useSSL=false
    username: root
    password: 123456
    hikari:
      minimum-idle: 5
      idle-timeout: 600000
      maximum-pool-size: 10
      auto-commit: true
      pool-name: MyHikariCP
      max-lifetime: 1800000
      connection-timeout: 30000
      connection-test-query: SELECT 1

mybatis:
  type-aliases-package: com.zxx.shop.entity
  mapper-locations: classpath:mapper/*.xml

logging.level.com.zxx.shop.mapper: debug

启动类

package com.zxx.shop;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;

@MapperScan("com.zxx.shop.mapper")
@SpringBootApplication
public class CouponServiceApplication {

    public static void main(String[] args) {
        SpringApplication.run(CouponServiceApplication.class, args);
    }
}

测试类:

package com.zxx.shop;

import com.zxx.shop.entity.TradeCoupon;
import com.zxx.shop.mapper.TradeCouponMapper;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import javax.annotation.Resource;

@RunWith(SpringRunner.class)
@SpringBootTest
public class CouponServiceTests {

    @Resource
    TradeCouponMapper couponMapper;

    /**
     *
     */
    @Test
    public void test01(){
        TradeCoupon one = couponMapper.selectByPrimaryKey(1L);
        System.out.println(one);
    }
}

项目地址:

返回顶部↑

基于SpringBoot2.x和tkMapper快速搭建微服务项目脚手架工程

上一篇:Android连载4-自定义控件的单位和尺寸


下一篇:android中Toast,makeText()的用法