├── src ├── main │ ├── resources │ │ ├── application-prod.properties │ │ ├── application-test.properties │ │ ├── banner.txt │ │ ├── application.properties │ │ ├── application-dev.yml │ │ └── mapper │ │ │ └── TUserMapper.xml │ └── java │ │ └── com │ │ └── company │ │ └── project │ │ ├── core │ │ ├── ServiceException.java │ │ ├── MybatisPlusConfig.java │ │ ├── ProjectConstant.java │ │ ├── MessageResultUtils.java │ │ ├── Query.java │ │ └── CodeMsgEnum.java │ │ ├── Application.java │ │ └── configurer │ │ ├── MybatisConfigurer.java │ │ ├── Swagger2Configurer.java │ │ └── WebConfigurer.java └── test │ ├── resources │ ├── generator │ │ └── template │ │ │ ├── service.ftl │ │ │ ├── service-impl.ftl │ │ │ ├── controller.ftl │ │ │ └── controller-restful.ftl │ └── demo-user.sql │ └── java │ ├── com │ └── company │ │ └── project │ │ ├── Tester.java │ │ └── GeneratorSwagger2Model.java │ └── CodeGenerator.java ├── spring-cloud-learning-01 ├── jf-mybatis │ ├── src │ │ ├── main │ │ │ ├── resources │ │ │ │ ├── application.properties │ │ │ │ ├── application-dev.yml │ │ │ │ └── mapper │ │ │ │ │ └── TUserMapper.xml │ │ │ └── java │ │ │ │ └── com │ │ │ │ └── demo │ │ │ │ ├── core │ │ │ │ ├── ServiceException.java │ │ │ │ ├── MybatisPlusConfig.java │ │ │ │ ├── ProjectConstant.java │ │ │ │ ├── MessageResultUtils.java │ │ │ │ ├── Query.java │ │ │ │ └── CodeMsgEnum.java │ │ │ │ ├── JfMybatisApplication.java │ │ │ │ └── configurer │ │ │ │ ├── MybatisConfigurer.java │ │ │ │ ├── Swagger2Configurer.java │ │ │ │ └── WebConfigurer.java │ │ └── test │ │ │ ├── resources │ │ │ ├── generator │ │ │ │ └── template │ │ │ │ │ ├── service.ftl │ │ │ │ │ ├── service-impl.ftl │ │ │ │ │ ├── controller.ftl │ │ │ │ │ └── controller-restful.ftl │ │ │ └── demo-user.sql │ │ │ └── java │ │ │ ├── com │ │ │ └── demo │ │ │ │ └── GeneratorSwagger2Model.java │ │ │ └── CodeGenerator.java │ └── pom.xml ├── jf-client01 │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── application.yml │ │ │ └── java │ │ │ └── com │ │ │ └── demo │ │ │ └── JfClient01Application.java │ └── pom.xml ├── jf-server │ ├── src │ │ └── main │ │ │ ├── resources │ │ │ └── application.yml │ │ │ └── java │ │ │ └── com │ │ │ └── demo │ │ │ └── EurekaServerApplication.java │ └── pom.xml ├── pom.xml └── log │ └── learing-test.log ├── .gitignore ├── README.md └── pom.xml /src/main/resources/application-prod.properties: -------------------------------------------------------------------------------- 1 | # 生产环境配置 2 | -------------------------------------------------------------------------------- /src/main/resources/application-test.properties: -------------------------------------------------------------------------------- 1 | # 测试环境配置 2 | -------------------------------------------------------------------------------- /src/main/resources/banner.txt: -------------------------------------------------------------------------------- 1 | //////////////////////////////////////////////////////////////////// 2 | -------------------------------------------------------------------------------- /src/main/resources/application.properties: -------------------------------------------------------------------------------- 1 | spring.profiles.active=dev 2 | # 所有环境通用的配置,放在这里 3 | 4 | # 404 交给异常处理器处理 5 | spring.mvc.throw-exception-if-no-handler-found=true 6 | spring.resources.add-mappings=false 7 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/resources/application.properties: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sjf1256754123/spring-boot-api-mybatis-plus/HEAD/spring-cloud-learning-01/jf-mybatis/src/main/resources/application.properties -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-client01/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8082 3 | 4 | spring: 5 | application: 6 | name: service-client01 7 | 8 | eureka: 9 | client: 10 | serviceUrl: 11 | defaultZone: http://localhost:8081/eureka/ 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | target/ 2 | 3 | ### STS ### 4 | .apt_generated 5 | .classpath 6 | .factorypath 7 | .project 8 | .settings 9 | .springBeans 10 | 11 | ### IntelliJ IDEA ### 12 | .idea 13 | *.iws 14 | *.iml 15 | *.ipr 16 | 17 | ### NetBeans ### 18 | nbproject/private/ 19 | build/ 20 | nbbuild/ 21 | dist/ 22 | nbdist/ 23 | .nb-gradle/ -------------------------------------------------------------------------------- /src/test/resources/generator/template/service.ftl: -------------------------------------------------------------------------------- 1 | package ${basePackage}.service; 2 | import ${basePackage}.model.${modelNameUpperCamel}; 3 | import ${basePackage}.core.Service; 4 | 5 | 6 | /** 7 | * @author ${author} 8 | * @data ${date}. 9 | */ 10 | public interface ${modelNameUpperCamel}Service extends Service<${modelNameUpperCamel}> { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/resources/generator/template/service.ftl: -------------------------------------------------------------------------------- 1 | package ${basePackage}.service; 2 | import ${basePackage}.model.${modelNameUpperCamel}; 3 | import ${basePackage}.core.Service; 4 | 5 | 6 | /** 7 | * @author ${author} 8 | * @data ${date}. 9 | */ 10 | public interface ${modelNameUpperCamel}Service extends Service<${modelNameUpperCamel}> { 11 | 12 | } 13 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-server/src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8081 3 | 4 | eureka: 5 | instance: 6 | hostname: localhost 7 | client: 8 | registerWithEureka: false 9 | fetchRegistry: false 10 | serviceUrl: 11 | defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/ 12 | 13 | spring: 14 | application: 15 | name: eurka-server 16 | 17 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/core/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.company.project.core; 2 | 3 | /** 4 | * 服务(业务)异常如“ 账号或密码错误 ”,该异常只做INFO级别的日志记录 @see WebMvcConfigurer 5 | */ 6 | public class ServiceException extends RuntimeException { 7 | public ServiceException() { 8 | } 9 | 10 | public ServiceException(String message) { 11 | super(message); 12 | } 13 | 14 | public ServiceException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/core/ServiceException.java: -------------------------------------------------------------------------------- 1 | package com.demo.core; 2 | 3 | /** 4 | * 服务(业务)异常如“ 账号或密码错误 ”,该异常只做INFO级别的日志记录 @see WebMvcConfigurer 5 | */ 6 | public class ServiceException extends RuntimeException { 7 | public ServiceException() { 8 | } 9 | 10 | public ServiceException(String message) { 11 | super(message); 12 | } 13 | 14 | public ServiceException(String message, Throwable cause) { 15 | super(message, cause); 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-client01/src/main/java/com/demo/JfClient01Application.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaClient 9 | public class JfClient01Application { 10 | public static void main(String[] args) { 11 | SpringApplication.run(JfClient01Application.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-server/src/main/java/com/demo/EurekaServerApplication.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer; 6 | 7 | @SpringBootApplication 8 | @EnableEurekaServer 9 | public class EurekaServerApplication { 10 | public static void main(String[] args) { 11 | SpringApplication.run(EurekaServerApplication.class, args); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /src/test/java/com/company/project/Tester.java: -------------------------------------------------------------------------------- 1 | package com.company.project; 2 | 3 | 4 | import com.company.project.Application; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.context.SpringBootTest; 7 | import org.springframework.test.annotation.Rollback; 8 | import org.springframework.test.context.junit4.SpringRunner; 9 | import org.springframework.transaction.annotation.Transactional; 10 | 11 | /** 12 | * 单元测试继承该类即可 13 | */ 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest(classes = Application.class) 16 | @Transactional 17 | @Rollback 18 | public abstract class Tester {} 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/JfMybatisApplication.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import org.springframework.boot.SpringApplication; 4 | import org.springframework.boot.autoconfigure.SpringBootApplication; 5 | import org.springframework.cloud.netflix.eureka.EnableEurekaClient; 6 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 7 | 8 | @SpringBootApplication 9 | @EnableSwagger2 10 | @EnableEurekaClient 11 | public class JfMybatisApplication { 12 | public static void main(String[] args) { 13 | SpringApplication.run(JfMybatisApplication.class, args); 14 | } 15 | 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/Application.java: -------------------------------------------------------------------------------- 1 | package com.company.project; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 7 | 8 | /** 9 | * @author Gahon 10 | */ 11 | @SpringBootApplication 12 | @EnableSwagger2 13 | //@MapperScan("com.company.project.dao") 14 | public class Application { 15 | public static void main(String[] args) { 16 | SpringApplication.run(Application.class, args); 17 | } 18 | } 19 | 20 | -------------------------------------------------------------------------------- /src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 9999 3 | 4 | spring: 5 | datasource: 6 | url: jdbc:mysql://localhost:3306/learning_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true 7 | username: root 8 | password: 123456 9 | 10 | mybatis-plus: 11 | mapperLocations: classpath:mapper/*Mapper.xml 12 | global-config: 13 | banner: true 14 | db-config: 15 | id-type: auto 16 | tableUnderline: false 17 | # 逻辑已删除值(默认为 1) 18 | logic-delete-value: 1 19 | # 逻辑未删除值(默认为 0) 20 | logic-not-delete-value: 0 21 | configuration: 22 | map-underscore-to-camel-case: false 23 | 24 | logging: 25 | file: log/learning-test.log 26 | level: 27 | com.company.project.dao : debug 28 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/core/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.company.project.core; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @author ya 10 | * @date 2018/7/19 20:27 11 | */ 12 | @Configuration 13 | @MapperScan("com.xxx.xxx") 14 | public class MybatisPlusConfig { 15 | 16 | /** 17 | * mybatis-plus分页插件
18 | * 文档:http://mp.baomidou.com
19 | */ 20 | @Bean 21 | public PaginationInterceptor paginationInterceptor() { 22 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 23 | return paginationInterceptor; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/test/resources/generator/template/service-impl.ftl: -------------------------------------------------------------------------------- 1 | package ${basePackage}.service.impl; 2 | 3 | import ${basePackage}.dao.${modelNameUpperCamel}Mapper; 4 | import ${basePackage}.model.${modelNameUpperCamel}; 5 | import ${basePackage}.service.${modelNameUpperCamel}Service; 6 | import ${basePackage}.core.AbstractService; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import javax.annotation.Resource; 11 | 12 | 13 | /** 14 | * @author ${author} 15 | * @data ${date}. 16 | */ 17 | @Service 18 | @Transactional 19 | public class ${modelNameUpperCamel}ServiceImpl extends AbstractService<${modelNameUpperCamel}> implements ${modelNameUpperCamel}Service { 20 | @Resource 21 | private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/core/MybatisPlusConfig.java: -------------------------------------------------------------------------------- 1 | package com.demo.core; 2 | 3 | import com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor; 4 | import org.mybatis.spring.annotation.MapperScan; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | 8 | /** 9 | * @author ya 10 | * @date 2018/7/19 20:27 11 | */ 12 | @Configuration 13 | @MapperScan("com.xxx.xxx") 14 | public class MybatisPlusConfig { 15 | 16 | /** 17 | * mybatis-plus分页插件
18 | * 文档:http://mp.baomidou.com
19 | */ 20 | @Bean 21 | public PaginationInterceptor paginationInterceptor() { 22 | PaginationInterceptor paginationInterceptor = new PaginationInterceptor(); 23 | return paginationInterceptor; 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8083 3 | 4 | spring: 5 | datasource: 6 | url: jdbc:mysql://localhost:3306/learning_test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=GMT&useSSL=false&allowPublicKeyRetrieval=true 7 | username: root 8 | password: 123456 9 | application: 10 | name: service-mybatisPlus 11 | 12 | eureka: 13 | client: 14 | serviceUrl: 15 | defaultZone: http://localhost:8081/eureka/ 16 | 17 | mybatis-plus: 18 | mapper-locations: classpath:mapper/*Mapper.xml 19 | global-config: 20 | db-config: 21 | id-type: auto 22 | table-underline: false 23 | logic-delete-value: 1 24 | logic-not-delete-value: 0 25 | configuration: 26 | map-underscore-to-camel-case: false 27 | 28 | 29 | logging: 30 | level: 31 | com.demo.dao: debug 32 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/resources/generator/template/service-impl.ftl: -------------------------------------------------------------------------------- 1 | package ${basePackage}.service.impl; 2 | 3 | import ${basePackage}.dao.${modelNameUpperCamel}Mapper; 4 | import ${basePackage}.model.${modelNameUpperCamel}; 5 | import ${basePackage}.service.${modelNameUpperCamel}Service; 6 | import ${basePackage}.core.AbstractService; 7 | import org.springframework.stereotype.Service; 8 | import org.springframework.transaction.annotation.Transactional; 9 | 10 | import javax.annotation.Resource; 11 | 12 | 13 | /** 14 | * @author ${author} 15 | * @data ${date}. 16 | */ 17 | @Service 18 | @Transactional 19 | public class ${modelNameUpperCamel}ServiceImpl extends AbstractService<${modelNameUpperCamel}> implements ${modelNameUpperCamel}Service { 20 | @Resource 21 | private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper; 22 | 23 | } 24 | -------------------------------------------------------------------------------- /src/main/resources/mapper/TUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | id, user_name, pass_word, mail, is_del, sasdasdasd 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/resources/mapper/TUserMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | id, user_name, pass_word, mail, is_del, sasdasdasd 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-server/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jf.learning 7 | jf.maven 8 | 1.0-SNAPSHOT 9 | 10 | 11 | jf-server 12 | eureka-server 13 | 0.0.1-SNAPSHOT 14 | eureka-server 15 | Demo project for Spring Boot 16 | 17 | 18 | 19 | org.springframework.cloud 20 | spring-cloud-starter-netflix-eureka-server 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-client01/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jf.learning 7 | jf.maven 8 | 1.0-SNAPSHOT 9 | 10 | 11 | eureka-client01 12 | jf-client01 13 | 0.0.1-SNAPSHOT 14 | jf-client01 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | Greenwich.SR1 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-netflix-eureka-server 26 | 27 | 28 | 29 | 30 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/core/ProjectConstant.java: -------------------------------------------------------------------------------- 1 | package com.company.project.core; 2 | 3 | /** 4 | * 项目常量 5 | * @author Gahon 6 | */ 7 | public final class ProjectConstant { 8 | /** 9 | * 生成代码所在的基础包名称,可根据自己公司的项目修改(注意:这个配置修改之后需要手工修改src目录项目默认的包路径,使其保持一致,不然会找不到类) 10 | **/ 11 | public static final String BASE_PACKAGE = "com.company.project"; 12 | /** 13 | * 生成的Model所在包 14 | */ 15 | public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model"; 16 | /** 17 | * 生成的Mapper所在包 18 | */ 19 | public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".dao"; 20 | /** 21 | * 生成的Service所在包 22 | */ 23 | public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service"; 24 | /** 25 | * 生成的ServiceImpl所在包 26 | */ 27 | public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl"; 28 | /** 29 | * 生成的Controller所在包 30 | */ 31 | public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".controller"; 32 | /** 33 | * Mapper插件基础接口的完全限定名 34 | */ 35 | public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.Mapper"; 36 | } 37 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/core/ProjectConstant.java: -------------------------------------------------------------------------------- 1 | package com.demo.core; 2 | 3 | /** 4 | * 项目常量 5 | * @author Gahon 6 | */ 7 | public final class ProjectConstant { 8 | 9 | /** 10 | * 项目路径 11 | */ 12 | public static final String PROJECT_PATH = "E:/Desktop/spring-cloud-learning-01/jf-mybatis"; 13 | /** 14 | * 生成代码所在的基础包名称,可根据自己公司的项目修改(注意:这个配置修改之后需要手工修改src目录项目默认的包路径,使其保持一致,不然会找不到类) 15 | **/ 16 | public static final String BASE_PACKAGE = "com.demo"; 17 | /** 18 | * 生成的Model所在包 19 | */ 20 | public static final String MODEL_PACKAGE = BASE_PACKAGE + ".model"; 21 | /** 22 | * 生成的Mapper所在包 23 | */ 24 | public static final String MAPPER_PACKAGE = BASE_PACKAGE + ".dao"; 25 | /** 26 | * 生成的Service所在包 27 | */ 28 | public static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service"; 29 | /** 30 | * 生成的ServiceImpl所在包 31 | */ 32 | public static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl"; 33 | /** 34 | * 生成的Controller所在包 35 | */ 36 | public static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".controller"; 37 | /** 38 | * Mapper插件基础接口的完全限定名 39 | */ 40 | public static final String MAPPER_INTERFACE_REFERENCE = BASE_PACKAGE + ".core.Mapper"; 41 | } 42 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/configurer/MybatisConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.demo.configurer; 2 | 3 | 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import tk.mybatis.spring.mapper.MapperScannerConfigurer; 7 | 8 | import java.util.Properties; 9 | 10 | import static com.demo.core.ProjectConstant.MAPPER_PACKAGE; 11 | 12 | /** 13 | * Mybatis & Mapper & PageHelper 配置 14 | * @author Gahon 15 | */ 16 | @Configuration 17 | public class MybatisConfigurer { 18 | 19 | @Bean 20 | public MapperScannerConfigurer mapperScannerConfigurer() { 21 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 22 | // mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean"); 23 | mapperScannerConfigurer.setBasePackage(MAPPER_PACKAGE); 24 | 25 | //配置通用Mapper,详情请查阅官方文档 26 | 27 | Properties properties = new Properties(); 28 | // properties.setProperty("mappers", MAPPER_INTERFACE_REFERENCE); //4.0之后版本不需要,除非自定义mapper 29 | 30 | //insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != '' 31 | properties.setProperty("notEmpty", "false"); 32 | //取回主键的方式 33 | properties.setProperty("IDENTITY", "MYSQL"); 34 | //配置后会自动处理关键字,可以配的值和数据库有关。 35 | properties.setProperty("wrapKeyword", "`{0}`"); 36 | mapperScannerConfigurer.setProperties(properties); 37 | 38 | return mapperScannerConfigurer; 39 | } 40 | 41 | } 42 | 43 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/core/MessageResultUtils.java: -------------------------------------------------------------------------------- 1 | package com.company.project.core; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @version:1.0 10 | * @explain: 11 | * @Date: created in 15:56 2019/1/9 12 | */ 13 | public class MessageResultUtils { 14 | 15 | /** 16 | * @param @param t 17 | * @param @param msgEnum 18 | * @param @return 设定文件 19 | * @return Map 返回类型 20 | * @throws 21 | * @Title: getResults 22 | */ 23 | public static Map getResults(T t, CodeMsgEnum msgEnum) { 24 | Map modelMap = new HashMap(); 25 | modelMap.put(CodeMsgEnum.STATUS, msgEnum.getCode()); 26 | modelMap.put(CodeMsgEnum.BUSINESSSTATUS, msgEnum.getBunissCode()); 27 | //modelMap.put(msgEnum.MESSAGE, msgEnum.getMsg()); 28 | modelMap.put(CodeMsgEnum.MESSAGE, (StringUtils.isBlank(msgEnum.getMsg()) ? t : msgEnum.getMsg())); 29 | modelMap.put(CodeMsgEnum.ITEMS, t); 30 | return modelMap; 31 | } 32 | 33 | /** 34 | * @param @param msgEnum 35 | * @param @return 设定文件 36 | * @return Map 返回类型 37 | * @throws 38 | * @Title: getResults 39 | */ 40 | public static Map getResults(CodeMsgEnum msgEnum) { 41 | return getResults(null, msgEnum); 42 | } 43 | 44 | 45 | public static Map returnResults(T resultData, Integer status, String businessStatus, String msg, T ext) { 46 | Map modelMap = new HashMap(); 47 | 48 | modelMap.put("STATUS", status); 49 | modelMap.put("BUSINESSSTATUS", businessStatus); 50 | modelMap.put("MESSAGE", msg); 51 | modelMap.put("ITEMS", resultData); 52 | modelMap.put("EXT", ext); 53 | return modelMap; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /src/test/java/com/company/project/GeneratorSwagger2Model.java: -------------------------------------------------------------------------------- 1 | package com.company.project; 2 | 3 | import org.mybatis.generator.api.IntrospectedColumn; 4 | import org.mybatis.generator.api.IntrospectedTable; 5 | import org.mybatis.generator.api.PluginAdapter; 6 | import org.mybatis.generator.api.dom.java.Field; 7 | import org.mybatis.generator.api.dom.java.TopLevelClass; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author Gahon 13 | * description 根据数据库注释对实体类增加swagger2文档注解 14 | */ 15 | public class GeneratorSwagger2Model extends PluginAdapter { 16 | public boolean validate(List list) { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { 22 | String classAnnotation = "@ApiModel(value=\"" + topLevelClass.getType().getShortName() + "\")"; 23 | if (!topLevelClass.getAnnotations().contains(classAnnotation)) { 24 | topLevelClass.addAnnotation(classAnnotation); 25 | } 26 | 27 | String apiModelAnnotationPackage = properties.getProperty("apiModelAnnotationPackage"); 28 | String apiModelPropertyAnnotationPackage = properties.getProperty("apiModelPropertyAnnotationPackage"); 29 | if (null == apiModelAnnotationPackage) apiModelAnnotationPackage = "io.swagger.annotations.ApiModel"; 30 | if (null == apiModelPropertyAnnotationPackage) 31 | apiModelPropertyAnnotationPackage = "io.swagger.annotations.ApiModelProperty"; 32 | 33 | topLevelClass.addImportedType(apiModelAnnotationPackage); 34 | topLevelClass.addImportedType(apiModelPropertyAnnotationPackage); 35 | 36 | field.addAnnotation("@ApiModelProperty(value=\"" + introspectedColumn.getRemarks() + "\")"); 37 | return super.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/core/MessageResultUtils.java: -------------------------------------------------------------------------------- 1 | package com.demo.core; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import java.util.HashMap; 6 | import java.util.Map; 7 | 8 | /** 9 | * @version:1.0 10 | * @explain: 11 | * @Date: created in 15:56 2019/1/9 12 | */ 13 | public class MessageResultUtils { 14 | 15 | /** 16 | * @param @param t 17 | * @param @param msgEnum 18 | * @param @return 设定文件 19 | * @return Map 返回类型 20 | * @throws 21 | * @Title: getResults 22 | */ 23 | public static Map getResults(T t, CodeMsgEnum msgEnum) { 24 | Map modelMap = new HashMap(); 25 | modelMap.put(CodeMsgEnum.STATUS, msgEnum.getCode()); 26 | modelMap.put(CodeMsgEnum.BUSINESSSTATUS, msgEnum.getBunissCode()); 27 | //modelMap.put(msgEnum.MESSAGE, msgEnum.getMsg()); 28 | modelMap.put(CodeMsgEnum.MESSAGE, (StringUtils.isBlank(msgEnum.getMsg()) ? t : msgEnum.getMsg())); 29 | modelMap.put(CodeMsgEnum.ITEMS, t); 30 | return modelMap; 31 | } 32 | 33 | /** 34 | * @param @param msgEnum 35 | * @param @return 设定文件 36 | * @return Map 返回类型 37 | * @throws 38 | * @Title: getResults 39 | */ 40 | public static Map getResults(CodeMsgEnum msgEnum) { 41 | return getResults(null, msgEnum); 42 | } 43 | 44 | 45 | public static Map returnResults(T resultData, Integer status, String businessStatus, String msg, T ext) { 46 | Map modelMap = new HashMap(); 47 | 48 | modelMap.put("STATUS", status); 49 | modelMap.put("BUSINESSSTATUS", businessStatus); 50 | modelMap.put("MESSAGE", msg); 51 | modelMap.put("ITEMS", resultData); 52 | modelMap.put("EXT", ext); 53 | return modelMap; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/java/com/demo/GeneratorSwagger2Model.java: -------------------------------------------------------------------------------- 1 | package com.demo; 2 | 3 | import org.mybatis.generator.api.IntrospectedColumn; 4 | import org.mybatis.generator.api.IntrospectedTable; 5 | import org.mybatis.generator.api.PluginAdapter; 6 | import org.mybatis.generator.api.dom.java.Field; 7 | import org.mybatis.generator.api.dom.java.TopLevelClass; 8 | 9 | import java.util.List; 10 | 11 | /** 12 | * @author Gahon 13 | * description 根据数据库注释对实体类增加swagger2文档注解 14 | */ 15 | public class GeneratorSwagger2Model extends PluginAdapter { 16 | public boolean validate(List list) { 17 | return true; 18 | } 19 | 20 | @Override 21 | public boolean modelFieldGenerated(Field field, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) { 22 | String classAnnotation = "@ApiModel(value=\"" + topLevelClass.getType().getShortName() + "\")"; 23 | if (!topLevelClass.getAnnotations().contains(classAnnotation)) { 24 | topLevelClass.addAnnotation(classAnnotation); 25 | } 26 | 27 | String apiModelAnnotationPackage = properties.getProperty("apiModelAnnotationPackage"); 28 | String apiModelPropertyAnnotationPackage = properties.getProperty("apiModelPropertyAnnotationPackage"); 29 | if (null == apiModelAnnotationPackage) apiModelAnnotationPackage = "io.swagger.annotations.ApiModel"; 30 | if (null == apiModelPropertyAnnotationPackage) 31 | apiModelPropertyAnnotationPackage = "io.swagger.annotations.ApiModelProperty"; 32 | 33 | topLevelClass.addImportedType(apiModelAnnotationPackage); 34 | topLevelClass.addImportedType(apiModelPropertyAnnotationPackage); 35 | 36 | field.addAnnotation("@ApiModelProperty(value=\"" + introspectedColumn.getRemarks() + "\")"); 37 | return super.modelFieldGenerated(field, topLevelClass, introspectedColumn, introspectedTable, modelClassType); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/configurer/MybatisConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.company.project.configurer; 2 | 3 | 4 | import com.github.pagehelper.PageHelper; 5 | import com.github.pagehelper.PageInterceptor; 6 | import org.apache.ibatis.plugin.Interceptor; 7 | import org.apache.ibatis.session.SqlSessionFactory; 8 | import org.mybatis.spring.SqlSessionFactoryBean; 9 | import org.springframework.context.annotation.Bean; 10 | import org.springframework.context.annotation.Configuration; 11 | import org.springframework.core.io.support.PathMatchingResourcePatternResolver; 12 | import org.springframework.core.io.support.ResourcePatternResolver; 13 | import tk.mybatis.spring.mapper.MapperScannerConfigurer; 14 | import javax.sql.DataSource; 15 | import java.util.Properties; 16 | 17 | import static com.company.project.core.ProjectConstant.MAPPER_PACKAGE; 18 | import static com.company.project.core.ProjectConstant.MODEL_PACKAGE; 19 | 20 | /** 21 | * Mybatis & Mapper & PageHelper 配置 22 | * @author Gahon 23 | */ 24 | @Configuration 25 | public class MybatisConfigurer { 26 | 27 | @Bean 28 | public MapperScannerConfigurer mapperScannerConfigurer() { 29 | MapperScannerConfigurer mapperScannerConfigurer = new MapperScannerConfigurer(); 30 | // mapperScannerConfigurer.setSqlSessionFactoryBeanName("sqlSessionFactoryBean"); 31 | mapperScannerConfigurer.setBasePackage(MAPPER_PACKAGE); 32 | 33 | //配置通用Mapper,详情请查阅官方文档 34 | 35 | Properties properties = new Properties(); 36 | // properties.setProperty("mappers", MAPPER_INTERFACE_REFERENCE); //4.0之后版本不需要,除非自定义mapper 37 | 38 | //insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != '' 39 | properties.setProperty("notEmpty", "false"); 40 | //取回主键的方式 41 | properties.setProperty("IDENTITY", "MYSQL"); 42 | //配置后会自动处理关键字,可以配的值和数据库有关。 43 | properties.setProperty("wrapKeyword", "`{0}`"); 44 | mapperScannerConfigurer.setProperties(properties); 45 | 46 | return mapperScannerConfigurer; 47 | } 48 | 49 | } 50 | 51 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/core/Query.java: -------------------------------------------------------------------------------- 1 | package com.company.project.core; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import lombok.Getter; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @Author:xpj 13 | * @version:1.0 14 | * @explain: 15 | * @Date: created in 12:27 2019/1/11 16 | */ 17 | public class Query extends Page { 18 | private static final String PAGE = "page"; 19 | private static final String pageSize = "pageSize"; 20 | private static final String ORDER_BY_FIELD = "orderByField"; 21 | private static final String IS_ASC = "isAsc"; 22 | 23 | @Getter 24 | private Map condition; 25 | 26 | public Query setCondition(Map condition) { 27 | this.condition = condition; 28 | return this; 29 | } 30 | 31 | @Override 32 | public Map condition() { 33 | return new HashMap<>(this.getCondition()); 34 | } 35 | 36 | public Query(Map params) { 37 | super(Integer.parseInt(params.getOrDefault(PAGE, 1).toString()) 38 | , Integer.parseInt(params.getOrDefault(pageSize, 10).toString())); 39 | 40 | //移除不包含查询条件的字段 41 | params.entrySet().removeIf(condition -> ObjectUtil.isNull(condition.getValue()) || StrUtil.isEmpty(condition.getValue().toString())); 42 | 43 | // 判断是否是升序 44 | boolean isAsc = Boolean.parseBoolean(params.getOrDefault(IS_ASC, Boolean.TRUE).toString()); 45 | 46 | // 用于排序的字段 47 | String orderByField = params.getOrDefault(ORDER_BY_FIELD, "").toString(); 48 | if (StrUtil.isNotEmpty(orderByField)) { 49 | if (isAsc) { 50 | this.setAsc(orderByField); 51 | } else { 52 | this.setDesc(orderByField); 53 | } 54 | } 55 | params.remove(PAGE); 56 | params.remove(pageSize); 57 | params.remove(ORDER_BY_FIELD); 58 | params.remove(IS_ASC); 59 | this.setCondition(params); 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/core/Query.java: -------------------------------------------------------------------------------- 1 | package com.demo.core; 2 | 3 | import cn.hutool.core.util.ObjectUtil; 4 | import cn.hutool.core.util.StrUtil; 5 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 6 | import lombok.Getter; 7 | 8 | import java.util.HashMap; 9 | import java.util.Map; 10 | 11 | /** 12 | * @Author:xpj 13 | * @version:1.0 14 | * @explain: 15 | * @Date: created in 12:27 2019/1/11 16 | */ 17 | public class Query extends Page { 18 | private static final String PAGE = "page"; 19 | private static final String pageSize = "pageSize"; 20 | private static final String ORDER_BY_FIELD = "orderByField"; 21 | private static final String IS_ASC = "isAsc"; 22 | 23 | @Getter 24 | private Map condition; 25 | 26 | public Query setCondition(Map condition) { 27 | this.condition = condition; 28 | return this; 29 | } 30 | 31 | @Override 32 | public Map condition() { 33 | return new HashMap<>(this.getCondition()); 34 | } 35 | 36 | public Query(Map params) { 37 | super(Integer.parseInt(params.getOrDefault(PAGE, 1).toString()) 38 | , Integer.parseInt(params.getOrDefault(pageSize, 10).toString())); 39 | 40 | //移除不包含查询条件的字段 41 | params.entrySet().removeIf(condition -> ObjectUtil.isNull(condition.getValue()) || StrUtil.isEmpty(condition.getValue().toString())); 42 | 43 | // 判断是否是升序 44 | boolean isAsc = Boolean.parseBoolean(params.getOrDefault(IS_ASC, Boolean.TRUE).toString()); 45 | 46 | // 用于排序的字段 47 | String orderByField = params.getOrDefault(ORDER_BY_FIELD, "").toString(); 48 | if (StrUtil.isNotEmpty(orderByField)) { 49 | if (isAsc) { 50 | this.setAsc(orderByField); 51 | } else { 52 | this.setDesc(orderByField); 53 | } 54 | } 55 | params.remove(PAGE); 56 | params.remove(pageSize); 57 | params.remove(ORDER_BY_FIELD); 58 | params.remove(IS_ASC); 59 | this.setCondition(params); 60 | } 61 | } 62 | 63 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/configurer/Swagger2Configurer.java: -------------------------------------------------------------------------------- 1 | package com.company.project.configurer; 2 | 3 | import com.company.project.core.ProjectConstant; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 7 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 8 | import springfox.documentation.builders.ApiInfoBuilder; 9 | import springfox.documentation.builders.PathSelectors; 10 | import springfox.documentation.builders.RequestHandlerSelectors; 11 | import springfox.documentation.service.ApiInfo; 12 | import springfox.documentation.spi.DocumentationType; 13 | import springfox.documentation.spring.web.plugins.Docket; 14 | 15 | /** 16 | * @author Gahon 17 | */ 18 | @Configuration 19 | public class Swagger2Configurer implements WebMvcConfigurer { 20 | 21 | /** 22 | * 这个地方要重新注入一下资源文件,不然不会注入资源的,也没有注入requestHandlerMappping,相当于xml配置的 23 | * 24 | * 25 | * 26 | */ 27 | @Override 28 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 29 | registry.addResourceHandler("doc.html") 30 | .addResourceLocations("classpath:/META-INF/resources/"); 31 | registry.addResourceHandler("/webjars/**") 32 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 33 | } 34 | 35 | 36 | @Bean 37 | public Docket createRestApi() { 38 | return new Docket(DocumentationType.SWAGGER_2) 39 | .apiInfo(apiInfo()) 40 | .select() 41 | .apis(RequestHandlerSelectors.basePackage(ProjectConstant.CONTROLLER_PACKAGE)) 42 | .paths(PathSelectors.any()) 43 | .build(); 44 | } 45 | 46 | private ApiInfo apiInfo() { 47 | return new ApiInfoBuilder() 48 | .title("API文档展示") 49 | .description("通过直接且美观的方式来查看和调试API") 50 | .version("1.0") 51 | .build(); 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/configurer/Swagger2Configurer.java: -------------------------------------------------------------------------------- 1 | package com.demo.configurer; 2 | 3 | import com.demo.core.ProjectConstant; 4 | import com.demo.core.ProjectConstant; 5 | import org.springframework.context.annotation.Bean; 6 | import org.springframework.context.annotation.Configuration; 7 | import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; 8 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 9 | import springfox.documentation.builders.ApiInfoBuilder; 10 | import springfox.documentation.builders.PathSelectors; 11 | import springfox.documentation.builders.RequestHandlerSelectors; 12 | import springfox.documentation.service.ApiInfo; 13 | import springfox.documentation.spi.DocumentationType; 14 | import springfox.documentation.spring.web.plugins.Docket; 15 | 16 | /** 17 | * @author Gahon 18 | */ 19 | @Configuration 20 | public class Swagger2Configurer implements WebMvcConfigurer { 21 | 22 | /** 23 | * 这个地方要重新注入一下资源文件,不然不会注入资源的,也没有注入requestHandlerMappping,相当于xml配置的 24 | * 25 | * 26 | * 27 | */ 28 | @Override 29 | public void addResourceHandlers(ResourceHandlerRegistry registry) { 30 | registry.addResourceHandler("doc.html") 31 | .addResourceLocations("classpath:/META-INF/resources/"); 32 | registry.addResourceHandler("/webjars/**") 33 | .addResourceLocations("classpath:/META-INF/resources/webjars/"); 34 | } 35 | 36 | 37 | @Bean 38 | public Docket createRestApi() { 39 | return new Docket(DocumentationType.SWAGGER_2) 40 | .apiInfo(apiInfo()) 41 | .select() 42 | .apis(RequestHandlerSelectors.basePackage(ProjectConstant.CONTROLLER_PACKAGE)) 43 | .paths(PathSelectors.any()) 44 | .build(); 45 | } 46 | 47 | private ApiInfo apiInfo() { 48 | return new ApiInfoBuilder() 49 | .title("API文档展示") 50 | .description("通过直接且美观的方式来查看和调试API") 51 | .version("1.0") 52 | .build(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /src/test/resources/generator/template/controller.ftl: -------------------------------------------------------------------------------- 1 | package ${basePackage}.web; 2 | import ${basePackage}.core.Result; 3 | import ${basePackage}.core.ResultGenerator; 4 | import ${basePackage}.model.${modelNameUpperCamel}; 5 | import ${basePackage}.service.${modelNameUpperCamel}Service; 6 | import com.github.pagehelper.PageHelper; 7 | import com.github.pagehelper.PageInfo; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import javax.annotation.Resource; 14 | import java.util.List; 15 | 16 | /** 17 | * @author ${author} 18 | * @data ${date}. 19 | */ 20 | @RestController 21 | @RequestMapping("${baseRequestMapping}") 22 | public class ${modelNameUpperCamel}Controller { 23 | @Resource 24 | private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service; 25 | 26 | @PostMapping("/add") 27 | public Result add(${modelNameUpperCamel} ${modelNameLowerCamel}) { 28 | ${modelNameLowerCamel}Service.save(${modelNameLowerCamel}); 29 | return ResultGenerator.genSuccessResult(); 30 | } 31 | 32 | @PostMapping("/delete") 33 | public Result delete(@RequestParam Integer id) { 34 | ${modelNameLowerCamel}Service.deleteById(id); 35 | return ResultGenerator.genSuccessResult(); 36 | } 37 | 38 | @PostMapping("/update") 39 | public Result update(${modelNameUpperCamel} ${modelNameLowerCamel}) { 40 | ${modelNameLowerCamel}Service.update(${modelNameLowerCamel}); 41 | return ResultGenerator.genSuccessResult(); 42 | } 43 | 44 | @PostMapping("/detail") 45 | public Result detail(@RequestParam Integer id) { 46 | ${modelNameUpperCamel} ${modelNameLowerCamel} = ${modelNameLowerCamel}Service.findById(id); 47 | return ResultGenerator.genSuccessResult(${modelNameLowerCamel}); 48 | } 49 | 50 | @PostMapping("/list") 51 | public Result list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) { 52 | PageHelper.startPage(page, size); 53 | List<${modelNameUpperCamel}> list = ${modelNameLowerCamel}Service.findAll(); 54 | PageInfo pageInfo = new PageInfo(list); 55 | return ResultGenerator.genSuccessResult(pageInfo); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/resources/generator/template/controller.ftl: -------------------------------------------------------------------------------- 1 | package ${basePackage}.web; 2 | import ${basePackage}.core.Result; 3 | import ${basePackage}.core.ResultGenerator; 4 | import ${basePackage}.model.${modelNameUpperCamel}; 5 | import ${basePackage}.service.${modelNameUpperCamel}Service; 6 | import com.github.pagehelper.PageHelper; 7 | import com.github.pagehelper.PageInfo; 8 | import org.springframework.web.bind.annotation.PostMapping; 9 | import org.springframework.web.bind.annotation.RequestMapping; 10 | import org.springframework.web.bind.annotation.RequestParam; 11 | import org.springframework.web.bind.annotation.RestController; 12 | 13 | import javax.annotation.Resource; 14 | import java.util.List; 15 | 16 | /** 17 | * @author ${author} 18 | * @data ${date}. 19 | */ 20 | @RestController 21 | @RequestMapping("${baseRequestMapping}") 22 | public class ${modelNameUpperCamel}Controller { 23 | @Resource 24 | private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service; 25 | 26 | @PostMapping("/add") 27 | public Result add(${modelNameUpperCamel} ${modelNameLowerCamel}) { 28 | ${modelNameLowerCamel}Service.save(${modelNameLowerCamel}); 29 | return ResultGenerator.genSuccessResult(); 30 | } 31 | 32 | @PostMapping("/delete") 33 | public Result delete(@RequestParam Integer id) { 34 | ${modelNameLowerCamel}Service.deleteById(id); 35 | return ResultGenerator.genSuccessResult(); 36 | } 37 | 38 | @PostMapping("/update") 39 | public Result update(${modelNameUpperCamel} ${modelNameLowerCamel}) { 40 | ${modelNameLowerCamel}Service.update(${modelNameLowerCamel}); 41 | return ResultGenerator.genSuccessResult(); 42 | } 43 | 44 | @PostMapping("/detail") 45 | public Result detail(@RequestParam Integer id) { 46 | ${modelNameUpperCamel} ${modelNameLowerCamel} = ${modelNameLowerCamel}Service.findById(id); 47 | return ResultGenerator.genSuccessResult(${modelNameLowerCamel}); 48 | } 49 | 50 | @PostMapping("/list") 51 | public Result list(@RequestParam(defaultValue = "0") Integer page, @RequestParam(defaultValue = "0") Integer size) { 52 | PageHelper.startPage(page, size); 53 | List<${modelNameUpperCamel}> list = ${modelNameLowerCamel}Service.findAll(); 54 | PageInfo pageInfo = new PageInfo(list); 55 | return ResultGenerator.genSuccessResult(pageInfo); 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/core/CodeMsgEnum.java: -------------------------------------------------------------------------------- 1 | package com.company.project.core; 2 | 3 | /** 4 | * @ClassName: CodeMsgEnum 5 | * @Description: TODO 请求返回信息枚举类 6 | * @author F_xh 7 | * @date 2017年4月28日 下午4:21:31 8 | * 9 | */ 10 | public enum CodeMsgEnum { 11 | //参数请求信息 12 | ILLEGALREQUEST("0","8000","非法请求"), 13 | PARAMERR("0","8001","参数错误"), 14 | CACHEEXPIRED("0","8002","缓存失败"), 15 | 16 | USER_LOGIN_SUCCESS("1","","登陆成功"), 17 | USER_LOGIN_ERROR("0","","账号或密码错误"), 18 | USER_LOGIN_ERROR_ACCOUNT("0","","账号错误"), 19 | USER_LOGIN_ERROR_PW("0","","密码错误"), 20 | USER_SAVE_SUCCESS("1","","修改成功"), 21 | USER_MODIFY_ERROR_PW("0","","原密码错误"), 22 | USER_MODIFY_ERROR_CONFIRM("0","","两次输入不一致"), 23 | 24 | TOKEN_ERROR("1","","Token错误或失效"), 25 | RANDOM_CODE_ERROR("0","","验证码错误"), 26 | 27 | // 复制 28 | COPY_SUCCESS("1", "", "复制成功"), 29 | COPY_ERROR("0", "", "复制失败"), 30 | 31 | // 保存 32 | SAVE_SUCCESS("1", "", "保存成功"), 33 | SAVE_ERROR("0", "", "保存失败"), 34 | SAVE_REFUSE("0", "", "不可编辑"), 35 | 36 | // 查询 37 | SEARCH_SUCCESS("1", "", "查询成功"), 38 | SEARCH_ERROR("0", "", "查询失败"), 39 | 40 | // 删除 41 | DEL_SUCCESS("1", "", "删除成功"), 42 | DEL_ERROR("0", "", "删除失败"), 43 | DEL_REFUSE("0", "", "不可删除"), 44 | 45 | // 是否成功 46 | SUCCESS("1", "", ""), 47 | ERROR("0", "", ""), 48 | 49 | //免责声明,关于 50 | DISCLAIMERABOUTSUCCESS("1","8090","获取成功"), 51 | 52 | /*web enum---------end--*/ 53 | //系统信息 54 | SYSTEM("0","10000","系统异常,请刷新后重试或联系系统管理员"), 55 | 56 | STATUS(),BUSINESSSTATUS(),ITEMS(),MESSAGE(),FEEDBACK(); 57 | 58 | private String code; 59 | private String bunissCode; 60 | private String msg; 61 | 62 | private CodeMsgEnum(String code, String bunissCode, String msg){ 63 | this.code=code; 64 | this.bunissCode=bunissCode; 65 | this.msg=msg; 66 | } 67 | 68 | private CodeMsgEnum(){ 69 | 70 | } 71 | 72 | public String getCode() { 73 | return code; 74 | } 75 | 76 | public void setCode(String code) { 77 | this.code = code; 78 | } 79 | 80 | public String getBunissCode() { 81 | return bunissCode; 82 | } 83 | 84 | public void setBunissCode(String bunissCode) { 85 | this.bunissCode = bunissCode; 86 | } 87 | 88 | public String getMsg() { 89 | return msg; 90 | } 91 | 92 | public void setMsg(String msg) { 93 | this.msg = msg; 94 | } 95 | 96 | public static void main(String[] args){ 97 | System.out.print(CodeMsgEnum.DISCLAIMERABOUTSUCCESS); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/core/CodeMsgEnum.java: -------------------------------------------------------------------------------- 1 | package com.demo.core; 2 | 3 | /** 4 | * @ClassName: CodeMsgEnum 5 | * @Description: TODO 请求返回信息枚举类 6 | * @author F_xh 7 | * @date 2017年4月28日 下午4:21:31 8 | * 9 | */ 10 | public enum CodeMsgEnum { 11 | //参数请求信息 12 | ILLEGALREQUEST("0","8000","非法请求"), 13 | PARAMERR("0","8001","参数错误"), 14 | CACHEEXPIRED("0","8002","缓存失败"), 15 | 16 | USER_LOGIN_SUCCESS("1","","登陆成功"), 17 | USER_LOGIN_ERROR("0","","账号或密码错误"), 18 | USER_LOGIN_ERROR_ACCOUNT("0","","账号错误"), 19 | USER_LOGIN_ERROR_PW("0","","密码错误"), 20 | USER_SAVE_SUCCESS("1","","修改成功"), 21 | USER_MODIFY_ERROR_PW("0","","原密码错误"), 22 | USER_MODIFY_ERROR_CONFIRM("0","","两次输入不一致"), 23 | 24 | TOKEN_ERROR("1","","Token错误或失效"), 25 | RANDOM_CODE_ERROR("0","","验证码错误"), 26 | 27 | // 复制 28 | COPY_SUCCESS("1", "", "复制成功"), 29 | COPY_ERROR("0", "", "复制失败"), 30 | 31 | // 保存 32 | SAVE_SUCCESS("1", "", "保存成功"), 33 | SAVE_ERROR("0", "", "保存失败"), 34 | SAVE_REFUSE("0", "", "不可编辑"), 35 | 36 | // 查询 37 | SEARCH_SUCCESS("1", "", "查询成功"), 38 | SEARCH_ERROR("0", "", "查询失败"), 39 | 40 | // 删除 41 | DEL_SUCCESS("1", "", "删除成功"), 42 | DEL_ERROR("0", "", "删除失败"), 43 | DEL_REFUSE("0", "", "不可删除"), 44 | 45 | // 是否成功 46 | SUCCESS("1", "", ""), 47 | ERROR("0", "", ""), 48 | 49 | //免责声明,关于 50 | DISCLAIMERABOUTSUCCESS("1","8090","获取成功"), 51 | 52 | /*web enum---------end--*/ 53 | //系统信息 54 | SYSTEM("0","10000","系统异常,请刷新后重试或联系系统管理员"), 55 | 56 | STATUS(),BUSINESSSTATUS(),ITEMS(),MESSAGE(),FEEDBACK(); 57 | 58 | private String code; 59 | private String bunissCode; 60 | private String msg; 61 | 62 | private CodeMsgEnum(String code, String bunissCode, String msg){ 63 | this.code=code; 64 | this.bunissCode=bunissCode; 65 | this.msg=msg; 66 | } 67 | 68 | private CodeMsgEnum(){ 69 | 70 | } 71 | 72 | public String getCode() { 73 | return code; 74 | } 75 | 76 | public void setCode(String code) { 77 | this.code = code; 78 | } 79 | 80 | public String getBunissCode() { 81 | return bunissCode; 82 | } 83 | 84 | public void setBunissCode(String bunissCode) { 85 | this.bunissCode = bunissCode; 86 | } 87 | 88 | public String getMsg() { 89 | return msg; 90 | } 91 | 92 | public void setMsg(String msg) { 93 | this.msg = msg; 94 | } 95 | 96 | public static void main(String[] args){ 97 | System.out.print(CodeMsgEnum.DISCLAIMERABOUTSUCCESS); 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /src/test/resources/demo-user.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : Localhost 5 | Source Server Version : 50713 6 | Source Host : localhost:3306 7 | Source Database : test 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50713 11 | File Encoding : 65001 12 | 13 | Date: 2017-06-23 14:25:27 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | DROP DATABASE IF EXISTS `TEST_USER`; 18 | CREATE DATABASE TEST_USER; 19 | USE TEST_USER; 20 | -- ---------------------------- 21 | -- Table structure for user 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `user`; 24 | CREATE TABLE `user` ( 25 | `id` int(11) NOT NULL AUTO_INCREMENT, 26 | `username` varchar(255) NOT NULL 27 | COMMENT '用户名', 28 | `password` varchar(255) NOT NULL 29 | COMMENT '密码', 30 | `nick_name` varchar(255) DEFAULT NULL 31 | COMMENT '昵称', 32 | `sex` int(1) DEFAULT NULL 33 | COMMENT '性别', 34 | `register_date` datetime NOT NULL 35 | COMMENT '注册日期', 36 | PRIMARY KEY (`id`) 37 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; 38 | 39 | -- ---------------------------- 40 | -- Records of user 41 | -- ---------------------------- 42 | INSERT INTO `user` VALUES ('1', '89921218@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆', '1', '2017-06-23 14:24:23'); 43 | INSERT INTO `user` VALUES ('2', '2@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-2', '1', '2017-06-23 14:24:23'); 44 | INSERT INTO `user` VALUES ('3', '3@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-3', '1', '2017-06-23 14:24:23'); 45 | INSERT INTO `user` VALUES ('4', '4@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-4', '1', '2017-06-23 14:24:23'); 46 | INSERT INTO `user` VALUES ('5', '5@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-5', '1', '2017-06-23 14:24:23'); 47 | INSERT INTO `user` VALUES ('6', '6@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-6', '1', '2017-06-23 14:24:23'); 48 | INSERT INTO `user` VALUES ('7', '7@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-7', '1', '2017-06-23 14:24:23'); 49 | INSERT INTO `user` VALUES ('8', '8@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-8', '1', '2017-06-23 14:24:23'); 50 | INSERT INTO `user` VALUES ('9', '9@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-9', '1', '2017-06-23 14:24:23'); 51 | INSERT INTO `user` VALUES ('10', '10@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-10', '1', '2017-06-23 14:24:23'); 52 | SET FOREIGN_KEY_CHECKS=1; 53 | 54 | SELECT * FROM user; -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/resources/demo-user.sql: -------------------------------------------------------------------------------- 1 | /* 2 | Navicat MySQL Data Transfer 3 | 4 | Source Server : Localhost 5 | Source Server Version : 50713 6 | Source Host : localhost:3306 7 | Source Database : test 8 | 9 | Target Server Type : MYSQL 10 | Target Server Version : 50713 11 | File Encoding : 65001 12 | 13 | Date: 2017-06-23 14:25:27 14 | */ 15 | 16 | SET FOREIGN_KEY_CHECKS=0; 17 | DROP DATABASE IF EXISTS `TEST_USER`; 18 | CREATE DATABASE TEST_USER; 19 | USE TEST_USER; 20 | -- ---------------------------- 21 | -- Table structure for user 22 | -- ---------------------------- 23 | DROP TABLE IF EXISTS `user`; 24 | CREATE TABLE `user` ( 25 | `id` int(11) NOT NULL AUTO_INCREMENT, 26 | `username` varchar(255) NOT NULL 27 | COMMENT '用户名', 28 | `password` varchar(255) NOT NULL 29 | COMMENT '密码', 30 | `nick_name` varchar(255) DEFAULT NULL 31 | COMMENT '昵称', 32 | `sex` int(1) DEFAULT NULL 33 | COMMENT '性别', 34 | `register_date` datetime NOT NULL 35 | COMMENT '注册日期', 36 | PRIMARY KEY (`id`) 37 | ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8; 38 | 39 | -- ---------------------------- 40 | -- Records of user 41 | -- ---------------------------- 42 | INSERT INTO `user` VALUES ('1', '89921218@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆', '1', '2017-06-23 14:24:23'); 43 | INSERT INTO `user` VALUES ('2', '2@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-2', '1', '2017-06-23 14:24:23'); 44 | INSERT INTO `user` VALUES ('3', '3@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-3', '1', '2017-06-23 14:24:23'); 45 | INSERT INTO `user` VALUES ('4', '4@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-4', '1', '2017-06-23 14:24:23'); 46 | INSERT INTO `user` VALUES ('5', '5@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-5', '1', '2017-06-23 14:24:23'); 47 | INSERT INTO `user` VALUES ('6', '6@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-6', '1', '2017-06-23 14:24:23'); 48 | INSERT INTO `user` VALUES ('7', '7@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-7', '1', '2017-06-23 14:24:23'); 49 | INSERT INTO `user` VALUES ('8', '8@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-8', '1', '2017-06-23 14:24:23'); 50 | INSERT INTO `user` VALUES ('9', '9@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-9', '1', '2017-06-23 14:24:23'); 51 | INSERT INTO `user` VALUES ('10', '10@qq.com', '1ee04e0b1cb5af7367c80c22e42efd8b', '土豆-10', '1', '2017-06-23 14:24:23'); 52 | SET FOREIGN_KEY_CHECKS=1; 53 | 54 | SELECT * FROM user; -------------------------------------------------------------------------------- /spring-cloud-learning-01/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | jf.learning 8 | jf.maven 9 | 1.0-SNAPSHOT 10 | pom 11 | 12 | 13 | org.springframework.boot 14 | spring-boot-starter-parent 15 | 2.1.4.RELEASE 16 | 17 | 18 | 19 | 20 | 21 | jf-server 22 | jf-client01 23 | jf-mybatis 24 | 25 | 26 | 27 | 28 | UTF-8 29 | UTF-8 30 | 1.8 31 | Greenwich.SR1 32 | 33 | 34 | 35 | 36 | 37 | org.springframework.cloud 38 | spring-cloud-dependencies 39 | ${spring-cloud.version} 40 | pom 41 | import 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | org.springframework.boot 51 | spring-boot-maven-plugin 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | aliyun-repos 60 | http://maven.aliyun.com/nexus/content/groups/public/ 61 | 62 | false 63 | 64 | 65 | 66 | 67 | 68 | 69 | aliyun-plugin 70 | http://maven.aliyun.com/nexus/content/groups/public/ 71 | 72 | false 73 | 74 | 75 | 76 | 77 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![Licence](https://img.shields.io/badge/licence-none-green.svg) 2 | [![GitHub Release](https://img.shields.io/github/release/lihengming/spring-boot-api-project-seed.svg)](https://github.com/lihengming/spring-boot-api-project-seed/releases) 3 | # First of all 4 | 此项目是在 5 | https://github.com/tangzhimang/spring-boot-api-project-seed-master-self 6 | 以及 7 | https://github.com/lihengming/spring-boot-api-project-seed 8 | 两位的基础上再次开发的 9 | 10 | 主要区别是此项目使用的是mybatis-plus 11 | 12 | 2019-04-29 13 | ### 更新: 14 | 1、简单整合spring-cloud使用eureka 项目目录:spring-cloud-learning-01 15 | 16 | ### 修复: 17 | 1、修改模板文件的包名问题,之后只在core包里ProjectConstant文件中的PROJECT_PATH与BASE_PACKAGE即可 18 | 19 | 20 | 21 | 22 | ## 简介 23 | Spring Boot API Project Seed 是一个基于Spring Boot & MyBatis-plus的种子项目,用于快速构建中小型API、RESTful API项目,该种子项目已经有过多个真实项目的实践,稳定、简单、快速,使我们摆脱那些重复劳动,专注于业务代码的编写,减少加班。下面是一个简单的使用演示,看如何基于本项目在短短几十秒钟内实现一套简单的API,并运行提供服务。 24 | 25 | [![请选择超清](https://raw.githubusercontent.com/lihengming/java-codes/master/shared-resources/github-images/project-example-youku.png)](http://v.youku.com/v_show/id_XMjg1NjYwNDgxNg==.html?spm=a2h3j.8428770.3416059.1) 26 | ## 特征&提供 27 | - 新: 更新项目所有依赖以及插件为最新版本 28 | - 新: 集成Swagger2,同时自动生成简单的API测试说明,生成后访问地址为 http://localhost:8080/doc.html 29 | - 统一响应结果封装及生成工具 30 | - 统一异常处理 31 | - 简单的接口签名认证 32 | - 常用基础方法抽象封装 33 | - 使用Druid Spring Boot Starter 集成Druid数据库连接池与监控 34 | - 使用FastJsonHttpMessageConverter,提高JSON序列化速度 35 | - 集成MyBatis-plus、分页插件,实现单表业务零SQL 36 | - 提供代码生成器根据表名生成对应的Model、Mapper、MapperXML、Service、ServiceImpl、Controller等基础代码,其中Controller模板默认提供POST和RESTful两套,根据需求在```CodeGenerator.genController(tableName)```方法中自己选择,默认使用POST模板。代码模板可根据实际项目的需求来扩展,由于每个公司业务都不太一样,所以只提供了一些比较基础、通用的模板,**主要是提供一个思路**来减少重复代码的编写,我在实际项目的使用中,其实根据公司业务的抽象编写了大量的模板。另外,使用模板也有助于保持团队代码风格的统一 37 | - 另有彩蛋,待你探索 38 |   39 | ## 快速开始 40 | 1. 克隆项目 41 | 2. 对```test```包内的代码生成器```CodeGenerator```进行配置,主要是JDBC,因为要根据表名来生成代码 42 | 3. 如果只是想根据上面的演示来亲自试试的话可以使用```test/resources```目录下的```demo-user.sql```,否则忽略该步 43 | 3. 输入表名,运行```CodeGenerator.main()```方法,生成基础代码(可能需要刷新项目目录才会出来) 44 | 4. 根据业务在基础代码上进行扩展 45 | 5. 对开发环境配置文件```application-dev.properties```进行配置,启动项目,Have Fun! 46 |   47 | ## 开发建议 48 | - 表名,建议使用小写,多个单词使用下划线拼接 49 | - Model内成员变量建议与表字段数量对应,如需扩展成员变量(比如连表查询)建议创建DTO,否则需在扩展的成员变量上加```@Transient```注解,详情见[通用Mapper插件文档说明](https://mapperhelper.github.io/docs/2.use/) 50 | - 建议业务失败直接使用```ServiceException("message")```抛出,由统一异常处理器来封装业务失败的响应结果,比如```throw new ServiceException("该手机号已被注册")```,会直接被封装为```{"code":400,"message":"该手机号已被注册"}```返回,无需自己处理,尽情抛出 51 | - 需要工具类的话建议先从```apache-commons-*```和```guava```中找,实在没有再造轮子或引入类库,尽量精简项目 52 | - 开发规范建议遵循阿里巴巴Java开发手册([最新版下载](https://github.com/alibaba/p3c)) 53 | - 建议在公司内部使用[ShowDoc](https://github.com/star7th/showdoc)、[SpringFox-Swagger2](https://github.com/springfox/springfox) 、[RAP](https://github.com/thx/RAP)等开源项目来编写、管理API文档 54 |   55 | ## 技术选型&文档 56 | - Spring Boot([查看Spring Boot学习&使用指南](http://www.jianshu.com/p/1a9fd8936bd8)) 57 | - MyBatis-plus([查看官方中文文档](https://mp.baomidou.com/)) 58 | - Druid Spring Boot Starter([查看官方中文文档](https://github.com/alibaba/druid/tree/master/druid-spring-boot-starter/)) 59 | - swagger2 ([查看官方文档](https://swagger.io/docs/)) 60 | - 其他略 61 | 62 | ## License 63 | 无,纯粹开源分享。 64 | -------------------------------------------------------------------------------- /src/test/resources/generator/template/controller-restful.ftl: -------------------------------------------------------------------------------- 1 | package ${controllerPackage}; 2 | 3 | import ${basePackage}.model.${modelNameUpperCamel}; 4 | import ${basePackage}.service.${modelNameUpperCamel}Service; 5 | import ${basePackage}.dao.${modelNameUpperCamel}Mapper; 6 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 7 | import com.baomidou.mybatisplus.core.metadata.IPage; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiImplicitParam; 10 | import io.swagger.annotations.ApiImplicitParams; 11 | import io.swagger.annotations.ApiOperation; 12 | import org.springframework.web.bind.annotation.*; 13 | import com.company.project.core.CodeMsgEnum; 14 | import com.company.project.core.MessageResultUtils; 15 | import com.company.project.core.Query; 16 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 17 | import javax.annotation.Resource; 18 | import java.util.Map; 19 | import springfox.documentation.annotations.ApiIgnore; 20 | 21 | /** 22 | * @author ${author} 23 | * @data ${date}. 24 | */ 25 | @RestController 26 | @RequestMapping("${baseRequestMapping}") 27 | @Api(value = "${modelNameUpperCamel}控制类", description = "控制类接口测试") 28 | public class ${modelNameUpperCamel}Controller { 29 | @Resource 30 | private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service; 31 | 32 | @Resource 33 | private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper; 34 | 35 | @GetMapping 36 | @ApiOperation(value = "获取全部",notes = "返回分页过后的数据",httpMethod = "GET") 37 | @ApiImplicitParams({ 38 | @ApiImplicitParam(name = "page",value = "查询页码", paramType = "query",dataType = "Integer",defaultValue = "1"), 39 | @ApiImplicitParam(name = "pageSize",value = "每页数据量", paramType = "query",dataType = "Integer",defaultValue = "10") 40 | }) 41 | 42 | public Map list(@ApiIgnore @RequestParam Map params) { 43 | Page ${modelNameLowerCamel}Page = new Query<>(params); 44 | QueryWrapper<${modelNameUpperCamel}> wrapper = new QueryWrapper<>(); 45 | IPage<${modelNameUpperCamel}> ${modelNameLowerCamel}IPage = ${modelNameLowerCamel}Mapper.selectPage(${modelNameLowerCamel}Page,wrapper); 46 | return MessageResultUtils.getResults(${modelNameLowerCamel}IPage, CodeMsgEnum.SEARCH_SUCCESS); 47 | } 48 | @PostMapping 49 | @ApiOperation(value = "添加数据",notes = "添加新的数据",httpMethod = "POST") 50 | @ApiImplicitParams({ 51 | @ApiImplicitParam(name = "${modelNameLowerCamel}",value = "待添加的${modelNameLowerCamel}实例",paramType = "body",dataType = "${modelNameUpperCamel}",required = true) 52 | }) 53 | public Map add(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}) { 54 | boolean b = ${modelNameLowerCamel}Service.save(${modelNameLowerCamel}); 55 | return MessageResultUtils.getResults(b, CodeMsgEnum.SAVE_SUCCESS); 56 | } 57 | 58 | @DeleteMapping("/{id}") 59 | @ApiOperation(value = "删除数据",notes = "根据id删除数据",httpMethod = "DELETE") 60 | @ApiImplicitParams({ 61 | @ApiImplicitParam(name = "id",value = "查询的id", paramType = "path",required = true,dataType = "Integer"), 62 | }) 63 | public Map delete(@PathVariable Integer id) { 64 | boolean b = ${modelNameLowerCamel}Service.removeById(id); 65 | return MessageResultUtils.getResults(b, CodeMsgEnum.SAVE_SUCCESS); 66 | } 67 | 68 | @PutMapping 69 | @ApiOperation(value = "更新数据",notes = "根据内容更新数据",httpMethod = "PUT") 70 | @ApiImplicitParams({ 71 | @ApiImplicitParam(name = "${modelNameLowerCamel}",value = "更新的${modelNameLowerCamel}实例",paramType = "body",dataType = "${modelNameUpperCamel}",required = true) 72 | }) 73 | public Map update(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}) { 74 | boolean b = ${modelNameLowerCamel}Service.updateById(${modelNameLowerCamel}); 75 | return MessageResultUtils.getResults(b, CodeMsgEnum.SAVE_SUCCESS); 76 | } 77 | 78 | @GetMapping("/{id}") 79 | @ApiOperation(value = "获取单个值",notes = "查看单个项目的内容",httpMethod = "GET") 80 | @ApiImplicitParams({ 81 | @ApiImplicitParam(name = "id",value = "查询的id", paramType = "path",required = true,dataType = "Integer",defaultValue = "0") 82 | }) 83 | public Map detail(@PathVariable Integer id) { 84 | ${modelNameUpperCamel} ${modelNameLowerCamel} = ${modelNameLowerCamel}Service.getById(id); 85 | return MessageResultUtils.getResults(${modelNameLowerCamel}, CodeMsgEnum.SAVE_SUCCESS); 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/resources/generator/template/controller-restful.ftl: -------------------------------------------------------------------------------- 1 | package ${controllerPackage}; 2 | 3 | import ${basePackage}.model.${modelNameUpperCamel}; 4 | import ${basePackage}.service.${modelNameUpperCamel}Service; 5 | import ${basePackage}.dao.${modelNameUpperCamel}Mapper; 6 | import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper; 7 | import com.baomidou.mybatisplus.core.metadata.IPage; 8 | import io.swagger.annotations.Api; 9 | import io.swagger.annotations.ApiImplicitParam; 10 | import io.swagger.annotations.ApiImplicitParams; 11 | import io.swagger.annotations.ApiOperation; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import ${basePackage}.core.CodeMsgEnum; 15 | import ${basePackage}.core.MessageResultUtils; 16 | import ${basePackage}.core.Query; 17 | 18 | import com.baomidou.mybatisplus.extension.plugins.pagination.Page; 19 | import javax.annotation.Resource; 20 | import java.util.Map; 21 | import springfox.documentation.annotations.ApiIgnore; 22 | 23 | /** 24 | * @author ${author} 25 | * @data ${date}. 26 | */ 27 | @RestController 28 | @RequestMapping("${baseRequestMapping}") 29 | @Api(value = "${modelNameUpperCamel}控制类", description = "控制类接口测试") 30 | public class ${modelNameUpperCamel}Controller { 31 | @Resource 32 | private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service; 33 | 34 | @Resource 35 | private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper; 36 | 37 | @GetMapping 38 | @ApiOperation(value = "获取全部",notes = "返回分页过后的数据",httpMethod = "GET") 39 | @ApiImplicitParams({ 40 | @ApiImplicitParam(name = "page",value = "查询页码", paramType = "query",dataType = "Integer",defaultValue = "1"), 41 | @ApiImplicitParam(name = "pageSize",value = "每页数据量", paramType = "query",dataType = "Integer",defaultValue = "10") 42 | }) 43 | 44 | public Map list(@ApiIgnore @RequestParam Map params) { 45 | Page ${modelNameLowerCamel}Page = new Query<>(params); 46 | QueryWrapper<${modelNameUpperCamel}> wrapper = new QueryWrapper<>(); 47 | IPage<${modelNameUpperCamel}> ${modelNameLowerCamel}IPage = ${modelNameLowerCamel}Mapper.selectPage(${modelNameLowerCamel}Page,wrapper); 48 | return MessageResultUtils.getResults(${modelNameLowerCamel}IPage, CodeMsgEnum.SEARCH_SUCCESS); 49 | } 50 | @PostMapping 51 | @ApiOperation(value = "添加数据",notes = "添加新的数据",httpMethod = "POST") 52 | @ApiImplicitParams({ 53 | @ApiImplicitParam(name = "${modelNameLowerCamel}",value = "待添加的${modelNameLowerCamel}实例",paramType = "body",dataType = "${modelNameUpperCamel}",required = true) 54 | }) 55 | public Map add(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}) { 56 | boolean b = ${modelNameLowerCamel}Service.save(${modelNameLowerCamel}); 57 | return MessageResultUtils.getResults(b, CodeMsgEnum.SAVE_SUCCESS); 58 | } 59 | 60 | @DeleteMapping("/{id}") 61 | @ApiOperation(value = "删除数据",notes = "根据id删除数据",httpMethod = "DELETE") 62 | @ApiImplicitParams({ 63 | @ApiImplicitParam(name = "id",value = "查询的id", paramType = "path",required = true,dataType = "Integer"), 64 | }) 65 | public Map delete(@PathVariable Integer id) { 66 | boolean b = ${modelNameLowerCamel}Service.removeById(id); 67 | return MessageResultUtils.getResults(b, CodeMsgEnum.SAVE_SUCCESS); 68 | } 69 | 70 | @PutMapping 71 | @ApiOperation(value = "更新数据",notes = "根据内容更新数据",httpMethod = "PUT") 72 | @ApiImplicitParams({ 73 | @ApiImplicitParam(name = "${modelNameLowerCamel}",value = "更新的${modelNameLowerCamel}实例",paramType = "body",dataType = "${modelNameUpperCamel}",required = true) 74 | }) 75 | public Map update(@RequestBody ${modelNameUpperCamel} ${modelNameLowerCamel}) { 76 | boolean b = ${modelNameLowerCamel}Service.updateById(${modelNameLowerCamel}); 77 | return MessageResultUtils.getResults(b, CodeMsgEnum.SAVE_SUCCESS); 78 | } 79 | 80 | @GetMapping("/{id}") 81 | @ApiOperation(value = "获取单个值",notes = "查看单个项目的内容",httpMethod = "GET") 82 | @ApiImplicitParams({ 83 | @ApiImplicitParam(name = "id",value = "查询的id", paramType = "path",required = true,dataType = "Integer",defaultValue = "0") 84 | }) 85 | public Map detail(@PathVariable Integer id) { 86 | ${modelNameUpperCamel} ${modelNameLowerCamel} = ${modelNameLowerCamel}Service.getById(id); 87 | return MessageResultUtils.getResults(${modelNameLowerCamel}, CodeMsgEnum.SAVE_SUCCESS); 88 | } 89 | } 90 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/log/learing-test.log: -------------------------------------------------------------------------------- 1 | 2019-04-29 14:43:35.386 ERROR 16128 --- [main] o.s.boot.SpringApplication : Application run failed 2 | 3 | org.springframework.boot.context.properties.bind.BindException: Failed to bind properties under 'logging.level' to java.util.Map 4 | at org.springframework.boot.context.properties.bind.Binder.handleBindError(Binder.java:249) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 5 | at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:225) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 6 | at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:208) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 7 | at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:177) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 8 | at org.springframework.boot.context.logging.LoggingApplicationListener.setLogLevels(LoggingApplicationListener.java:342) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 9 | at org.springframework.boot.context.logging.LoggingApplicationListener.initializeFinalLoggingLevels(LoggingApplicationListener.java:318) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 10 | at org.springframework.boot.context.logging.LoggingApplicationListener.initialize(LoggingApplicationListener.java:266) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 11 | at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEnvironmentPreparedEvent(LoggingApplicationListener.java:228) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 12 | at org.springframework.boot.context.logging.LoggingApplicationListener.onApplicationEvent(LoggingApplicationListener.java:201) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 13 | at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] 14 | at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] 15 | at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] 16 | at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:127) ~[spring-context-5.1.6.RELEASE.jar:5.1.6.RELEASE] 17 | at org.springframework.boot.context.event.EventPublishingRunListener.environmentPrepared(EventPublishingRunListener.java:75) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 18 | at org.springframework.boot.SpringApplicationRunListeners.environmentPrepared(SpringApplicationRunListeners.java:54) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 19 | at org.springframework.boot.SpringApplication.prepareEnvironment(SpringApplication.java:347) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 20 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:306) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 21 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:1260) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 22 | at org.springframework.boot.SpringApplication.run(SpringApplication.java:1248) [spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 23 | at com.demo.JfMybatisApplication.main(JfMybatisApplication.java:11) [classes/:na] 24 | Caused by: org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type [java.lang.String] to type [java.util.Map] 25 | at org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321) ~[spring-core-5.1.6.RELEASE.jar:5.1.6.RELEASE] 26 | at org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194) ~[spring-core-5.1.6.RELEASE.jar:5.1.6.RELEASE] 27 | at org.springframework.boot.context.properties.bind.BindConverter$CompositeConversionService.convert(BindConverter.java:177) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 28 | at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:98) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 29 | at org.springframework.boot.context.properties.bind.BindConverter.convert(BindConverter.java:90) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 30 | at org.springframework.boot.context.properties.bind.MapBinder.bindAggregate(MapBinder.java:65) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 31 | at org.springframework.boot.context.properties.bind.AggregateBinder.bind(AggregateBinder.java:58) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 32 | at org.springframework.boot.context.properties.bind.Binder.lambda$bindAggregate$2(Binder.java:304) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 33 | at org.springframework.boot.context.properties.bind.Binder$Context.withIncreasedDepth(Binder.java:448) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 34 | at org.springframework.boot.context.properties.bind.Binder$Context.access$100(Binder.java:388) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 35 | at org.springframework.boot.context.properties.bind.Binder.bindAggregate(Binder.java:303) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 36 | at org.springframework.boot.context.properties.bind.Binder.bindObject(Binder.java:261) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 37 | at org.springframework.boot.context.properties.bind.Binder.bind(Binder.java:220) ~[spring-boot-2.1.4.RELEASE.jar:2.1.4.RELEASE] 38 | ... 18 common frames omitted 39 | 40 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | jf.learning 7 | jf.maven 8 | 1.0-SNAPSHOT 9 | 10 | 11 | jf-mybatisPlus 12 | jf-mybatis 13 | 0.0.1-SNAPSHOT 14 | jf-mybatis 15 | Demo project for Spring Boot 16 | 17 | 18 | 1.8 19 | Greenwich.SR1 20 | 21 | 22 | 23 | 24 | org.springframework.cloud 25 | spring-cloud-starter-netflix-eureka-server 26 | 27 | 28 | 29 | org.springframework.boot 30 | spring-boot-starter-web 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-jdbc 35 | 36 | 37 | org.springframework.boot 38 | spring-boot-starter-test 39 | test 40 | 41 | 42 | 43 | commons-codec 44 | commons-codec 45 | 46 | 47 | 48 | 49 | org.apache.velocity 50 | velocity-engine-core 51 | 2.0 52 | 53 | 54 | cn.hutool 55 | hutool-all 56 | 4.1.2 57 | 58 | 59 | org.projectlombok 60 | lombok 61 | true 62 | 63 | 64 | 65 | com.baomidou 66 | mybatis-plus-boot-starter 67 | 3.0.5 68 | 69 | 70 | 71 | com.baomidou 72 | mybatis-plus-core 73 | 3.0.5 74 | 75 | 76 | 77 | org.apache.commons 78 | commons-lang3 79 | 3.8.1 80 | 81 | 82 | com.google.guava 83 | guava 84 | 27.0-jre 85 | 86 | 87 | 88 | mysql 89 | mysql-connector-java 90 | runtime 91 | 92 | 93 | 94 | tk.mybatis 95 | mapper 96 | 4.0.4 97 | 98 | 99 | com.github.pagehelper 100 | pagehelper 101 | 5.1.8 102 | 103 | 104 | 105 | com.alibaba 106 | fastjson 107 | 1.2.51 108 | 109 | 110 | 111 | com.alibaba 112 | druid-spring-boot-starter 113 | 1.1.10 114 | 115 | 116 | 117 | org.freemarker 118 | freemarker 119 | 2.3.28 120 | test 121 | 122 | 123 | org.mybatis.generator 124 | mybatis-generator-core 125 | 1.3.7 126 | test 127 | 128 | 129 | io.springfox 130 | springfox-swagger2 131 | 2.9.2 132 | 133 | 134 | com.github.xiaoymin 135 | swagger-bootstrap-ui 136 | 1.8.7 137 | 138 | 139 | 140 | 141 | 142 | 143 | src/main/java 144 | 145 | **/*.java 146 | 147 | 148 | 149 | src/main/resources 150 | 151 | **/*.* 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.github.lihengming 8 | spring-boot-api-project-seed 9 | 1.0 10 | jar 11 | 12 | 13 | 1.8 14 | 15 | 16 | 17 | 18 | org.springframework.boot 19 | spring-boot-starter-parent 20 | 2.1.0.RELEASE 21 | 22 | 23 | 24 | 25 | 26 | org.springframework.boot 27 | spring-boot-starter-web 28 | 29 | 30 | org.springframework.boot 31 | spring-boot-starter-jdbc 32 | 33 | 34 | org.springframework.boot 35 | spring-boot-starter-test 36 | test 37 | 38 | 39 | 40 | commons-codec 41 | commons-codec 42 | 43 | 44 | 45 | 46 | org.apache.velocity 47 | velocity-engine-core 48 | 2.0 49 | 50 | 51 | cn.hutool 52 | hutool-all 53 | 4.1.2 54 | 55 | 56 | org.projectlombok 57 | lombok 58 | true 59 | 60 | 61 | 62 | com.baomidou 63 | mybatis-plus-boot-starter 64 | 3.0.5 65 | 66 | 67 | 68 | com.baomidou 69 | mybatis-plus-core 70 | 3.0.5 71 | 72 | 73 | 74 | org.apache.commons 75 | commons-lang3 76 | 3.8.1 77 | 78 | 79 | com.google.guava 80 | guava 81 | 27.0-jre 82 | 83 | 84 | 85 | mysql 86 | mysql-connector-java 87 | runtime 88 | 89 | 90 | 91 | tk.mybatis 92 | mapper 93 | 4.0.4 94 | 95 | 96 | com.github.pagehelper 97 | pagehelper 98 | 5.1.8 99 | 100 | 101 | 102 | com.alibaba 103 | fastjson 104 | 1.2.51 105 | 106 | 107 | 108 | com.alibaba 109 | druid-spring-boot-starter 110 | 1.1.10 111 | 112 | 113 | 114 | org.freemarker 115 | freemarker 116 | 2.3.28 117 | test 118 | 119 | 120 | org.mybatis.generator 121 | mybatis-generator-core 122 | 1.3.7 123 | test 124 | 125 | 126 | io.springfox 127 | springfox-swagger2 128 | 2.9.2 129 | 130 | 131 | com.github.xiaoymin 132 | swagger-bootstrap-ui 133 | 1.8.7 134 | 135 | 136 | 137 | 138 | 139 | 140 | org.springframework.boot 141 | spring-boot-maven-plugin 142 | 143 | 144 | maven-compiler-plugin 145 | 146 | ${java.version} 147 | ${java.version} 148 | UTF-8 149 | 150 | 151 | 152 | 153 | 154 | src/main/java 155 | 156 | **/*.java 157 | 158 | 159 | 160 | src/main/resources 161 | 162 | **/*.* 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | aliyun-repos 171 | http://maven.aliyun.com/nexus/content/groups/public/ 172 | 173 | false 174 | 175 | 176 | 177 | 178 | 179 | 180 | aliyun-plugin 181 | http://maven.aliyun.com/nexus/content/groups/public/ 182 | 183 | false 184 | 185 | 186 | 187 | 188 | 189 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/main/java/com/demo/configurer/WebConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.demo.configurer; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.alibaba.fastjson.support.config.FastJsonConfig; 6 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; 7 | import com.demo.core.CodeMsgEnum; 8 | import com.demo.core.MessageResultUtils; 9 | import com.demo.core.ServiceException; 10 | import org.apache.commons.codec.digest.DigestUtils; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.http.MediaType; 17 | import org.springframework.http.converter.HttpMessageConverter; 18 | import org.springframework.web.method.HandlerMethod; 19 | import org.springframework.web.servlet.HandlerExceptionResolver; 20 | import org.springframework.web.servlet.ModelAndView; 21 | import org.springframework.web.servlet.NoHandlerFoundException; 22 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 23 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 24 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 25 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 26 | 27 | import javax.servlet.ServletException; 28 | import javax.servlet.http.HttpServletRequest; 29 | import javax.servlet.http.HttpServletResponse; 30 | import java.io.IOException; 31 | import java.nio.charset.Charset; 32 | import java.util.ArrayList; 33 | import java.util.Arrays; 34 | import java.util.Collections; 35 | import java.util.List; 36 | 37 | /** 38 | * Spring MVC 配置 39 | * @author Gahon 40 | */ 41 | @Configuration 42 | public class WebConfigurer implements WebMvcConfigurer { 43 | 44 | private final Logger logger = LoggerFactory.getLogger(WebConfigurer.class); 45 | @Value("${spring.profiles.active}") 46 | //当前激活的配置文件 47 | private String dev; 48 | 49 | //使用阿里 FastJson 作为JSON MessageConverter 50 | @Override 51 | public void configureMessageConverters(List> converters) { 52 | FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); 53 | FastJsonConfig config = new FastJsonConfig(); 54 | //保留空的字段 55 | config.setSerializerFeatures(SerializerFeature.WriteMapNullValue); 56 | //SerializerFeature.WriteNullStringAsEmpty,//String null -> "" 57 | //SerializerFeature.WriteNullNumberAsZero//Number null -> 0 58 | // 按需配置,更多参考FastJson文档哈 59 | 60 | converter.setFastJsonConfig(config); 61 | converter.setDefaultCharset(Charset.forName("UTF-8")); 62 | converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8)); 63 | converters.add(converter); 64 | } 65 | 66 | 67 | //统一异常处理 68 | @Override 69 | public void configureHandlerExceptionResolvers(List exceptionResolvers) { 70 | exceptionResolvers.add(new HandlerExceptionResolver() { 71 | @Override 72 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { 73 | //业务失败的异常,如“账号或密码错误” 74 | if (e instanceof ServiceException) { 75 | // 这里几个处理异常都是返回一样的信息,可自行配置 76 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 77 | logger.info(e.getMessage()); 78 | } else if (e instanceof NoHandlerFoundException) { 79 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 80 | } else if (e instanceof ServletException) { 81 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 82 | } else { 83 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 84 | String message; 85 | if (handler instanceof HandlerMethod) { 86 | HandlerMethod handlerMethod = (HandlerMethod) handler; 87 | message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", 88 | request.getRequestURI(), 89 | handlerMethod.getBean().getClass().getName(), 90 | handlerMethod.getMethod().getName(), 91 | e.getMessage()); 92 | } else { 93 | message = e.getMessage(); 94 | } 95 | logger.error(message, e); 96 | } 97 | responseResult(response, CodeMsgEnum.SYSTEM); 98 | return new ModelAndView(); 99 | } 100 | 101 | }); 102 | } 103 | 104 | /** 105 | * @param registry 106 | */ 107 | //解决跨域问题 108 | @Override 109 | public void addCorsMappings(CorsRegistry registry) { 110 | //registry.addMapping("/**"); 111 | } 112 | 113 | /** 114 | * @param registry 115 | */ 116 | //添加拦截器 117 | @Override 118 | public void addInterceptors(InterceptorRegistry registry) { 119 | //接口签名认证拦截器,该签名认证比较简单,实际项目中可以使用Json Web Token或其他更好的方式替代。 120 | if (!"dev".equals(dev)) { 121 | //开发环境忽略签名认证 122 | registry.addInterceptor(new HandlerInterceptorAdapter() { 123 | @Override 124 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 125 | //验证签名 126 | boolean pass = validateSign(request); 127 | if (pass) { 128 | return true; 129 | } else { 130 | logger.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", 131 | request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap())); 132 | responseResult(response, CodeMsgEnum.TOKEN_ERROR); 133 | return false; 134 | } 135 | } 136 | }); 137 | } 138 | } 139 | 140 | private void responseResult(HttpServletResponse response, CodeMsgEnum codeMsgEnum) { 141 | response.setCharacterEncoding("UTF-8"); 142 | response.setHeader("Content-type", "application/json;charset=UTF-8"); 143 | response.setStatus(200); 144 | try { 145 | response.getWriter().write(JSON.toJSONString(codeMsgEnum)); 146 | } catch (IOException ex) { 147 | logger.error(ex.getMessage()); 148 | } 149 | } 150 | 151 | /** 152 | * 一个简单的签名认证,规则: 153 | * 1. 将请求参数按ascii码排序 154 | * 2. 拼接为a=value&b=value...这样的字符串(不包含sign) 155 | * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较 156 | */ 157 | private boolean validateSign(HttpServletRequest request) { 158 | String requestSign = request.getParameter("sign");//获得请求签名,如sign=19e907700db7ad91318424a97c54ed57 159 | if (StringUtils.isEmpty(requestSign)) { 160 | return false; 161 | } 162 | List keys = new ArrayList(request.getParameterMap().keySet()); 163 | keys.remove("sign");//排除sign参数 164 | Collections.sort(keys);//排序 165 | 166 | StringBuilder sb = new StringBuilder(); 167 | for (String key : keys) { 168 | sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串 169 | } 170 | String linkString = sb.toString(); 171 | linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最后一个'&' 172 | 173 | String secret = "Potato";//密钥,自己修改 174 | String sign = DigestUtils.md5Hex(linkString + secret);//混合密钥md5 175 | 176 | return StringUtils.equals(sign, requestSign);//比较 177 | } 178 | 179 | private String getIpAddress(HttpServletRequest request) { 180 | String ip = request.getHeader("x-forwarded-for"); 181 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 182 | ip = request.getHeader("Proxy-Client-IP"); 183 | } 184 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 185 | ip = request.getHeader("WL-Proxy-Client-IP"); 186 | } 187 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 188 | ip = request.getHeader("HTTP_CLIENT_IP"); 189 | } 190 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 191 | ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 192 | } 193 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 194 | ip = request.getRemoteAddr(); 195 | } 196 | // 如果是多级代理,那么取第一个ip为客户端ip 197 | if (ip != null && ip.indexOf(",") != -1) { 198 | ip = ip.substring(0, ip.indexOf(",")).trim(); 199 | } 200 | 201 | return ip; 202 | } 203 | } 204 | -------------------------------------------------------------------------------- /src/main/java/com/company/project/configurer/WebConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.company.project.configurer; 2 | 3 | import com.alibaba.fastjson.JSON; 4 | import com.alibaba.fastjson.serializer.SerializerFeature; 5 | import com.alibaba.fastjson.support.config.FastJsonConfig; 6 | import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter; 7 | import com.company.project.core.CodeMsgEnum; 8 | import com.company.project.core.MessageResultUtils; 9 | import com.company.project.core.ServiceException; 10 | import org.apache.commons.codec.digest.DigestUtils; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.slf4j.Logger; 13 | import org.slf4j.LoggerFactory; 14 | import org.springframework.beans.factory.annotation.Value; 15 | import org.springframework.context.annotation.Configuration; 16 | import org.springframework.http.MediaType; 17 | import org.springframework.http.converter.HttpMessageConverter; 18 | import org.springframework.web.method.HandlerMethod; 19 | import org.springframework.web.servlet.HandlerExceptionResolver; 20 | import org.springframework.web.servlet.ModelAndView; 21 | import org.springframework.web.servlet.NoHandlerFoundException; 22 | import org.springframework.web.servlet.config.annotation.CorsRegistry; 23 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 24 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 25 | import org.springframework.web.servlet.handler.HandlerInterceptorAdapter; 26 | import javax.servlet.ServletException; 27 | import javax.servlet.http.HttpServletRequest; 28 | import javax.servlet.http.HttpServletResponse; 29 | import java.io.IOException; 30 | import java.nio.charset.Charset; 31 | import java.util.ArrayList; 32 | import java.util.Arrays; 33 | import java.util.Collections; 34 | import java.util.List; 35 | 36 | /** 37 | * Spring MVC 配置 38 | * @author Gahon 39 | */ 40 | @Configuration 41 | public class WebConfigurer implements WebMvcConfigurer { 42 | 43 | private final Logger logger = LoggerFactory.getLogger(WebConfigurer.class); 44 | @Value("${spring.profiles.active}") 45 | //当前激活的配置文件 46 | private String env; 47 | 48 | //使用阿里 FastJson 作为JSON MessageConverter 49 | @Override 50 | public void configureMessageConverters(List> converters) { 51 | FastJsonHttpMessageConverter converter = new FastJsonHttpMessageConverter(); 52 | FastJsonConfig config = new FastJsonConfig(); 53 | //保留空的字段 54 | config.setSerializerFeatures(SerializerFeature.WriteMapNullValue); 55 | //SerializerFeature.WriteNullStringAsEmpty,//String null -> "" 56 | //SerializerFeature.WriteNullNumberAsZero//Number null -> 0 57 | // 按需配置,更多参考FastJson文档哈 58 | 59 | converter.setFastJsonConfig(config); 60 | converter.setDefaultCharset(Charset.forName("UTF-8")); 61 | converter.setSupportedMediaTypes(Arrays.asList(MediaType.APPLICATION_JSON_UTF8)); 62 | converters.add(converter); 63 | } 64 | 65 | 66 | //统一异常处理 67 | @Override 68 | public void configureHandlerExceptionResolvers(List exceptionResolvers) { 69 | exceptionResolvers.add(new HandlerExceptionResolver() { 70 | @Override 71 | public ModelAndView resolveException(HttpServletRequest request, HttpServletResponse response, Object handler, Exception e) { 72 | //业务失败的异常,如“账号或密码错误” 73 | if (e instanceof ServiceException) { 74 | // 这里几个处理异常都是返回一样的信息,可自行配置 75 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 76 | logger.info(e.getMessage()); 77 | } else if (e instanceof NoHandlerFoundException) { 78 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 79 | } else if (e instanceof ServletException) { 80 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 81 | } else { 82 | MessageResultUtils.getResults(null,CodeMsgEnum.SYSTEM); 83 | String message; 84 | if (handler instanceof HandlerMethod) { 85 | HandlerMethod handlerMethod = (HandlerMethod) handler; 86 | message = String.format("接口 [%s] 出现异常,方法:%s.%s,异常摘要:%s", 87 | request.getRequestURI(), 88 | handlerMethod.getBean().getClass().getName(), 89 | handlerMethod.getMethod().getName(), 90 | e.getMessage()); 91 | } else { 92 | message = e.getMessage(); 93 | } 94 | logger.error(message, e); 95 | } 96 | responseResult(response, CodeMsgEnum.SYSTEM); 97 | return new ModelAndView(); 98 | } 99 | 100 | }); 101 | } 102 | 103 | /** 104 | * @param registry 105 | */ 106 | //解决跨域问题 107 | @Override 108 | public void addCorsMappings(CorsRegistry registry) { 109 | //registry.addMapping("/**"); 110 | } 111 | 112 | /** 113 | * @param registry 114 | */ 115 | //添加拦截器 116 | @Override 117 | public void addInterceptors(InterceptorRegistry registry) { 118 | //接口签名认证拦截器,该签名认证比较简单,实际项目中可以使用Json Web Token或其他更好的方式替代。 119 | if (!"dev".equals(env)) { 120 | //开发环境忽略签名认证 121 | registry.addInterceptor(new HandlerInterceptorAdapter() { 122 | @Override 123 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { 124 | //验证签名 125 | boolean pass = validateSign(request); 126 | if (pass) { 127 | return true; 128 | } else { 129 | logger.warn("签名认证失败,请求接口:{},请求IP:{},请求参数:{}", 130 | request.getRequestURI(), getIpAddress(request), JSON.toJSONString(request.getParameterMap())); 131 | responseResult(response, CodeMsgEnum.TOKEN_ERROR); 132 | return false; 133 | } 134 | } 135 | }); 136 | } 137 | } 138 | 139 | private void responseResult(HttpServletResponse response, CodeMsgEnum codeMsgEnum) { 140 | response.setCharacterEncoding("UTF-8"); 141 | response.setHeader("Content-type", "application/json;charset=UTF-8"); 142 | response.setStatus(200); 143 | try { 144 | response.getWriter().write(JSON.toJSONString(codeMsgEnum)); 145 | } catch (IOException ex) { 146 | logger.error(ex.getMessage()); 147 | } 148 | } 149 | 150 | /** 151 | * 一个简单的签名认证,规则: 152 | * 1. 将请求参数按ascii码排序 153 | * 2. 拼接为a=value&b=value...这样的字符串(不包含sign) 154 | * 3. 混合密钥(secret)进行md5获得签名,与请求的签名进行比较 155 | */ 156 | private boolean validateSign(HttpServletRequest request) { 157 | String requestSign = request.getParameter("sign");//获得请求签名,如sign=19e907700db7ad91318424a97c54ed57 158 | if (StringUtils.isEmpty(requestSign)) { 159 | return false; 160 | } 161 | List keys = new ArrayList(request.getParameterMap().keySet()); 162 | keys.remove("sign");//排除sign参数 163 | Collections.sort(keys);//排序 164 | 165 | StringBuilder sb = new StringBuilder(); 166 | for (String key : keys) { 167 | sb.append(key).append("=").append(request.getParameter(key)).append("&");//拼接字符串 168 | } 169 | String linkString = sb.toString(); 170 | linkString = StringUtils.substring(linkString, 0, linkString.length() - 1);//去除最后一个'&' 171 | 172 | String secret = "Potato";//密钥,自己修改 173 | String sign = DigestUtils.md5Hex(linkString + secret);//混合密钥md5 174 | 175 | return StringUtils.equals(sign, requestSign);//比较 176 | } 177 | 178 | private String getIpAddress(HttpServletRequest request) { 179 | String ip = request.getHeader("x-forwarded-for"); 180 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 181 | ip = request.getHeader("Proxy-Client-IP"); 182 | } 183 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 184 | ip = request.getHeader("WL-Proxy-Client-IP"); 185 | } 186 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 187 | ip = request.getHeader("HTTP_CLIENT_IP"); 188 | } 189 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 190 | ip = request.getHeader("HTTP_X_FORWARDED_FOR"); 191 | } 192 | if (ip == null || ip.length() == 0 || "unknown".equalsIgnoreCase(ip)) { 193 | ip = request.getRemoteAddr(); 194 | } 195 | // 如果是多级代理,那么取第一个ip为客户端ip 196 | if (ip != null && ip.indexOf(",") != -1) { 197 | ip = ip.substring(0, ip.indexOf(",")).trim(); 198 | } 199 | 200 | return ip; 201 | } 202 | } 203 | -------------------------------------------------------------------------------- /spring-cloud-learning-01/jf-mybatis/src/test/java/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | import com.baomidou.mybatisplus.annotation.DbType; 2 | import com.baomidou.mybatisplus.core.toolkit.StringPool; 3 | import com.baomidou.mybatisplus.generator.AutoGenerator; 4 | import com.baomidou.mybatisplus.generator.InjectionConfig; 5 | import com.baomidou.mybatisplus.generator.config.*; 6 | import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; 7 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; 8 | import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; 9 | import com.google.common.base.CaseFormat; 10 | import freemarker.template.TemplateExceptionHandler; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.mybatis.generator.api.MyBatisGenerator; 13 | import org.mybatis.generator.config.*; 14 | import org.mybatis.generator.internal.DefaultShellCallback; 15 | 16 | import java.io.File; 17 | import java.io.FileWriter; 18 | import java.io.IOException; 19 | import java.text.SimpleDateFormat; 20 | import java.util.*; 21 | 22 | import static com.demo.core.ProjectConstant.*; 23 | /** 24 | * 代码生成器,根据数据表名称生成对应的Model、Mapper、Service、Controller简化开发。 25 | */ 26 | public class CodeGenerator { 27 | //JDBC配置,请修改为你项目的实际配置 28 | private static final String JDBC_URL = "jdbc:mysql://localhost:3306/learning_test"+ "?serverTimezone=GMT%2B8"; 29 | private static final String JDBC_USERNAME = "root"; 30 | private static final String JDBC_PASSWORD = "123456"; 31 | private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver"; 32 | 33 | private static final String TEMPLATE_FILE_PATH = PROJECT_PATH + "/src/test/resources/generator/template";//模板位置 34 | 35 | private static final String JAVA_PATH = PROJECT_PATH + "/src/main/java"; //java文件路径 36 | private static final String RESOURCES_PATH = PROJECT_PATH + "/src/main/resources";//资源文件路径 37 | 38 | private static final String PACKAGE_PATH_SERVICE = packageConvertPath(SERVICE_PACKAGE);//生成的Service存放路径 39 | private static final String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(SERVICE_IMPL_PACKAGE);//生成的Service实现存放路径 40 | private static final String PACKAGE_PATH_CONTROLLER = packageConvertPath(CONTROLLER_PACKAGE);//生成的Controller存放路径 41 | 42 | private static final String AUTHOR = "sjf";//@author 43 | private static final String DATE = new SimpleDateFormat("yyyy-MM-dd").format(new Date());//@date 44 | 45 | public static void main(String[] args) { 46 | genCode("t_user"); 47 | //genCodeByCustomModelName("输入表名","输入自定义Model名称"); 48 | } 49 | 50 | /** 51 | * 通过数据表名称生成代码,Model 名称通过解析数据表名称获得,下划线转大驼峰的形式。 52 | * 如输入表名称 "t_user_detail" 将生成 TUserDetail、TUserDetailMapper、TUserDetailService ... 53 | * @param tableNames 数据表名称... 54 | */ 55 | public static void genCode(String... tableNames) { 56 | for (String tableName : tableNames) { 57 | genCodeByCustomModelName(tableName, null); 58 | } 59 | } 60 | 61 | /** 62 | * 通过数据表名称,和自定义的 Model 名称生成代码 63 | * 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User" 将生成 User、UserMapper、UserService ... 64 | * @param tableName 数据表名称 65 | * @param modelName 自定义的 Model 名称 66 | */ 67 | public static void genCodeByCustomModelName(String tableName, String modelName) { 68 | genModelAndMapper(tableName, modelName); 69 | // genService(tableName, modelName); 70 | genController(tableName, modelName); 71 | } 72 | 73 | 74 | public static void genModelAndMapper(String tableName, String modelName) { 75 | System.out.println(PROJECT_PATH); 76 | Context context = new Context(ModelType.FLAT); 77 | String tmp = context.getProperty("mergeable"); 78 | context.setId("Potato"); 79 | context.setTargetRuntime("MyBatis3Simple"); 80 | context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`"); 81 | context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`"); 82 | 83 | JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration(); 84 | jdbcConnectionConfiguration.setConnectionURL(JDBC_URL); 85 | jdbcConnectionConfiguration.setUserId(JDBC_USERNAME); 86 | jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD); 87 | jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME); 88 | context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration); 89 | 90 | // mybatis plus 91 | 92 | AutoGenerator ag = new AutoGenerator(); 93 | // 全局配置 94 | GlobalConfig gc = new GlobalConfig(); 95 | gc.setOutputDir(JAVA_PATH); // 设置输出目录 96 | gc.setFileOverride(true); //设置文件是否被覆盖 97 | gc.setActiveRecord(true); // 设置是否记录 98 | gc.setSwagger2(true); // 设置Swagger 99 | // gc.setEnableCache(true); // 设置缓存 100 | gc.setBaseResultMap(true); // 设置返回类型 101 | gc.setBaseColumnList(true); // XML columList 102 | gc.setMapperName("%sMapper"); 103 | gc.setXmlName("%sMapper"); 104 | gc.setServiceName("%sService"); 105 | gc.setServiceImplName("%sServiceImpl"); 106 | gc.setControllerName("%sController"); 107 | // 添加全局设置到自动配置里 108 | ag.setGlobalConfig(gc); 109 | 110 | StrategyConfig sc = new StrategyConfig(); 111 | // 数据源配置 112 | DataSourceConfig dsc = new DataSourceConfig(); 113 | dsc.setDbType(DbType.MYSQL); // 设置连接数据库类型 114 | dsc.setDriverName(JDBC_DIVER_CLASS_NAME); 115 | dsc.setUrl(JDBC_URL); 116 | dsc.setUsername(JDBC_USERNAME); 117 | dsc.setPassword(JDBC_PASSWORD); 118 | ag.setDataSource(dsc); 119 | 120 | // 策略配置 121 | sc.entityTableFieldAnnotationEnable(true) 122 | .setCapitalMode(true) 123 | .setEntityLombokModel(true) 124 | // .setTablePrefix(new String[]{"t_"}) 125 | .setRestControllerStyle(true) 126 | .setEntityBuilderModel(true) 127 | .setColumnNaming(NamingStrategy.underline_to_camel) 128 | .setNaming(NamingStrategy.underline_to_camel); // 表名生成策略 129 | 130 | sc.setInclude(tableName); 131 | 132 | ag.setStrategy(sc); 133 | 134 | 135 | // 包设置 136 | PackageConfig pc = new PackageConfig(); 137 | // pc.setModuleName("tbldept");//模块名称,单独生成模块时使用! 138 | pc.setParent(BASE_PACKAGE) 139 | .setEntity("model") 140 | .setController("controller") 141 | .setMapper("dao") 142 | .setXml("XML") 143 | .setService("service") 144 | .setServiceImpl("service.impl"); 145 | ag.setPackageInfo(pc); 146 | TemplateConfig tc = new TemplateConfig(); 147 | tc.setXml(null); 148 | ag.setTemplate(tc); 149 | 150 | // 自定义配置 151 | InjectionConfig cfg = new InjectionConfig() { 152 | @Override 153 | public void initMap() { 154 | // to do nothing 155 | } 156 | }; 157 | 158 | // 如果模板引擎是 freemarker 159 | // String templatePath = "/templates/mapper.xml.ftl"; 160 | // 如果模板引擎是 velocity 161 | String templatePath = "/templates/mapper.xml.vm"; 162 | 163 | // 自定义输出配置 164 | List focList = new ArrayList<>(); 165 | // 自定义配置会被优先输出 166 | focList.add(new FileOutConfig(templatePath) { 167 | @Override 168 | public String outputFile(TableInfo tableInfo) { 169 | // 自定义输出文件名 170 | return RESOURCES_PATH + "/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; 171 | } 172 | }); 173 | cfg.setFileOutConfigList(focList); 174 | ag.setCfg(cfg); 175 | ag.execute(); 176 | } 177 | 178 | public static void genController(String tableName, String modelName) { 179 | try { 180 | freemarker.template.Configuration cfg = getConfiguration(); 181 | 182 | Map data = new HashMap<>(); 183 | data.put("date", DATE); 184 | data.put("author", AUTHOR); 185 | String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName) : modelName; 186 | data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel)); 187 | data.put("modelNameUpperCamel", modelNameUpperCamel); 188 | data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel)); 189 | data.put("basePackage", BASE_PACKAGE); 190 | data.put("controllerPackage", CONTROLLER_PACKAGE); 191 | 192 | File file = new File(JAVA_PATH + PACKAGE_PATH_CONTROLLER + modelNameUpperCamel + "Controller.java"); 193 | if (!file.getParentFile().exists()) { 194 | file.getParentFile().mkdirs(); 195 | } 196 | cfg.getTemplate("controller-restful.ftl").process(data, new FileWriter(file)); 197 | //cfg.getTemplate("controller.ftl").process(data, new FileWriter(file)) 198 | System.out.println(modelNameUpperCamel + "Controller.java 生成成功"); 199 | } catch (Exception e) { 200 | throw new RuntimeException("生成Controller失败", e); 201 | } 202 | } 203 | 204 | private static freemarker.template.Configuration getConfiguration() throws IOException { 205 | freemarker.template.Configuration cfg = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_23); 206 | cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH)); 207 | cfg.setDefaultEncoding("UTF-8"); 208 | cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); 209 | return cfg; 210 | } 211 | 212 | private static String tableNameConvertLowerCamel(String tableName) { 213 | return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase()); 214 | } 215 | 216 | private static String tableNameConvertUpperCamel(String tableName) { 217 | return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase()); 218 | 219 | } 220 | 221 | private static String tableNameConvertMappingPath(String tableName) { 222 | tableName = tableName.toLowerCase();//兼容使用大写的表名 223 | return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName); 224 | } 225 | 226 | private static String modelNameConvertMappingPath(String modelName) { 227 | String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName); 228 | return tableNameConvertMappingPath(tableName); 229 | } 230 | 231 | private static String packageConvertPath(String packageName) { 232 | return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName); 233 | } 234 | 235 | } 236 | -------------------------------------------------------------------------------- /src/test/java/CodeGenerator.java: -------------------------------------------------------------------------------- 1 | import com.baomidou.mybatisplus.annotation.DbType; 2 | import com.baomidou.mybatisplus.core.toolkit.StringPool; 3 | import com.baomidou.mybatisplus.generator.AutoGenerator; 4 | import com.baomidou.mybatisplus.generator.InjectionConfig; 5 | import com.baomidou.mybatisplus.generator.config.*; 6 | import com.baomidou.mybatisplus.generator.config.builder.ConfigBuilder; 7 | import com.baomidou.mybatisplus.generator.config.po.TableInfo; 8 | import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy; 9 | import com.google.common.base.CaseFormat; 10 | import freemarker.template.TemplateExceptionHandler; 11 | import org.apache.commons.lang3.StringUtils; 12 | import org.mybatis.generator.api.MyBatisGenerator; 13 | import org.mybatis.generator.config.*; 14 | import org.mybatis.generator.internal.DefaultShellCallback; 15 | 16 | import java.io.File; 17 | import java.io.FileWriter; 18 | import java.io.IOException; 19 | import java.text.SimpleDateFormat; 20 | import java.util.*; 21 | 22 | import static com.company.project.core.ProjectConstant.*; 23 | /** 24 | * 代码生成器,根据数据表名称生成对应的Model、Mapper、Service、Controller简化开发。 25 | */ 26 | public class CodeGenerator { 27 | //JDBC配置,请修改为你项目的实际配置 28 | private static final String JDBC_URL = "jdbc:mysql://localhost:3306/learning_test"+ "?serverTimezone=GMT%2B8"; 29 | private static final String JDBC_USERNAME = "root"; 30 | private static final String JDBC_PASSWORD = "123456"; 31 | private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver"; 32 | 33 | private static final String PROJECT_PATH = System.getProperty("user.dir");//项目在硬盘上的基础路径 34 | 35 | private static final String TEMPLATE_FILE_PATH = PROJECT_PATH + "/src/test/resources/generator/template";//模板位置 36 | 37 | private static final String JAVA_PATH = PROJECT_PATH + "/src/main/java"; //java文件路径 38 | private static final String RESOURCES_PATH = PROJECT_PATH + "/src/main/resources";//资源文件路径 39 | 40 | private static final String PACKAGE_PATH_SERVICE = packageConvertPath(SERVICE_PACKAGE);//生成的Service存放路径 41 | private static final String PACKAGE_PATH_SERVICE_IMPL = packageConvertPath(SERVICE_IMPL_PACKAGE);//生成的Service实现存放路径 42 | private static final String PACKAGE_PATH_CONTROLLER = packageConvertPath(CONTROLLER_PACKAGE);//生成的Controller存放路径 43 | 44 | private static final String AUTHOR = "sjf";//@author 45 | private static final String DATE = new SimpleDateFormat("yyyy-MM-dd").format(new Date());//@date 46 | 47 | public static void main(String[] args) { 48 | genCode("t_user"); 49 | //genCodeByCustomModelName("输入表名","输入自定义Model名称"); 50 | } 51 | 52 | /** 53 | * 通过数据表名称生成代码,Model 名称通过解析数据表名称获得,下划线转大驼峰的形式。 54 | * 如输入表名称 "t_user_detail" 将生成 TUserDetail、TUserDetailMapper、TUserDetailService ... 55 | * @param tableNames 数据表名称... 56 | */ 57 | public static void genCode(String... tableNames) { 58 | for (String tableName : tableNames) { 59 | genCodeByCustomModelName(tableName, null); 60 | } 61 | } 62 | 63 | /** 64 | * 通过数据表名称,和自定义的 Model 名称生成代码 65 | * 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User" 将生成 User、UserMapper、UserService ... 66 | * @param tableName 数据表名称 67 | * @param modelName 自定义的 Model 名称 68 | */ 69 | public static void genCodeByCustomModelName(String tableName, String modelName) { 70 | genModelAndMapper(tableName, modelName); 71 | // genService(tableName, modelName); 72 | genController(tableName, modelName); 73 | } 74 | 75 | 76 | public static void genModelAndMapper(String tableName, String modelName) { 77 | System.out.println(PROJECT_PATH); 78 | Context context = new Context(ModelType.FLAT); 79 | String tmp = context.getProperty("mergeable"); 80 | context.setId("Potato"); 81 | context.setTargetRuntime("MyBatis3Simple"); 82 | context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`"); 83 | context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`"); 84 | 85 | JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration(); 86 | jdbcConnectionConfiguration.setConnectionURL(JDBC_URL); 87 | jdbcConnectionConfiguration.setUserId(JDBC_USERNAME); 88 | jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD); 89 | jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME); 90 | context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration); 91 | 92 | // mybatis plus 93 | 94 | AutoGenerator ag = new AutoGenerator(); 95 | // 全局配置 96 | GlobalConfig gc = new GlobalConfig(); 97 | gc.setOutputDir(JAVA_PATH); // 设置输出目录 98 | gc.setFileOverride(true); //设置文件是否被覆盖 99 | gc.setActiveRecord(true); // 设置是否记录 100 | gc.setSwagger2(true); // 设置Swagger 101 | // gc.setEnableCache(true); // 设置缓存 102 | gc.setBaseResultMap(true); // 设置返回类型 103 | gc.setBaseColumnList(true); // XML columList 104 | gc.setMapperName("%sMapper"); 105 | gc.setXmlName("%sMapper"); 106 | gc.setServiceName("%sService"); 107 | gc.setServiceImplName("%sServiceImpl"); 108 | gc.setControllerName("%sController"); 109 | // 添加全局设置到自动配置里 110 | ag.setGlobalConfig(gc); 111 | 112 | StrategyConfig sc = new StrategyConfig(); 113 | // 数据源配置 114 | DataSourceConfig dsc = new DataSourceConfig(); 115 | dsc.setDbType(DbType.MYSQL); // 设置连接数据库类型 116 | dsc.setDriverName(JDBC_DIVER_CLASS_NAME); 117 | dsc.setUrl(JDBC_URL); 118 | dsc.setUsername(JDBC_USERNAME); 119 | dsc.setPassword(JDBC_PASSWORD); 120 | ag.setDataSource(dsc); 121 | 122 | // 策略配置 123 | sc.entityTableFieldAnnotationEnable(true) 124 | .setCapitalMode(true) 125 | .setEntityLombokModel(true) 126 | // .setTablePrefix(new String[]{"t_"}) 127 | .setRestControllerStyle(true) 128 | .setEntityBuilderModel(true) 129 | .setColumnNaming(NamingStrategy.underline_to_camel) 130 | .setNaming(NamingStrategy.underline_to_camel); // 表名生成策略 131 | 132 | sc.setInclude(tableName); 133 | 134 | ag.setStrategy(sc); 135 | 136 | 137 | // 包设置 138 | PackageConfig pc = new PackageConfig(); 139 | // pc.setModuleName("tbldept");//模块名称,单独生成模块时使用! 140 | pc.setParent(BASE_PACKAGE) 141 | .setEntity("model") 142 | .setController("controller") 143 | .setMapper("dao") 144 | .setXml("XML") 145 | .setService("service") 146 | .setServiceImpl("service.impl"); 147 | ag.setPackageInfo(pc); 148 | TemplateConfig tc = new TemplateConfig(); 149 | tc.setXml(null); 150 | ag.setTemplate(tc); 151 | 152 | // 自定义配置 153 | InjectionConfig cfg = new InjectionConfig() { 154 | @Override 155 | public void initMap() { 156 | // to do nothing 157 | } 158 | }; 159 | 160 | // 如果模板引擎是 freemarker 161 | // String templatePath = "/templates/mapper.xml.ftl"; 162 | // 如果模板引擎是 velocity 163 | String templatePath = "/templates/mapper.xml.vm"; 164 | 165 | // 自定义输出配置 166 | List focList = new ArrayList<>(); 167 | // 自定义配置会被优先输出 168 | focList.add(new FileOutConfig(templatePath) { 169 | @Override 170 | public String outputFile(TableInfo tableInfo) { 171 | // 自定义输出文件名 172 | return RESOURCES_PATH + "/mapper/" + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML; 173 | } 174 | }); 175 | cfg.setFileOutConfigList(focList); 176 | ag.setCfg(cfg); 177 | ag.execute(); 178 | } 179 | 180 | public static void genController(String tableName, String modelName) { 181 | try { 182 | freemarker.template.Configuration cfg = getConfiguration(); 183 | 184 | Map data = new HashMap<>(); 185 | data.put("date", DATE); 186 | data.put("author", AUTHOR); 187 | String modelNameUpperCamel = StringUtils.isEmpty(modelName) ? tableNameConvertUpperCamel(tableName) : modelName; 188 | data.put("baseRequestMapping", modelNameConvertMappingPath(modelNameUpperCamel)); 189 | data.put("modelNameUpperCamel", modelNameUpperCamel); 190 | data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel)); 191 | data.put("basePackage", BASE_PACKAGE); 192 | data.put("controllerPackage", CONTROLLER_PACKAGE); 193 | 194 | File file = new File(JAVA_PATH + PACKAGE_PATH_CONTROLLER + modelNameUpperCamel + "Controller.java"); 195 | if (!file.getParentFile().exists()) { 196 | file.getParentFile().mkdirs(); 197 | } 198 | cfg.getTemplate("controller-restful.ftl").process(data, new FileWriter(file)); 199 | //cfg.getTemplate("controller.ftl").process(data, new FileWriter(file)) 200 | System.out.println(modelNameUpperCamel + "Controller.java 生成成功"); 201 | } catch (Exception e) { 202 | throw new RuntimeException("生成Controller失败", e); 203 | } 204 | } 205 | 206 | private static freemarker.template.Configuration getConfiguration() throws IOException { 207 | freemarker.template.Configuration cfg = new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_23); 208 | cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH)); 209 | cfg.setDefaultEncoding("UTF-8"); 210 | cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER); 211 | return cfg; 212 | } 213 | 214 | private static String tableNameConvertLowerCamel(String tableName) { 215 | return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase()); 216 | } 217 | 218 | private static String tableNameConvertUpperCamel(String tableName) { 219 | return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase()); 220 | 221 | } 222 | 223 | private static String tableNameConvertMappingPath(String tableName) { 224 | tableName = tableName.toLowerCase();//兼容使用大写的表名 225 | return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName); 226 | } 227 | 228 | private static String modelNameConvertMappingPath(String modelName) { 229 | String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName); 230 | return tableNameConvertMappingPath(tableName); 231 | } 232 | 233 | private static String packageConvertPath(String packageName) { 234 | return String.format("/%s/", packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName); 235 | } 236 | 237 | } 238 | --------------------------------------------------------------------------------