├── src ├── main │ ├── resources │ │ ├── application.yml │ │ ├── static │ │ │ ├── favicon.ico │ │ │ └── image │ │ │ │ └── template.png │ │ ├── application-prod.yml │ │ ├── application-test.yml │ │ ├── templates │ │ │ ├── error.html │ │ │ └── fremarkertemp.html │ │ ├── public │ │ │ └── index.html │ │ ├── log4j2-prod.xml │ │ ├── log4j2-test.xml │ │ ├── application-dev.yml │ │ └── log4j2-dev.xml │ └── java │ │ └── com │ │ └── zimug │ │ └── bootlaunch │ │ ├── model │ │ ├── Reader.java │ │ ├── Address.java │ │ ├── Person.java │ │ └── ArticleVO.java │ │ ├── config │ │ ├── exception │ │ │ ├── ModelView.java │ │ │ ├── CustomExceptionType.java │ │ │ ├── CustomException.java │ │ │ ├── ModelViewException.java │ │ │ ├── ModelViewAspect.java │ │ │ ├── AjaxResponse.java │ │ │ └── WebExceptionHandler.java │ │ ├── DozerBeanMapperConfigure.java │ │ ├── accesslog │ │ │ ├── AccessLog.java │ │ │ └── AccessLogInterceptor.java │ │ ├── MyWebMvcConfigurer.java │ │ ├── Swagger2.java │ │ └── RedisConfig.java │ │ ├── dao │ │ └── PersonRepository.java │ │ ├── service │ │ ├── ArticleRestService.java │ │ ├── ExceptionService.java │ │ └── ArticleMybatisRestServiceImpl.java │ │ ├── BootLaunchApplication.java │ │ ├── controller │ │ ├── LogDemoController.java │ │ ├── RedisSessionController.java │ │ ├── TemplateController.java │ │ ├── HelloController.java │ │ ├── FastdfsController.java │ │ └── ArticleRestController.java │ │ ├── utils │ │ ├── DozerUtils.java │ │ └── AdrressIpUtils.java │ │ └── generator │ │ └── testdb │ │ ├── ArticleMapper.java │ │ ├── Article.java │ │ ├── ArticleMapper.xml │ │ └── ArticleExample.java └── test │ └── java │ └── com │ └── zimug │ └── bootlaunch │ ├── BootLaunchApplicationTests.java │ ├── mybatis │ └── MybatisTest.java │ ├── redis │ ├── RedisRepositoryTest.java │ └── RedisConfigTest.java │ └── restful │ ├── ArticleRestControllerTest.java │ ├── ArticleRestControllerTest2.java │ └── ArticleRestControllerTest3.java ├── .gitignore ├── README.md └── pom.xml /src/main/resources/application.yml: -------------------------------------------------------------------------------- 1 | #需要使用的配置文件 2 | spring: 3 | profiles: 4 | active: dev -------------------------------------------------------------------------------- /src/main/resources/static/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanxt/boot-launch/HEAD/src/main/resources/static/favicon.ico -------------------------------------------------------------------------------- /src/main/resources/static/image/template.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hanxt/boot-launch/HEAD/src/main/resources/static/image/template.png -------------------------------------------------------------------------------- /src/main/resources/application-prod.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8889 3 | 4 | 5 | spring: 6 | jackson: 7 | date-format: yyyy-MM-dd HH:mm:ss 8 | time-zone: GMT+8 9 | 10 | logging: 11 | config: classpath:log4j2-prod.xml -------------------------------------------------------------------------------- /src/main/resources/application-test.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8890 3 | 4 | 5 | spring: 6 | jackson: 7 | date-format: yyyy-MM-dd HH:mm:ss 8 | time-zone: GMT+8 9 | 10 | 11 | logging: 12 | config: classpath:log4j2-prod.xml -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/model/Reader.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.model; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class Reader { 7 | 8 | private String name; 9 | 10 | private int age; 11 | 12 | } 13 | -------------------------------------------------------------------------------- /src/main/resources/templates/error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | error.html 6 | 7 | 8 |

error

9 | 10 |
${exception}
11 |
${url}
12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/ModelView.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | import java.lang.annotation.*; 4 | 5 | @Documented 6 | @Retention(RetentionPolicy.RUNTIME) 7 | @Target({ElementType.METHOD})//只能在方法上使用此注解 8 | public @interface ModelView { 9 | 10 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/dao/PersonRepository.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.dao; 2 | 3 | import com.zimug.bootlaunch.model.Person; 4 | import org.springframework.data.repository.CrudRepository; 5 | 6 | public interface PersonRepository extends CrudRepository { 7 | // 继承CrudRepository,获取基本的CRUD操作 8 | } -------------------------------------------------------------------------------- /src/main/resources/public/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 首页 6 | 7 | 8 | 首页 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/model/Address.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.model; 2 | 3 | import lombok.Data; 4 | 5 | import java.io.Serializable; 6 | 7 | @Data 8 | public class Address implements Serializable { 9 | 10 | private static final long serialVersionUID = -8985545025228238771L; 11 | 12 | String city; 13 | String country; 14 | 15 | public Address(String city, String country) { 16 | this.city = city; 17 | this.country = country; 18 | } 19 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/service/ArticleRestService.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.service; 2 | 3 | import com.zimug.bootlaunch.model.ArticleVO; 4 | 5 | import java.util.List; 6 | 7 | public interface ArticleRestService { 8 | 9 | ArticleVO saveArticle(ArticleVO article); 10 | 11 | void deleteArticle(Long id); 12 | 13 | ArticleVO updateArticle(ArticleVO article); 14 | 15 | ArticleVO getArticle(Long id); 16 | 17 | List getAll(); 18 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/DozerBeanMapperConfigure.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config; 2 | 3 | import org.dozer.DozerBeanMapper; 4 | import org.springframework.context.annotation.Bean; 5 | import org.springframework.context.annotation.Configuration; 6 | 7 | @Configuration 8 | public class DozerBeanMapperConfigure { 9 | @Bean 10 | public DozerBeanMapper mapper() { 11 | DozerBeanMapper mapper = new DozerBeanMapper(); 12 | return mapper; 13 | } 14 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | HELP.md 2 | target/ 3 | !.mvn/wrapper/maven-wrapper.jar 4 | !**/src/main/** 5 | !**/src/test/** 6 | 7 | ### STS ### 8 | .apt_generated 9 | .classpath 10 | .factorypath 11 | .project 12 | .settings 13 | .springBeans 14 | .sts4-cache 15 | 16 | ### IntelliJ IDEA ### 17 | .idea 18 | *.iws 19 | *.iml 20 | *.ipr 21 | 22 | ### NetBeans ### 23 | /nbproject/private/ 24 | /nbbuild/ 25 | /dist/ 26 | /nbdist/ 27 | /.nb-gradle/ 28 | build/ 29 | 30 | ### VS Code ### 31 | .vscode/ 32 | 33 | 34 | logs/ 35 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/accesslog/AccessLog.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.accesslog; 2 | 3 | import lombok.Data; 4 | 5 | import java.util.Date; 6 | 7 | @Data 8 | public class AccessLog { 9 | //访问者用户名 10 | private String username; 11 | //请求路径 12 | private String url; 13 | //请求消耗时长 14 | private Integer duration; 15 | //http 方法:GET、POST等 16 | private String httpMethod; 17 | //http 请求响应状态码 18 | private Integer httpStatus; 19 | //访问者ip 20 | private String ip; 21 | //此条记录的创建时间 22 | private Date createTime; 23 | } -------------------------------------------------------------------------------- /src/main/resources/templates/fremarkertemp.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | freemarker简单示例 6 | 7 | 8 |

Hello Freemarker

9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | <#list articles as article> 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 |
作者教程名称内容
${article.author}${article.title}${article.content}
26 | 27 | 28 | 29 | 30 | 31 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/BootLaunchApplication.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch; 2 | 3 | import org.mybatis.spring.annotation.MapperScan; 4 | import org.springframework.boot.SpringApplication; 5 | import org.springframework.boot.autoconfigure.SpringBootApplication; 6 | import org.springframework.cache.annotation.EnableCaching; 7 | 8 | @SpringBootApplication 9 | @MapperScan(basePackages = {"com.zimug.bootlaunch.generator"}) 10 | @EnableCaching 11 | public class BootLaunchApplication { 12 | 13 | public static void main(String[] args) { 14 | SpringApplication.run(BootLaunchApplication.class, args); 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/BootLaunchApplicationTests.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch; 2 | 3 | import org.junit.Test; 4 | import org.junit.runner.RunWith; 5 | import org.springframework.boot.test.context.SpringBootTest; 6 | import org.springframework.session.data.redis.config.annotation.web.http.EnableRedisHttpSession; 7 | import org.springframework.test.context.junit4.SpringRunner; 8 | 9 | @RunWith(SpringRunner.class) 10 | @SpringBootTest 11 | @EnableRedisHttpSession(maxInactiveIntervalInSeconds = 30 * 60 * 1000) 12 | public class BootLaunchApplicationTests { 13 | 14 | @Test 15 | public void contextLoads() { 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/CustomExceptionType.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | public enum CustomExceptionType { 4 | USER_INPUT_ERROR(400,"用户输入异常"), 5 | SYSTEM_ERROR (500,"系统服务异常"), 6 | OTHER_ERROR(999,"其他未知异常"); 7 | 8 | CustomExceptionType(int code, String typeDesc) { 9 | this.code = code; 10 | this.typeDesc = typeDesc; 11 | } 12 | 13 | private String typeDesc;//异常类型中文描述 14 | 15 | private int code; //code 16 | 17 | public String getTypeDesc() { 18 | return typeDesc; 19 | } 20 | 21 | public int getCode() { 22 | return code; 23 | } 24 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/CustomException.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | public class CustomException extends RuntimeException { 4 | //异常错误编码 5 | private int code ; 6 | //异常信息 7 | private String message; 8 | 9 | private CustomException(){} 10 | 11 | public CustomException(CustomExceptionType exceptionTypeEnum, String message) { 12 | this.code = exceptionTypeEnum.getCode(); 13 | this.message = message; 14 | } 15 | 16 | public int getCode() { 17 | return code; 18 | } 19 | 20 | @Override 21 | public String getMessage() { 22 | return message; 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/model/Person.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.model; 2 | 3 | import lombok.Data; 4 | import org.springframework.data.annotation.Id; 5 | import org.springframework.data.redis.core.RedisHash; 6 | 7 | 8 | import java.io.Serializable; 9 | 10 | @Data 11 | @RedisHash("people") 12 | public class Person implements Serializable { 13 | 14 | private static final long serialVersionUID = -8985545025228238754L; 15 | 16 | @Id 17 | String id; 18 | String firstname; 19 | String lastname; 20 | Address address; 21 | 22 | public Person(String firstname, String lastname) { 23 | this.firstname = firstname; 24 | this.lastname = lastname; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/controller/LogDemoController.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.controller; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.springframework.web.bind.annotation.GetMapping; 5 | import org.springframework.web.bind.annotation.RestController; 6 | 7 | @RestController 8 | @Slf4j 9 | public class LogDemoController { 10 | //private static Logger log= LoggerFactory.getLogger(LogDemo.class); 11 | 12 | @GetMapping("/logdemo") 13 | public String log(){ 14 | log.trace("======trace"); 15 | log.debug("======debug"); 16 | log.info("======info"); 17 | log.warn("======warn"); 18 | log.error("======error"); 19 | return "logok"; 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/ModelViewException.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | public class ModelViewException extends RuntimeException{ 4 | 5 | //异常错误编码 6 | private int code ; 7 | //异常信息 8 | private String message; 9 | 10 | public static ModelViewException transfer(CustomException e) { 11 | return new ModelViewException(e.getCode(),e.getMessage()); 12 | } 13 | 14 | private ModelViewException(int code, String message){ 15 | this.code = code; 16 | this.message = message; 17 | } 18 | 19 | int getCode() { 20 | return code; 21 | } 22 | 23 | @Override 24 | public String getMessage() { 25 | return message; 26 | } 27 | 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/MyWebMvcConfigurer.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config; 2 | 3 | import com.zimug.bootlaunch.config.accesslog.AccessLogInterceptor; 4 | import org.springframework.context.annotation.Configuration; 5 | import org.springframework.web.servlet.config.annotation.InterceptorRegistry; 6 | import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; 7 | 8 | @Configuration 9 | public class MyWebMvcConfigurer implements WebMvcConfigurer { 10 | 11 | //设置排除路径,spring boot 2.*,注意排除掉静态资源的路径,不然静态资源无法访问 12 | private final String[] excludePath = {"/static"}; 13 | 14 | @Override 15 | public void addInterceptors(InterceptorRegistry registry) { 16 | registry.addInterceptor(new AccessLogInterceptor()).addPathPatterns("/**").excludePathPatterns(excludePath); 17 | } 18 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/utils/DozerUtils.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.utils; 2 | 3 | import com.google.common.collect.Lists; 4 | import org.dozer.DozerBeanMapper; 5 | 6 | import java.util.Collection; 7 | import java.util.Iterator; 8 | import java.util.List; 9 | 10 | public class DozerUtils { 11 | 12 | static DozerBeanMapper dozerBeanMapper = new DozerBeanMapper(); 13 | 14 | public static List mapList(Collection sourceList, Class destinationClass){ 15 | List destinationList = Lists.newArrayList(); 16 | for (Iterator i$ = sourceList.iterator(); i$.hasNext();){ 17 | Object sourceObject = i$.next(); 18 | Object destinationObject = dozerBeanMapper.map(sourceObject, destinationClass); 19 | destinationList.add(destinationObject); 20 | } 21 | return destinationList; 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/controller/RedisSessionController.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.controller; 2 | 3 | 4 | import org.springframework.web.bind.annotation.RequestMapping; 5 | import org.springframework.web.bind.annotation.RequestMethod; 6 | import org.springframework.web.bind.annotation.ResponseBody; 7 | import org.springframework.web.bind.annotation.RestController; 8 | 9 | import javax.servlet.http.HttpSession; 10 | import java.util.UUID; 11 | 12 | @RestController 13 | public class RedisSessionController { 14 | 15 | @RequestMapping(value="/uid",method = RequestMethod.GET) 16 | public @ResponseBody 17 | String uid(HttpSession session) { 18 | UUID uid = (UUID) session.getAttribute("uid"); 19 | if (uid == null) { 20 | uid = UUID.randomUUID(); 21 | } 22 | session.setAttribute("uid", uid); 23 | return session.getId(); 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/ModelViewAspect.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.aspectj.lang.annotation.AfterThrowing; 5 | import org.aspectj.lang.annotation.Aspect; 6 | import org.aspectj.lang.annotation.Pointcut; 7 | import org.springframework.stereotype.Component; 8 | 9 | @Aspect 10 | @Component 11 | public class ModelViewAspect { 12 | 13 | //设置切入点:这里直接拦截被@ModelView注解的方法 14 | @Pointcut("@annotation(com.zimug.bootlaunch.config.exception.ModelView)") 15 | public void pointcut() { } 16 | 17 | /** 18 | * 当有ModelView的注解的方法抛出异常的时候,做如下的处理 19 | */ 20 | @AfterThrowing(pointcut="pointcut()",throwing="e") 21 | public void afterThrowable(Throwable e) { 22 | 23 | if(e instanceof CustomException){ 24 | throw ModelViewException.transfer((CustomException) e); 25 | } 26 | } 27 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/model/ArticleVO.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.model; 2 | 3 | 4 | import com.fasterxml.jackson.annotation.*; 5 | import lombok.AllArgsConstructor; 6 | import lombok.Builder; 7 | import lombok.Data; 8 | import lombok.NoArgsConstructor; 9 | 10 | import javax.validation.constraints.NotEmpty; 11 | import java.util.Date; 12 | import java.util.List; 13 | 14 | @Data 15 | @AllArgsConstructor 16 | @NoArgsConstructor 17 | @Builder 18 | @JsonPropertyOrder(value={"content","title"}) 19 | public class ArticleVO { 20 | 21 | //@JsonIgnore 22 | private Long id; 23 | 24 | @JsonProperty("auther") 25 | private String author; 26 | private String title; 27 | @NotEmpty(message = "文章内容不能为空,请检查您的输入") 28 | private String content; 29 | 30 | @JsonInclude(JsonInclude.Include.NON_NULL) 31 | @JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") 32 | private Date createTime; 33 | private List reader; 34 | 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/generator/testdb/ArticleMapper.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.generator.testdb; 2 | 3 | import com.zimug.bootlaunch.generator.testdb.Article; 4 | import com.zimug.bootlaunch.generator.testdb.ArticleExample; 5 | import java.util.List; 6 | import org.apache.ibatis.annotations.Param; 7 | 8 | public interface ArticleMapper { 9 | long countByExample(ArticleExample example); 10 | 11 | int deleteByExample(ArticleExample example); 12 | 13 | int deleteByPrimaryKey(Long id); 14 | 15 | int insert(Article record); 16 | 17 | int insertSelective(Article record); 18 | 19 | List
selectByExample(ArticleExample example); 20 | 21 | Article selectByPrimaryKey(Long id); 22 | 23 | int updateByExampleSelective(@Param("record") Article record, @Param("example") ArticleExample example); 24 | 25 | int updateByExample(@Param("record") Article record, @Param("example") ArticleExample example); 26 | 27 | int updateByPrimaryKeySelective(Article record); 28 | 29 | int updateByPrimaryKey(Article record); 30 | } -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/mybatis/MybatisTest.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.mybatis; 2 | 3 | import com.github.pagehelper.PageHelper; 4 | import com.github.pagehelper.PageInfo; 5 | import com.zimug.bootlaunch.generator.testdb.Article; 6 | import com.zimug.bootlaunch.generator.testdb.ArticleMapper; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.List; 14 | 15 | @RunWith(SpringRunner.class) 16 | @SpringBootTest 17 | public class MybatisTest { 18 | 19 | @Resource 20 | ArticleMapper articleMapper; 21 | 22 | @Test 23 | public void testPageHelper(){ 24 | // 只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询(Select)方法会被分页!!!! 25 | PageHelper.startPage(1, 2); 26 | List
articles = articleMapper.selectByExample(null); 27 | PageInfo
page = PageInfo.of(articles); 28 | System.out.println(page); 29 | } 30 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/service/ExceptionService.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.service; 2 | 3 | import com.zimug.bootlaunch.config.exception.CustomException; 4 | import com.zimug.bootlaunch.config.exception.CustomExceptionType; 5 | import org.springframework.stereotype.Service; 6 | 7 | import java.util.ArrayList; 8 | import java.util.List; 9 | 10 | @Service 11 | public class ExceptionService { 12 | 13 | //服务层,模拟系统异常 14 | public void systemBizError() throws CustomException { 15 | try { 16 | Class.forName("com.mysql.jdbc.xxxx.Driver"); 17 | } catch (ClassNotFoundException e) { 18 | throw new CustomException(CustomExceptionType.SYSTEM_ERROR,"在XXX业务,myBiz()方法内,出现ClassNotFoundException"); 19 | } 20 | } 21 | 22 | //服务层,模拟用户输入数据导致的校验异常 23 | public List userBizError(int input) throws CustomException { 24 | if(input < 0){ //模拟业务校验失败逻辑 25 | throw new CustomException(CustomExceptionType.USER_INPUT_ERROR,"您输入的数据不符合业务逻辑,请确认后重新输入!"); 26 | }else{ // 27 | List list = new ArrayList<>(); 28 | list.add("科比"); 29 | list.add("詹姆斯"); 30 | list.add("库里"); 31 | return list; 32 | } 33 | } 34 | 35 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/Swagger2.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config; 2 | 3 | import org.springframework.context.annotation.Bean; 4 | import org.springframework.context.annotation.Configuration; 5 | import springfox.documentation.builders.ApiInfoBuilder; 6 | import springfox.documentation.builders.PathSelectors; 7 | import springfox.documentation.builders.RequestHandlerSelectors; 8 | import springfox.documentation.service.ApiInfo; 9 | import springfox.documentation.spi.DocumentationType; 10 | import springfox.documentation.spring.web.plugins.Docket; 11 | import springfox.documentation.swagger2.annotations.EnableSwagger2; 12 | 13 | @Configuration 14 | @EnableSwagger2 15 | public class Swagger2 { 16 | 17 | @Bean 18 | public Docket createRestApi() { 19 | return new Docket(DocumentationType.SWAGGER_2) 20 | .apiInfo(apiInfo()) 21 | .select() 22 | .apis(RequestHandlerSelectors.basePackage("com.zimug.bootlaunch")) 23 | .paths(PathSelectors.regex("/rest/.*")) 24 | .build(); 25 | } 26 | 27 | private ApiInfo apiInfo() { 28 | return new ApiInfoBuilder() 29 | .title("springboot利用swagger构建api文档") 30 | .description("简单优雅的restfun风格") 31 | .termsOfServiceUrl("http://www.zimug.com") 32 | .version("1.0") 33 | .build(); 34 | } 35 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/controller/TemplateController.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.controller; 2 | 3 | import com.zimug.bootlaunch.config.exception.ModelView; 4 | import com.zimug.bootlaunch.model.ArticleVO; 5 | import com.zimug.bootlaunch.service.ArticleRestService; 6 | import com.zimug.bootlaunch.service.ExceptionService; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.ui.Model; 9 | import org.springframework.web.bind.annotation.GetMapping; 10 | import org.springframework.web.bind.annotation.RequestMapping; 11 | 12 | import javax.annotation.Resource; 13 | import java.util.List; 14 | 15 | @Controller 16 | @RequestMapping("/template") 17 | public class TemplateController { 18 | 19 | @Resource(name="articleMybatisRestServiceImpl") 20 | ArticleRestService articleRestService; 21 | 22 | @Resource 23 | ExceptionService exceptionService; 24 | 25 | @ModelView 26 | @GetMapping("/freemarker") 27 | public String index(Model model) { 28 | 29 | List articles = articleRestService.getAll(); 30 | 31 | model.addAttribute("articles", articles); 32 | exceptionService.systemBizError(); 33 | 34 | //模版名称,实际的目录为:resources/templates/fremarkertemp.html 35 | return "fremarkertemp"; 36 | } 37 | } -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/redis/RedisRepositoryTest.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.redis; 2 | 3 | import com.zimug.bootlaunch.dao.PersonRepository; 4 | import com.zimug.bootlaunch.model.Address; 5 | import com.zimug.bootlaunch.model.Person; 6 | import org.junit.Test; 7 | import org.junit.runner.RunWith; 8 | import org.springframework.beans.factory.annotation.Autowired; 9 | import org.springframework.boot.test.context.SpringBootTest; 10 | import org.springframework.test.context.junit4.SpringRunner; 11 | 12 | import java.util.Optional; 13 | 14 | @RunWith(SpringRunner.class) 15 | @SpringBootTest 16 | public class RedisRepositoryTest { 17 | 18 | @Autowired 19 | PersonRepository personRepository; 20 | 21 | @Test 22 | public void test(){ 23 | 24 | Person rand = new Person("kobe", "byrant"); 25 | rand.setAddress(new Address("luosanji", "USA")); 26 | personRepository.save(rand); 27 | Optional op = personRepository.findById(rand.getId()); 28 | Person p2 = op.get(); 29 | personRepository.count(); 30 | //personRepository.delete(rand); 31 | 32 | } 33 | 34 | @Test 35 | public void testDelete(){ 36 | 37 | 38 | personRepository.deleteById("24bda079-619f-438e-a8c8-cfc3f1aab487"); 39 | 40 | } 41 | 42 | } -------------------------------------------------------------------------------- /src/main/resources/log4j2-prod.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/resources/log4j2-test.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/controller/HelloController.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.controller; 2 | 3 | import com.zimug.bootlaunch.config.exception.AjaxResponse; 4 | import com.zimug.bootlaunch.model.ArticleVO; 5 | import com.zimug.bootlaunch.service.ExceptionService; 6 | import lombok.extern.slf4j.Slf4j; 7 | import org.springframework.web.bind.annotation.RequestMapping; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | import org.springframework.web.bind.annotation.RestController; 10 | 11 | import javax.annotation.Resource; 12 | 13 | @Slf4j 14 | @RestController 15 | public class HelloController { 16 | 17 | @Resource 18 | ExceptionService exceptionService; 19 | 20 | //private static final Logger log = LoggerFactory.getLogger(HelloController.class); 21 | 22 | @RequestMapping("/hello") 23 | public ArticleVO hello() { 24 | /*ArticleRestService article = new ArticleRestService(1L,"zimug"); 25 | 26 | article.setAuthor("字母哥");*/ 27 | 28 | ArticleVO article1 = ArticleVO.builder().id(3L).author("莫言").build(); 29 | 30 | log.info("测试一下" + article1); 31 | 32 | return article1; 33 | } 34 | 35 | 36 | 37 | @RequestMapping("/ex/system") 38 | public @ResponseBody AjaxResponse system() { 39 | 40 | exceptionService.systemBizError(); 41 | 42 | return AjaxResponse.success(); 43 | } 44 | 45 | 46 | @RequestMapping("/ex/user") 47 | public @ResponseBody AjaxResponse user(Integer input) { 48 | 49 | return AjaxResponse.success(exceptionService.userBizError(input)); 50 | } 51 | 52 | } 53 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/AjaxResponse.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | import lombok.Data; 4 | 5 | @Data 6 | public class AjaxResponse { 7 | 8 | 9 | private boolean isok; 10 | private int code; 11 | private String message; 12 | private Object data; 13 | 14 | private AjaxResponse() { 15 | 16 | } 17 | 18 | //请求出现异常时的响应数据封装 19 | public static AjaxResponse error(CustomException e) { 20 | 21 | AjaxResponse resultBean = new AjaxResponse(); 22 | resultBean.setIsok(false); 23 | resultBean.setCode(e.getCode()); 24 | if(e.getCode() == CustomExceptionType.USER_INPUT_ERROR.getCode()){ 25 | resultBean.setMessage(e.getMessage()); 26 | }else if(e.getCode() == CustomExceptionType.SYSTEM_ERROR.getCode()){ 27 | resultBean.setMessage(e.getMessage() + ",系统出现异常,请联系管理员电话:1375610xxxx进行处理!"); 28 | }else{ 29 | resultBean.setMessage("系统出现未知异常,请联系管理员电话:13756108xxx进行处理!"); 30 | } 31 | return resultBean; 32 | } 33 | 34 | public static AjaxResponse success() { 35 | AjaxResponse resultBean = new AjaxResponse(); 36 | resultBean.setIsok(true); 37 | resultBean.setCode(200); 38 | resultBean.setMessage("success"); 39 | return resultBean; 40 | } 41 | 42 | public static AjaxResponse success(Object data) { 43 | AjaxResponse resultBean = new AjaxResponse(); 44 | resultBean.setIsok(true); 45 | resultBean.setCode(200); 46 | resultBean.setMessage("success"); 47 | resultBean.setData(data); 48 | return resultBean; 49 | } 50 | 51 | 52 | } -------------------------------------------------------------------------------- /src/main/resources/application-dev.yml: -------------------------------------------------------------------------------- 1 | server: 2 | port: 8888 3 | 4 | 5 | spring: 6 | jackson: 7 | date-format: yyyy-MM-dd HH:mm:ss 8 | time-zone: GMT+8 9 | datasource: 10 | url: jdbc:mysql://192.168.161.3:3306/testdb?useUnicode=true&characterEncoding=utf-8&useSSL=false 11 | username: test 12 | password: 4rfv$RFV 13 | driver-class-name: com.mysql.jdbc.Driver 14 | freemarker: 15 | cache: false # 缓存配置 开发阶段应该配置为false 因为经常会改 16 | suffix: .html # 模版后缀名 默认为ftl 17 | charset: UTF-8 # 文件编码 18 | template-loader-path: classpath:/templates/ 19 | redis: 20 | database: 0 # Redis 数据库索引(默认为 0) 21 | host: 192.168.161.3 # Redis 服务器地址 22 | port: 6379 # Redis 服务器连接端口 23 | password: 123456 # Redis 服务器连接密码(默认为空) 24 | lettuce: 25 | pool: 26 | max-active: 8 # 连接池最大连接数(使用负值表示没有限制) 默认 8 27 | max-wait: -1 # 连接池最大阻塞等待时间(使用负值表示没有限制) 默认 -1 28 | max-idle: 8 # 连接池中的最大空闲连接 默认 8 29 | min-idle: 0 # 连接池中的最小空闲连接 默认 0 30 | cache: 31 | type: redis 32 | redis: 33 | time-to-live: 600 34 | 35 | caching: 36 | ttlmap: 37 | article: 10 38 | articleAll: 20 39 | 40 | logging: 41 | config: classpath:log4j2-dev.xml 42 | 43 | mybatis: 44 | configuration: 45 | mapUnderscoreToCamelCase: true 46 | 47 | 48 | zimug: 49 | fastdfs: 50 | httpserver: http://192.168.161.3:8888/ #这个不是fastdfs属性,但是填上之后,在使用FastDFSClientUtil会得到完整的http文件访问路径 51 | connect_timeout: 5 52 | network_timeout: 30 53 | charset: UTF-8 54 | tracker_server: # tracker_server 可以配置成数组 55 | - 192.168.161.3:22122 56 | max_total: 50 57 | http_anti_steal_token: false # 如果有防盗链的话,这里true 58 | http_secret_key: # 有防盗链,这里填secret_key -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/controller/FastdfsController.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.controller; 2 | 3 | import com.zimug.bootlaunch.config.exception.AjaxResponse; 4 | import com.zimug.bootlaunch.config.exception.CustomException; 5 | import com.zimug.bootlaunch.config.exception.CustomExceptionType; 6 | import com.zimug.spring.fastdfs.FastDFSClientUtil; 7 | import org.springframework.stereotype.Controller; 8 | import org.springframework.web.bind.annotation.*; 9 | import org.springframework.web.multipart.MultipartFile; 10 | 11 | import javax.annotation.Resource; 12 | 13 | @Controller 14 | @RequestMapping("fastdfs") 15 | public class FastdfsController { 16 | 17 | @Resource 18 | private FastDFSClientUtil fastDFSClientUtil; 19 | 20 | @PostMapping("/upload") 21 | @ResponseBody 22 | public AjaxResponse upload(@RequestParam("file") MultipartFile file) { 23 | 24 | String fileId; 25 | try { 26 | String originalfileName = file.getOriginalFilename(); 27 | fileId = fastDFSClientUtil.uploadFile(file.getBytes(),originalfileName.substring(originalfileName.lastIndexOf("."))); 28 | return AjaxResponse.success(fastDFSClientUtil.getSourceUrl(fileId)); 29 | } catch (Exception e) { 30 | throw new CustomException(CustomExceptionType.SYSTEM_ERROR,"文件上传图片服务器失败"); 31 | } 32 | } 33 | 34 | 35 | @DeleteMapping("/delete") 36 | @ResponseBody 37 | public AjaxResponse upload(@RequestParam String fileid) { 38 | try { 39 | fastDFSClientUtil.delete(fileid); 40 | byte[] imgfile = fastDFSClientUtil.downloadFile(fileid); 41 | } catch (Exception e) { 42 | throw new CustomException(CustomExceptionType.SYSTEM_ERROR,"文件删除失败"); 43 | } 44 | return AjaxResponse.success(); 45 | } 46 | 47 | 48 | } 49 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/utils/AdrressIpUtils.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.utils; 2 | 3 | import org.apache.commons.lang3.StringUtils; 4 | 5 | import javax.servlet.http.HttpServletRequest; 6 | 7 | public class AdrressIpUtils { 8 | /** 9 | * 获取Ip地址 10 | * @param request HttpServletRequest 11 | * @return ip 12 | */ 13 | public static String getIpAdrress(HttpServletRequest request) { 14 | String Xip = request.getHeader("X-Real-IP"); 15 | String XFor = request.getHeader("X-Forwarded-For"); 16 | if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){ 17 | //多次反向代理后会有多个ip值,第一个ip才是真实ip 18 | int index = XFor.indexOf(","); 19 | if(index != -1){ 20 | return XFor.substring(0,index); 21 | }else{ 22 | return XFor; 23 | } 24 | } 25 | XFor = Xip; 26 | if(StringUtils.isNotEmpty(XFor) && !"unKnown".equalsIgnoreCase(XFor)){ 27 | return XFor; 28 | } 29 | if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { 30 | XFor = request.getHeader("Proxy-Client-IP"); 31 | } 32 | if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { 33 | XFor = request.getHeader("WL-Proxy-Client-IP"); 34 | } 35 | if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { 36 | XFor = request.getHeader("HTTP_CLIENT_IP"); 37 | } 38 | if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { 39 | XFor = request.getHeader("HTTP_X_FORWARDED_FOR"); 40 | } 41 | if (StringUtils.isBlank(XFor) || "unknown".equalsIgnoreCase(XFor)) { 42 | XFor = request.getRemoteAddr(); 43 | } 44 | return XFor; 45 | } 46 | } -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/restful/ArticleRestControllerTest.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.restful; 2 | 3 | import com.zimug.bootlaunch.controller.ArticleRestController; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.junit.Before; 6 | import org.junit.Test; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.http.HttpMethod; 9 | import org.springframework.test.web.servlet.MockMvc; 10 | import org.springframework.test.web.servlet.MvcResult; 11 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 12 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; 13 | import org.springframework.test.web.servlet.setup.MockMvcBuilders; 14 | 15 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 16 | 17 | //@Transactional 18 | @Slf4j 19 | @SpringBootTest 20 | public class ArticleRestControllerTest { 21 | 22 | private MockMvc mockMvc; 23 | 24 | @Before 25 | public void setUp() { 26 | mockMvc = MockMvcBuilders.standaloneSetup(new ArticleRestController()).build(); 27 | } 28 | 29 | /*@Test 30 | public void saveArticle() throws Exception { 31 | 32 | String article = "{\n" + 33 | " \"id\": 1,\n" + 34 | " \"author\": \"zimug\",\n" + 35 | " \"title\": \"手摸手教你开发spring boot\",\n" + 36 | " \"content\": \"c\",\n" + 37 | " \"createTime\": \"2017-07-16 05:23:34\",\n" + 38 | " \"reader\":[{\"name\":\"zimug\",\"age\":18},{\"name\":\"kobe\",\"age\":37}]\n" + 39 | "}"; 40 | MvcResult result = mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/article") 41 | .contentType("application/json").content(article)) 42 | .andExpect(MockMvcResultMatchers.status().isOk()) 43 | .andExpect(MockMvcResultMatchers.jsonPath("$.data.author").value("zimug")) 44 | .andExpect(MockMvcResultMatchers.jsonPath("$.data.reader[0].age").value(18)) 45 | .andDo(print()) 46 | .andReturn(); 47 | 48 | log.info(result.getResponse().getContentAsString()); 49 | 50 | }*/ 51 | } -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/restful/ArticleRestControllerTest2.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.restful; 2 | 3 | import lombok.extern.slf4j.Slf4j; 4 | import org.junit.Test; 5 | import org.junit.runner.RunWith; 6 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 7 | import org.springframework.boot.test.context.SpringBootTest; 8 | import org.springframework.http.HttpMethod; 9 | import org.springframework.test.context.junit4.SpringRunner; 10 | import org.springframework.test.web.servlet.MockMvc; 11 | import org.springframework.test.web.servlet.MvcResult; 12 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 13 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; 14 | 15 | import javax.annotation.Resource; 16 | 17 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 18 | 19 | //@Transactional 20 | @Slf4j 21 | @RunWith(SpringRunner.class) 22 | @AutoConfigureMockMvc 23 | @SpringBootTest 24 | public class ArticleRestControllerTest2 { 25 | 26 | @Resource 27 | private MockMvc mockMvc; 28 | 29 | /*@Before 30 | public void setUp() { 31 | mockMvc = MockMvcBuilders.standaloneSetup(new ArticleRestController()).build(); 32 | }*/ 33 | 34 | @Test 35 | public void saveArticle() throws Exception { 36 | 37 | String article = "{\n" + 38 | " \"id\": 1,\n" + 39 | " \"author\": \"zimug\",\n" + 40 | " \"title\": \"手摸手教你开发spring boot\",\n" + 41 | " \"content\": \"c\",\n" + 42 | " \"createTime\": \"2017-07-16 05:23:34\",\n" + 43 | " \"reader\":[{\"name\":\"zimug\",\"age\":18},{\"name\":\"kobe\",\"age\":37}]\n" + 44 | "}"; 45 | MvcResult result = mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/article") 46 | .contentType("application/json").content(article)) 47 | .andExpect(MockMvcResultMatchers.status().isOk()) 48 | .andExpect(MockMvcResultMatchers.jsonPath("$.data.author").value("zimug")) 49 | .andExpect(MockMvcResultMatchers.jsonPath("$.data.reader[0].age").value(18)) 50 | .andDo(print()) 51 | .andReturn(); 52 | 53 | log.info(result.getResponse().getContentAsString()); 54 | 55 | } 56 | } -------------------------------------------------------------------------------- /src/main/resources/log4j2-dev.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/accesslog/AccessLogInterceptor.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.accesslog; 2 | 3 | import com.zimug.bootlaunch.utils.AdrressIpUtils; 4 | import lombok.extern.slf4j.Slf4j; 5 | import org.springframework.web.servlet.HandlerInterceptor; 6 | 7 | import javax.servlet.http.HttpServletRequest; 8 | import javax.servlet.http.HttpServletResponse; 9 | import java.util.Date; 10 | 11 | @Slf4j 12 | public class AccessLogInterceptor implements HandlerInterceptor { 13 | //请求开始时间标识 14 | private static final String LOGGER_SEND_TIME = "SEND_TIME"; 15 | //请求日志实体标识 16 | private static final String LOGGER_ACCESSLOG = "ACCESSLOG_ENTITY"; 17 | 18 | /** 19 | * 进入SpringMVC的Controller之前开始记录日志实体 20 | */ 21 | @Override 22 | public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object o) throws Exception { 23 | 24 | //创建日志实体 25 | AccessLog accessLog = new AccessLog(); 26 | 27 | // 设置IP地址 28 | accessLog.setIp(AdrressIpUtils.getIpAdrress(request)); 29 | 30 | //设置请求方法,GET,POST... 31 | accessLog.setHttpMethod(request.getMethod()); 32 | 33 | //设置请求路径 34 | accessLog.setUrl(request.getRequestURI()); 35 | 36 | //设置请求开始时间 37 | request.setAttribute(LOGGER_SEND_TIME,System.currentTimeMillis()); 38 | 39 | //设置请求实体到request内,方便afterCompletion方法调用 40 | request.setAttribute(LOGGER_ACCESSLOG,accessLog); 41 | return true; 42 | } 43 | 44 | 45 | @Override 46 | public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object o, Exception e) throws Exception { 47 | 48 | //获取本次请求日志实体 49 | AccessLog accessLog = (AccessLog) request.getAttribute(LOGGER_ACCESSLOG); 50 | 51 | //获取请求错误码,根据需求存入数据库,这里不保存 52 | int status = response.getStatus(); 53 | accessLog.setHttpStatus(status); 54 | 55 | //request.getSession().getAttribute("username"); 56 | //设置访问者(这里暂时写死) 57 | // 因为不同的应用可能将访问者信息放在session里面,有的通过request传递, 58 | // 总之可以获取到,但获取的方法不同 59 | accessLog.setUsername("admin"); 60 | 61 | //当前时间 62 | long currentTime = System.currentTimeMillis(); 63 | 64 | //请求开始时间 65 | long snedTime = Long.valueOf(request.getAttribute(LOGGER_SEND_TIME).toString()); 66 | 67 | 68 | //设置请求时间差 69 | accessLog.setDuration(Integer.valueOf((currentTime - snedTime)+"")); 70 | 71 | accessLog.setCreateTime(new Date()); 72 | //将sysLog对象持久化保存 73 | log.info(accessLog.toString()); 74 | } 75 | } 76 | 77 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/exception/WebExceptionHandler.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config.exception; 2 | 3 | import org.springframework.validation.BindException; 4 | import org.springframework.validation.FieldError; 5 | import org.springframework.web.bind.MethodArgumentNotValidException; 6 | import org.springframework.web.bind.annotation.ControllerAdvice; 7 | import org.springframework.web.bind.annotation.ExceptionHandler; 8 | import org.springframework.web.bind.annotation.ResponseBody; 9 | import org.springframework.web.servlet.ModelAndView; 10 | 11 | import javax.servlet.http.HttpServletRequest; 12 | 13 | @ControllerAdvice 14 | public class WebExceptionHandler { 15 | @ExceptionHandler(ModelViewException.class) 16 | public ModelAndView viewExceptionHandler(HttpServletRequest req, ModelViewException e) { 17 | ModelAndView modelAndView = new ModelAndView(); 18 | 19 | //将异常信息设置如modelAndView 20 | modelAndView.addObject("exception", e); 21 | modelAndView.addObject("url", req.getRequestURL()); 22 | modelAndView.setViewName("error"); 23 | 24 | //返回ModelAndView 25 | return modelAndView; 26 | } 27 | 28 | @ExceptionHandler(MethodArgumentNotValidException.class) 29 | @ResponseBody 30 | public AjaxResponse handleBindException(MethodArgumentNotValidException ex) { 31 | FieldError fieldError = ex.getBindingResult().getFieldError(); 32 | return AjaxResponse.error(new CustomException(CustomExceptionType.USER_INPUT_ERROR,fieldError.getDefaultMessage())); 33 | } 34 | 35 | 36 | @ExceptionHandler(BindException.class) 37 | @ResponseBody 38 | public AjaxResponse handleBindException(BindException ex) { 39 | FieldError fieldError = ex.getBindingResult().getFieldError(); 40 | return AjaxResponse.error(new CustomException(CustomExceptionType.USER_INPUT_ERROR,fieldError.getDefaultMessage())); 41 | } 42 | 43 | @ExceptionHandler(CustomException.class) 44 | @ResponseBody 45 | public AjaxResponse customerException(CustomException e) { 46 | if(e.getCode() == CustomExceptionType.SYSTEM_ERROR.getCode()){ 47 | //400异常不需要持久化,将异常信息以友好的方式告知用户就可以 48 | //TODO 将500异常信息持久化处理,方便运维人员处理 49 | } 50 | return AjaxResponse.error(e); 51 | } 52 | 53 | 54 | @ExceptionHandler(Exception.class) 55 | @ResponseBody 56 | public AjaxResponse exception(Exception e) { 57 | //TODO 将异常信息持久化处理,方便运维人员处理 58 | 59 | //没有被程序员发现,并转换为CustomException的异常,都是其他异常或者未知异常. 60 | return AjaxResponse.error(new CustomException(CustomExceptionType.OTHER_ERROR,"未知异常")); 61 | } 62 | 63 | 64 | } 65 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/service/ArticleMybatisRestServiceImpl.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.service; 2 | 3 | import com.zimug.bootlaunch.generator.testdb.Article; 4 | import com.zimug.bootlaunch.generator.testdb.ArticleMapper; 5 | import com.zimug.bootlaunch.model.ArticleVO; 6 | import com.zimug.bootlaunch.utils.DozerUtils; 7 | import lombok.extern.slf4j.Slf4j; 8 | 9 | import org.dozer.Mapper; 10 | import org.springframework.cache.annotation.CacheEvict; 11 | import org.springframework.cache.annotation.CachePut; 12 | import org.springframework.cache.annotation.Cacheable; 13 | import org.springframework.cache.annotation.Caching; 14 | import org.springframework.stereotype.Service; 15 | 16 | import javax.annotation.Resource; 17 | import java.util.List; 18 | 19 | @Slf4j 20 | @Service 21 | public class ArticleMybatisRestServiceImpl implements ArticleRestService{ 22 | 23 | @Resource 24 | protected Mapper dozerMapper; 25 | 26 | @Resource 27 | private ArticleMapper articleMapper; 28 | 29 | 30 | @Override 31 | @Caching( 32 | evict = { 33 | @CacheEvict(value = "article",key = "#article.getId()"), 34 | @CacheEvict(value = "articleAll",allEntries = true) 35 | } 36 | ) 37 | public ArticleVO saveArticle(ArticleVO article) { 38 | Article articlePO = dozerMapper.map(article,Article.class); 39 | articleMapper.insert(articlePO); 40 | 41 | //TODO 把readers村到数据库里面 42 | article.setId(articlePO.getId()); 43 | return article; 44 | } 45 | 46 | @Override 47 | @Caching( 48 | evict = { 49 | @CacheEvict(value = "article",key = "#id"), 50 | @CacheEvict(value = "articleAll",allEntries = true) 51 | } 52 | ) 53 | public void deleteArticle(Long id) { 54 | articleMapper.deleteByPrimaryKey(id); 55 | } 56 | 57 | @Override 58 | @Caching( 59 | evict = { 60 | @CacheEvict(value = "article",key = "#article.getId()"), 61 | @CacheEvict(value = "articleAll",allEntries = true) 62 | } 63 | ) 64 | public ArticleVO updateArticle(ArticleVO article) { 65 | Article articlePO = dozerMapper.map(article,Article.class); 66 | articleMapper.updateByPrimaryKeySelective(articlePO); 67 | return article; 68 | } 69 | 70 | @Override 71 | @Cacheable(value="article",key = "#id",condition = "#id > 1") 72 | public ArticleVO getArticle(Long id) { 73 | //TODO 把读者信息查询出来赋值给ArticleVo 74 | return dozerMapper.map(articleMapper.selectByPrimaryKey(id),ArticleVO.class); 75 | } 76 | 77 | @Override 78 | @Cacheable(value="articleAll") 79 | public List getAll() { 80 | List
articles = articleMapper.selectByExample(null); 81 | return DozerUtils.mapList(articles,ArticleVO.class); 82 | 83 | } 84 | } 85 | -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/restful/ArticleRestControllerTest3.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.restful; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.zimug.bootlaunch.controller.ArticleRestController; 5 | import com.zimug.bootlaunch.model.ArticleVO; 6 | import com.zimug.bootlaunch.service.ArticleMybatisRestServiceImpl; 7 | import lombok.extern.slf4j.Slf4j; 8 | import org.junit.Test; 9 | import org.junit.runner.RunWith; 10 | import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc; 11 | import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest; 12 | import org.springframework.boot.test.mock.mockito.MockBean; 13 | import org.springframework.http.HttpMethod; 14 | import org.springframework.test.context.junit4.SpringRunner; 15 | import org.springframework.test.web.servlet.MockMvc; 16 | import org.springframework.test.web.servlet.MvcResult; 17 | import org.springframework.test.web.servlet.request.MockMvcRequestBuilders; 18 | import org.springframework.test.web.servlet.result.MockMvcResultMatchers; 19 | 20 | import javax.annotation.Resource; 21 | 22 | import static org.mockito.Mockito.when; 23 | import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print; 24 | 25 | //@Transactional 26 | @Slf4j 27 | @RunWith(SpringRunner.class) 28 | @AutoConfigureMockMvc 29 | @WebMvcTest(ArticleRestController.class) 30 | public class ArticleRestControllerTest3 { 31 | 32 | @Resource 33 | private MockMvc mockMvc; 34 | 35 | @MockBean 36 | ArticleMybatisRestServiceImpl articleRestService; 37 | 38 | /*@Before 39 | public void setUp() { 40 | mockMvc = MockMvcBuilders.standaloneSetup(new ArticleRestController()).build(); 41 | }*/ 42 | 43 | @Test 44 | public void saveArticle() throws Exception { 45 | String article = "{\n" + 46 | " \"id\": 1,\n" + 47 | " \"author\": \"zimug\",\n" + 48 | " \"title\": \"手摸手教你开发spring boot\",\n" + 49 | " \"content\": \"c\",\n" + 50 | " \"createTime\": \"2017-07-16 05:23:34\",\n" + 51 | " \"reader\":[{\"name\":\"zimug\",\"age\":18},{\"name\":\"kobe\",\"age\":37}]\n" + 52 | "}"; 53 | 54 | 55 | ObjectMapper objectMapper = new ObjectMapper(); 56 | ArticleVO articleObj = objectMapper.readValue(article,ArticleVO.class); 57 | 58 | //打桩 59 | when(articleRestService.saveArticle(articleObj)).thenReturn(articleObj); 60 | 61 | 62 | MvcResult result = mockMvc.perform(MockMvcRequestBuilders.request(HttpMethod.POST, "/rest/article") 63 | .contentType("application/json").content(article)) 64 | .andExpect(MockMvcResultMatchers.status().isOk()) 65 | .andExpect(MockMvcResultMatchers.jsonPath("$.data.author").value("zimug")) 66 | .andExpect(MockMvcResultMatchers.jsonPath("$.data.reader[0].age").value(18)) 67 | .andDo(print()) 68 | .andReturn(); 69 | 70 | log.info(result.getResponse().getContentAsString()); 71 | 72 | } 73 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/controller/ArticleRestController.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.controller; 2 | 3 | import com.zimug.bootlaunch.config.exception.AjaxResponse; 4 | import com.zimug.bootlaunch.model.ArticleVO; 5 | import com.zimug.bootlaunch.service.ArticleRestService; 6 | import io.swagger.annotations.ApiOperation; 7 | import io.swagger.annotations.ApiResponse; 8 | import io.swagger.annotations.ApiResponses; 9 | import lombok.extern.slf4j.Slf4j; 10 | import org.springframework.cache.annotation.Cacheable; 11 | import org.springframework.stereotype.Controller; 12 | import org.springframework.web.bind.annotation.*; 13 | 14 | import javax.annotation.Resource; 15 | import javax.validation.Valid; 16 | 17 | 18 | @Slf4j 19 | @Controller 20 | @RequestMapping("/rest") 21 | public class ArticleRestController { 22 | 23 | @Resource(name="articleMybatisRestServiceImpl") 24 | ArticleRestService articleRestService; 25 | 26 | 27 | @ApiOperation(value = "添加文章", notes = "添加新的文章", tags = "ArticleVO",httpMethod = "POST") 28 | @ApiResponses({ 29 | @ApiResponse(code=200,message="成功",response=AjaxResponse.class), 30 | @ApiResponse(code=400,message="用户输入错误",response=AjaxResponse.class), 31 | @ApiResponse(code=500,message="系统内部错误",response=AjaxResponse.class) 32 | }) 33 | //@RequestMapping(value = "/article", method = POST, produces = "application/json") 34 | @PostMapping("/article") 35 | public @ResponseBody AjaxResponse saveArticle(@RequestBody ArticleVO article) { 36 | /*public @ResponseBody AjaxResponse saveArticle(@RequestParam String id, 37 | @RequestParam String author) {*/ 38 | 39 | log.info("saveArticle:{}",article); 40 | 41 | log.info("articleRestService return :" + articleRestService.saveArticle(article)); 42 | 43 | return AjaxResponse.success(article); 44 | } 45 | 46 | //@RequestMapping(value = "/article/{id}", method = DELETE, produces = "application/json") 47 | @DeleteMapping("/article/{id}") 48 | public @ResponseBody AjaxResponse deleteArticle(@PathVariable Long id) { 49 | 50 | articleRestService.deleteArticle(id); 51 | 52 | return AjaxResponse.success(id); 53 | } 54 | 55 | //@RequestMapping(value = "/article/{id}", method = PUT, produces = "application/json") 56 | @PutMapping("/article/{id}") 57 | public @ResponseBody AjaxResponse updateArticle(@PathVariable Long id, @Valid @RequestBody ArticleVO article) { 58 | article.setId(id); 59 | 60 | articleRestService.updateArticle(article); 61 | 62 | return AjaxResponse.success(); 63 | } 64 | 65 | 66 | //@RequestMapping(value = "/article/{id}", method = GET, produces = "application/json") 67 | @GetMapping( "/article/{id}") 68 | public @ResponseBody AjaxResponse getArticle(@PathVariable Long id) { 69 | 70 | 71 | return AjaxResponse.success(articleRestService.getArticle(id)); 72 | } 73 | 74 | 75 | //@RequestMapping(value = "/article/{id}", method = GET, produces = "application/json") 76 | @GetMapping( "/article") 77 | public @ResponseBody AjaxResponse getAll() { 78 | 79 | return AjaxResponse.success(articleRestService.getAll()); 80 | } 81 | } -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/generator/testdb/Article.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.generator.testdb; 2 | 3 | import java.io.Serializable; 4 | import java.util.Date; 5 | 6 | /** 7 | * article 8 | * @author 9 | */ 10 | public class Article implements Serializable { 11 | private Long id; 12 | 13 | private String author; 14 | 15 | private String content; 16 | 17 | private Date createTime; 18 | 19 | private String title; 20 | 21 | private static final long serialVersionUID = 1L; 22 | 23 | public Long getId() { 24 | return id; 25 | } 26 | 27 | public void setId(Long id) { 28 | this.id = id; 29 | } 30 | 31 | public String getAuthor() { 32 | return author; 33 | } 34 | 35 | public void setAuthor(String author) { 36 | this.author = author; 37 | } 38 | 39 | public String getContent() { 40 | return content; 41 | } 42 | 43 | public void setContent(String content) { 44 | this.content = content; 45 | } 46 | 47 | public Date getCreateTime() { 48 | return createTime; 49 | } 50 | 51 | public void setCreateTime(Date createTime) { 52 | this.createTime = createTime; 53 | } 54 | 55 | public String getTitle() { 56 | return title; 57 | } 58 | 59 | public void setTitle(String title) { 60 | this.title = title; 61 | } 62 | 63 | @Override 64 | public boolean equals(Object that) { 65 | if (this == that) { 66 | return true; 67 | } 68 | if (that == null) { 69 | return false; 70 | } 71 | if (getClass() != that.getClass()) { 72 | return false; 73 | } 74 | Article other = (Article) that; 75 | return (this.getId() == null ? other.getId() == null : this.getId().equals(other.getId())) 76 | && (this.getAuthor() == null ? other.getAuthor() == null : this.getAuthor().equals(other.getAuthor())) 77 | && (this.getContent() == null ? other.getContent() == null : this.getContent().equals(other.getContent())) 78 | && (this.getCreateTime() == null ? other.getCreateTime() == null : this.getCreateTime().equals(other.getCreateTime())) 79 | && (this.getTitle() == null ? other.getTitle() == null : this.getTitle().equals(other.getTitle())); 80 | } 81 | 82 | @Override 83 | public int hashCode() { 84 | final int prime = 31; 85 | int result = 1; 86 | result = prime * result + ((getId() == null) ? 0 : getId().hashCode()); 87 | result = prime * result + ((getAuthor() == null) ? 0 : getAuthor().hashCode()); 88 | result = prime * result + ((getContent() == null) ? 0 : getContent().hashCode()); 89 | result = prime * result + ((getCreateTime() == null) ? 0 : getCreateTime().hashCode()); 90 | result = prime * result + ((getTitle() == null) ? 0 : getTitle().hashCode()); 91 | return result; 92 | } 93 | 94 | @Override 95 | public String toString() { 96 | StringBuilder sb = new StringBuilder(); 97 | sb.append(getClass().getSimpleName()); 98 | sb.append(" ["); 99 | sb.append("Hash = ").append(hashCode()); 100 | sb.append(", id=").append(id); 101 | sb.append(", author=").append(author); 102 | sb.append(", content=").append(content); 103 | sb.append(", createTime=").append(createTime); 104 | sb.append(", title=").append(title); 105 | sb.append(", serialVersionUID=").append(serialVersionUID); 106 | sb.append("]"); 107 | return sb.toString(); 108 | } 109 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## 一、代码配套书籍介绍 2 | * 本书发布于:[http://springboot.zimug.com](http://springboot.zimug.com),会持续创作更新。 3 | * 作者博客: [字母哥博客:www.zimug.com](http://www.zimug.com) 4 | 5 | ### **这本电子书的价值?** 6 | * 市面上售价70、80元一本的讲解spring boot的图书,因为出版章节及页数的限制,不可能讲解的全面细致,更多的是偏概念。而且技术是在不断发展的,很多内容都过时。 7 | * 本书会随着作者的知识更新,不断更新。**笔者自认为,这本电子书是目前市面上spring boot知识梳理最系统、全面、合理的一本电子书**。 8 | 9 | ## 二、内容概览 10 | * 第一章 spring boot 2.x基础及概念入门 11 | * 1.1.spring boot 产生的背景及其优势 12 | * 1.2.spring boot 2.x 新特性说明 13 | * 1.3.helloworld及项目结构介绍 14 | * 1.4.IDEA结合spring boot开发技巧 15 | * 第二章 RESTFul接口实现与测试 16 | * 2.1.RESTFul接口与http协议状态表述 17 | * 2.2.常用注解开发一个RESTFul接口 18 | * 2.3 JSON数据处理与PostMan测试 19 | * 2.4.使用Mockito编码完成接口测试 20 | * 2.5. 使用Swagger2构建API文档 21 | * 第三章 spring boot 配置原理实战 22 | * 3.1.结合配置加载讲解bean自动装配原理 23 | * 3.2.详解YAML语法及占位符语法 24 | * 3.3.获取自定义配置的两种实现方法 25 | * 3.4.配置文件注入值数据校验 26 | * 3.5.加载旧项目配置文件的两种方式 27 | * 3.6.profile不同环境使用不同配置 28 | * 3.7.配置及配置文件的加载优先级 29 | * 3.8.配置文件敏感字段加密 30 | * 第四章 常用web开发数据库框架 31 | * 4.1.整合Spring JDBC操作数据 32 | * 4.2 Spring JDBC多数据源的实现 33 | * 4.3.Spring JDBC JTA实现分布式事务 34 | * 4.4.ORM主流框架选型 35 | * 4.5.bean转换Dozer的快速上手 36 | * 4.6.整合Spring Data JPA操作数据 37 | * 4.7.Spring data JPA的多数据源实现 38 | * 4.8.JPA+atomikos实现分布式事务 39 | * 4.9.整合Mybatis操作数据 40 | * 4.10.Mybatis开发最佳实践总结 41 | * 4.11.Spring mybatis的多数据源实现 42 | * 4.12.mybatis+atomikos实现分布式事务 43 | * 4.13.Spring事务与分布式事务 44 | * 4.14.整合Spring data mongodb操作数据 45 | * 4.15.一行代码实现RESTFul接口 46 | * 第五章 静态资源与模板引擎的整合 47 | * 5.1.webjars与静态资源 48 | * 5.2.模板引擎选型与未来趋势 49 | * 5.3.web应用开发之整合jsp 50 | * 5.4.web应用开发之整合freemarker 51 | * 5.5.web应用开发之整合thymeleaf 52 | * 5.6.thymeleaf基础语法讲解 53 | * 5.7.thymeleaf内置对象与工具类 54 | * 5.8.公共片段(标签)与内联js 55 | * 第六章 生命周期内的拦截过滤与监听 56 | * 6.1.servlet与filter与listener的实现 57 | * 6.2.spring拦截器及请求链路说明 58 | * 6.3.自定义事件的发布与监听 59 | * 6.4.应用启动的监听 60 | * 第七章 嵌入式容器的配置与应用 61 | * 7.1.嵌入式的容器配置与调整 62 | * 7.2.切换到jetty&undertow容器 63 | * 7.3.打war包部署到外置tomcat容器 64 | * 第八章 统一全局异常处理 65 | * 8.1.设计一个优秀的异常处理机制 66 | * 8.2.自定义异常和相关数据结构 67 | * 8.3.全局异常处理ExceptionHandler 68 | * 8.4.服务端数据校验与全局异常处理 69 | * 8.5.AOP实现完美异常处理方案 70 | * 第九章 日志框架与全局日志管理 71 | * 9.1.日志框架的简介与选型 72 | * 9.2.logback日志框架整合使用 73 | * 9.3.log4j2日志框架整合与使用 74 | * 9.4.拦截器实现统一访问日志 75 | * 第十章 异步任务与定时任务 76 | * 10.1.实现Async异步任务 77 | * 10.2.为异步任务规划线程池 78 | * 10.3.通过@Scheduled实现定时任务 79 | * 10.4.quartz简单定时任务(内存持久化) 80 | * 10.5.quartz动态定时任务(数据库持久化) 81 | * 第十一章 redis缓存与session共享 82 | * 11.1.使用docker安装redis 83 | * 11.2.redis数据结构与应用场景 84 | * 11.3.使用redisTemplate操作数据 85 | * 11.4.使用Redis Repository操作数据 86 | * 11.5.spring cache基本用法 87 | * 11.6.详述缓存声明式注解的使用 88 | * 11.7.个性化自定义缓存到期时间 89 | * 11.8.集群多节点应用session共享 90 | * 第十二章 整合分布式文件系统fastdfs 91 | * 12.1.fastdfs简介及架构说明 92 | * 12.2.使用docker安装fastdfs 93 | * 12.3.开发一个自定义fastdfs-starter 94 | * 12.4.整合fastdfs操作文件数据 95 | * 第十三章 服务器推送技术 96 | * 13.1.主流服务器推送技术说明 97 | * 13.2.服务端推送事件SSE 98 | * 13.3.双向实时通信websocket 99 | * 第十四章 消息队列的整合与使用 100 | * 14.1.消息队列与JMS规范简介 101 | * 14.2.使用docker安装activeMQ 102 | * 14.3.activeMQ实现点对点队列 103 | * 14.4.activeMQ实现发布订阅队列 104 | * 14.5.docker安装RocketMQ 105 | * 14.6.RocketMQ实现2种消费模式 106 | * 14.7.RocketMQ实现分布式事务 107 | * 第十五章 邮件发送的整合与使用 108 | * 15.1.基础协议及邮件配置整合 109 | * 15.2.发送html和基于模板的邮件 110 | * 15.3.发送带附件和内联附件邮件 111 | * 第十六章 响应式框架webflux 112 | * 16.1.webflux快速入门 113 | * 16.2.注解方式实现restful接口 114 | * 16.3.webflux整合mongodb 115 | * 16.4.webclient单元测试的编写 116 | * 番外篇:周边技术生态 117 | * 如何使用git查看本教程代码 118 | * centos7安装docker图文详解 119 | * docker安装mongodb(单点)图文详解 120 | * 如何使用mybatis自动生成的代码 121 | 122 | 123 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/config/RedisConfig.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.config; 2 | 3 | import com.fasterxml.jackson.annotation.JsonAutoDetect; 4 | import com.fasterxml.jackson.annotation.PropertyAccessor; 5 | import com.fasterxml.jackson.databind.ObjectMapper; 6 | import lombok.Data; 7 | import org.springframework.boot.context.properties.ConfigurationProperties; 8 | import org.springframework.context.annotation.Bean; 9 | import org.springframework.context.annotation.Configuration; 10 | import org.springframework.data.redis.cache.RedisCacheConfiguration; 11 | import org.springframework.data.redis.cache.RedisCacheManager; 12 | import org.springframework.data.redis.cache.RedisCacheWriter; 13 | import org.springframework.data.redis.connection.RedisConnectionFactory; 14 | import org.springframework.data.redis.core.RedisTemplate; 15 | import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer; 16 | import org.springframework.data.redis.serializer.RedisSerializationContext; 17 | import org.springframework.data.redis.serializer.StringRedisSerializer; 18 | import org.springframework.stereotype.Component; 19 | 20 | import java.time.Duration; 21 | import java.util.HashMap; 22 | import java.util.Map; 23 | 24 | @Data 25 | @Configuration 26 | @Component 27 | @ConfigurationProperties(prefix = "caching") 28 | public class RedisConfig { 29 | 30 | @Bean 31 | public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory) { 32 | RedisTemplate redisTemplate = new RedisTemplate(); 33 | redisTemplate.setConnectionFactory(redisConnectionFactory); 34 | Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class); 35 | 36 | ObjectMapper objectMapper = new ObjectMapper(); 37 | objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY); 38 | objectMapper.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL); 39 | 40 | jackson2JsonRedisSerializer.setObjectMapper(objectMapper); 41 | 42 | //重点在这四行代码 43 | redisTemplate.setKeySerializer(new StringRedisSerializer()); 44 | redisTemplate.setValueSerializer(jackson2JsonRedisSerializer); 45 | redisTemplate.setHashKeySerializer(new StringRedisSerializer()); 46 | redisTemplate.setHashValueSerializer(jackson2JsonRedisSerializer); 47 | 48 | redisTemplate.afterPropertiesSet(); 49 | return redisTemplate; 50 | } 51 | 52 | 53 | //自定义redisCacheManager 54 | @Bean 55 | public RedisCacheManager redisCacheManager(RedisTemplate redisTemplate) { 56 | RedisCacheWriter redisCacheWriter = RedisCacheWriter.nonLockingRedisCacheWriter(redisTemplate.getConnectionFactory()); 57 | 58 | RedisCacheManager redisCacheManager = new RedisCacheManager(redisCacheWriter, 59 | this.buildRedisCacheConfigurationWithTTL(redisTemplate,RedisCacheConfiguration.defaultCacheConfig().getTtl().getSeconds()), //默认的redis缓存配置 60 | this.getRedisCacheConfigurationMap(redisTemplate)); //针对每一个cache做个性化缓存配置 61 | 62 | return redisCacheManager; 63 | } 64 | 65 | //配置注入,key是缓存名称,value是缓存有效期 66 | private Map ttlmap; 67 | 68 | //根据ttlmap的属性装配结果,个性化RedisCacheConfiguration 69 | private Map getRedisCacheConfigurationMap(RedisTemplate redisTemplate) { 70 | Map redisCacheConfigurationMap = new HashMap<>(); 71 | 72 | for(Map.Entry entry : ttlmap.entrySet()){ 73 | String cacheName = entry.getKey(); 74 | Long ttl = entry.getValue(); 75 | redisCacheConfigurationMap.put(cacheName,this.buildRedisCacheConfigurationWithTTL(redisTemplate,ttl)); 76 | } 77 | 78 | return redisCacheConfigurationMap; 79 | } 80 | 81 | 82 | //让缓存的序列化方式使用redisTemplate.getValueSerializer(),并未每一个缓存分别设置ttl 83 | private RedisCacheConfiguration buildRedisCacheConfigurationWithTTL(RedisTemplate redisTemplate,Long ttl){ 84 | return RedisCacheConfiguration.defaultCacheConfig() 85 | .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(redisTemplate.getValueSerializer())) 86 | .entryTtl(Duration.ofSeconds(ttl)); 87 | } 88 | } -------------------------------------------------------------------------------- /src/test/java/com/zimug/bootlaunch/redis/RedisConfigTest.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.redis; 2 | 3 | import com.fasterxml.jackson.databind.ObjectMapper; 4 | import com.zimug.bootlaunch.model.Address; 5 | import com.zimug.bootlaunch.model.Person; 6 | import org.junit.Assert; 7 | import org.junit.Test; 8 | import org.junit.runner.RunWith; 9 | import org.springframework.beans.factory.annotation.Autowired; 10 | import org.springframework.boot.test.context.SpringBootTest; 11 | import org.springframework.data.redis.core.*; 12 | import org.springframework.data.redis.hash.HashMapper; 13 | import org.springframework.data.redis.hash.Jackson2HashMapper; 14 | import org.springframework.test.context.junit4.SpringRunner; 15 | 16 | import javax.annotation.Resource; 17 | import java.util.Map; 18 | import java.util.Set; 19 | import java.util.concurrent.TimeUnit; 20 | 21 | @RunWith(SpringRunner.class) 22 | @SpringBootTest 23 | public class RedisConfigTest { 24 | 25 | @Autowired 26 | private StringRedisTemplate stringRedisTemplate; 27 | 28 | /*@Autowired 29 | private RedisTemplate redisTemplate;*/ 30 | 31 | @Resource(name = "redisTemplate") 32 | private ValueOperations valueOperations; 33 | 34 | @Resource(name = "redisTemplate") 35 | private HashOperations hashOperations; 36 | 37 | @Resource(name = "redisTemplate") 38 | private ListOperations listOperations; 39 | 40 | @Resource(name = "redisTemplate") 41 | private SetOperations setOperations; 42 | 43 | @Resource(name = "redisTemplate") 44 | private ZSetOperations zSetOperations; 45 | 46 | @Test 47 | public void testValueObj() throws Exception{ 48 | Person person = new Person("kobe","byrant"); 49 | person.setAddress(new Address("南京","中国")); 50 | //ValueOperations operations = redisTemplate.opsForValue(); 51 | valueOperations.set("player:2",person,20,TimeUnit.SECONDS); //20秒之后数据消失 52 | 53 | Person getBack = (Person)valueOperations.get("player:1"); 54 | System.out.println(getBack); 55 | } 56 | 57 | @Test 58 | public void testSetOperation() throws Exception{ 59 | Person person = new Person("boke","byrant"); 60 | Person person2 = new Person("curry","stephen"); 61 | setOperations.add("playerset",person,person2); 62 | Set result = setOperations.members("playerset"); 63 | System.out.println(result); 64 | } 65 | 66 | @Test 67 | public void HashOperations() throws Exception{ 68 | Person person = new Person("boke","byrant"); 69 | //hset "hash:player" "firstname" kobe 70 | hashOperations.put("hash:player","firstname",person.getFirstname()); 71 | hashOperations.put("hash:player","lastname",person.getLastname()); 72 | hashOperations.put("hash:player","address",person.getAddress()); 73 | System.out.println(hashOperations.get("hash:player","firstname")); 74 | } 75 | 76 | @Test 77 | public void ListOperations() throws Exception{ 78 | 79 | listOperations.leftPush("list:player",new Person("boke","byrant")); 80 | listOperations.leftPush("list:player",new Person("Jordan","Mikel")); 81 | listOperations.leftPush("list:player",new Person("curry","stephen")); 82 | 83 | System.out.println(listOperations.leftPop("list:player")); 84 | } 85 | 86 | 87 | @Resource(name="redisTemplate") 88 | private HashOperations jacksonHashOperations; 89 | private HashMapper jackson2HashMapper = new Jackson2HashMapper(false); 90 | @Test 91 | public void testHashPutAll(){ 92 | 93 | Person person = new Person("boke","byrant"); 94 | person.setId("1"); 95 | person.setAddress(new Address("南京","中国")); 96 | //将对象以hash的形式放入数据库 97 | Map mappedHash = jackson2HashMapper.toHash(person); 98 | jacksonHashOperations.putAll("player" + person.getId(), mappedHash); 99 | 100 | //将对象从数据库取出来 101 | Map loadedHash = jacksonHashOperations.entries("player" + person.getId()); 102 | Object map = jackson2HashMapper.fromHash(loadedHash); 103 | Person getback = new ObjectMapper().convertValue(map,Person.class); 104 | Assert.assertEquals(person.getFirstname(),getback.getFirstname()); 105 | } 106 | } -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 4.0.0 5 | 6 | org.springframework.boot 7 | spring-boot-starter-parent 8 | 2.0.4.RELEASE 9 | 10 | 11 | com.zimug 12 | boot-launch 13 | 0.0.1-SNAPSHOT 14 | boot-launch 15 | Spring Boot 2 learing 16 | 17 | 18 | 1.8 19 | 20 | 21 | 22 | 23 | org.springframework.boot 24 | spring-boot-starter-web 25 | 26 | 27 | org.springframework.boot 28 | spring-boot-starter-logging 29 | 30 | 31 | 32 | 33 | org.springframework.boot 34 | spring-boot-starter-log4j2 35 | 36 | 37 | 38 | org.springframework.boot 39 | spring-boot-starter-test 40 | test 41 | 42 | 43 | org.springframework.boot 44 | spring-boot-devtools 45 | 46 | true 47 | 48 | 49 | 50 | io.springfox 51 | springfox-swagger2 52 | 2.6.1 53 | 54 | 55 | 56 | io.springfox 57 | springfox-swagger-ui 58 | 2.6.1 59 | 60 | 61 | 62 | org.mybatis.spring.boot 63 | mybatis-spring-boot-starter 64 | 1.3.2 65 | 66 | 67 | 68 | com.github.pagehelper 69 | pagehelper-spring-boot-starter 70 | 1.2.10 71 | 72 | 73 | mysql 74 | mysql-connector-java 75 | 76 | 77 | 78 | net.sf.dozer 79 | dozer 80 | 5.4.0 81 | 82 | 83 | org.slf4j 84 | slf4j-log4j12 85 | 86 | 87 | 88 | 89 | 90 | 91 | org.projectlombok 92 | lombok 93 | true 94 | 95 | 96 | 97 | org.springframework.boot 98 | spring-boot-starter-aop 99 | 100 | 101 | 102 | 103 | org.springframework.boot 104 | spring-boot-starter-data-redis 105 | 106 | 107 | org.apache.commons 108 | commons-pool2 109 | 110 | 111 | org.springframework.session 112 | spring-session-data-redis 113 | 114 | 115 | 116 | org.springframework.boot 117 | spring-boot-starter-cache 118 | 119 | 120 | 121 | com.zimug.spring 122 | zimug-fastdfs-spring-boot-starter 123 | 1.0.0 124 | 125 | 126 | 127 | 128 | org.webjars 129 | jquery 130 | 1.12.4 131 | 132 | 133 | 134 | org.webjars 135 | webjars-locator 136 | 0.30 137 | 138 | 139 | 140 | 141 | org.springframework.boot 142 | spring-boot-starter-freemarker 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | src/main/java 153 | false 154 | 155 | **/*.xml 156 | 157 | 158 | 159 | src/main/resources 160 | false 161 | 162 | 163 | 164 | 165 | org.springframework.boot 166 | spring-boot-maven-plugin 167 | 168 | true 169 | 170 | 171 | 172 | 173 | 174 | 175 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/generator/testdb/ArticleMapper.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | and ${criterion.condition} 20 | 21 | 22 | and ${criterion.condition} #{criterion.value} 23 | 24 | 25 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 26 | 27 | 28 | and ${criterion.condition} 29 | 30 | #{listItem} 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | and ${criterion.condition} 49 | 50 | 51 | and ${criterion.condition} #{criterion.value} 52 | 53 | 54 | and ${criterion.condition} #{criterion.value} and #{criterion.secondValue} 55 | 56 | 57 | and ${criterion.condition} 58 | 59 | #{listItem} 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | id, author, content, create_time, title 71 | 72 | 94 | 100 | 101 | delete from article 102 | where id = #{id,jdbcType=BIGINT} 103 | 104 | 105 | delete from article 106 | 107 | 108 | 109 | 110 | 111 | insert into article (author, content, create_time, 112 | title) 113 | values (#{author,jdbcType=VARCHAR}, #{content,jdbcType=VARCHAR}, #{createTime,jdbcType=TIMESTAMP}, 114 | #{title,jdbcType=VARCHAR}) 115 | 116 | 117 | insert into article 118 | 119 | 120 | author, 121 | 122 | 123 | content, 124 | 125 | 126 | create_time, 127 | 128 | 129 | title, 130 | 131 | 132 | 133 | 134 | #{author,jdbcType=VARCHAR}, 135 | 136 | 137 | #{content,jdbcType=VARCHAR}, 138 | 139 | 140 | #{createTime,jdbcType=TIMESTAMP}, 141 | 142 | 143 | #{title,jdbcType=VARCHAR}, 144 | 145 | 146 | 147 | 153 | 154 | update article 155 | 156 | 157 | id = #{record.id,jdbcType=BIGINT}, 158 | 159 | 160 | author = #{record.author,jdbcType=VARCHAR}, 161 | 162 | 163 | content = #{record.content,jdbcType=VARCHAR}, 164 | 165 | 166 | create_time = #{record.createTime,jdbcType=TIMESTAMP}, 167 | 168 | 169 | title = #{record.title,jdbcType=VARCHAR}, 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | update article 178 | set id = #{record.id,jdbcType=BIGINT}, 179 | author = #{record.author,jdbcType=VARCHAR}, 180 | content = #{record.content,jdbcType=VARCHAR}, 181 | create_time = #{record.createTime,jdbcType=TIMESTAMP}, 182 | title = #{record.title,jdbcType=VARCHAR} 183 | 184 | 185 | 186 | 187 | 188 | update article 189 | 190 | 191 | author = #{author,jdbcType=VARCHAR}, 192 | 193 | 194 | content = #{content,jdbcType=VARCHAR}, 195 | 196 | 197 | create_time = #{createTime,jdbcType=TIMESTAMP}, 198 | 199 | 200 | title = #{title,jdbcType=VARCHAR}, 201 | 202 | 203 | where id = #{id,jdbcType=BIGINT} 204 | 205 | 206 | update article 207 | set author = #{author,jdbcType=VARCHAR}, 208 | content = #{content,jdbcType=VARCHAR}, 209 | create_time = #{createTime,jdbcType=TIMESTAMP}, 210 | title = #{title,jdbcType=VARCHAR} 211 | where id = #{id,jdbcType=BIGINT} 212 | 213 | -------------------------------------------------------------------------------- /src/main/java/com/zimug/bootlaunch/generator/testdb/ArticleExample.java: -------------------------------------------------------------------------------- 1 | package com.zimug.bootlaunch.generator.testdb; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Date; 5 | import java.util.List; 6 | 7 | public class ArticleExample { 8 | protected String orderByClause; 9 | 10 | protected boolean distinct; 11 | 12 | protected List oredCriteria; 13 | 14 | private Integer limit; 15 | 16 | private Long offset; 17 | 18 | public ArticleExample() { 19 | oredCriteria = new ArrayList(); 20 | } 21 | 22 | public void setOrderByClause(String orderByClause) { 23 | this.orderByClause = orderByClause; 24 | } 25 | 26 | public String getOrderByClause() { 27 | return orderByClause; 28 | } 29 | 30 | public void setDistinct(boolean distinct) { 31 | this.distinct = distinct; 32 | } 33 | 34 | public boolean isDistinct() { 35 | return distinct; 36 | } 37 | 38 | public List getOredCriteria() { 39 | return oredCriteria; 40 | } 41 | 42 | public void or(Criteria criteria) { 43 | oredCriteria.add(criteria); 44 | } 45 | 46 | public Criteria or() { 47 | Criteria criteria = createCriteriaInternal(); 48 | oredCriteria.add(criteria); 49 | return criteria; 50 | } 51 | 52 | public Criteria createCriteria() { 53 | Criteria criteria = createCriteriaInternal(); 54 | if (oredCriteria.size() == 0) { 55 | oredCriteria.add(criteria); 56 | } 57 | return criteria; 58 | } 59 | 60 | protected Criteria createCriteriaInternal() { 61 | Criteria criteria = new Criteria(); 62 | return criteria; 63 | } 64 | 65 | public void clear() { 66 | oredCriteria.clear(); 67 | orderByClause = null; 68 | distinct = false; 69 | } 70 | 71 | public void setLimit(Integer limit) { 72 | this.limit = limit; 73 | } 74 | 75 | public Integer getLimit() { 76 | return limit; 77 | } 78 | 79 | public void setOffset(Long offset) { 80 | this.offset = offset; 81 | } 82 | 83 | public Long getOffset() { 84 | return offset; 85 | } 86 | 87 | protected abstract static class GeneratedCriteria { 88 | protected List criteria; 89 | 90 | protected GeneratedCriteria() { 91 | super(); 92 | criteria = new ArrayList(); 93 | } 94 | 95 | public boolean isValid() { 96 | return criteria.size() > 0; 97 | } 98 | 99 | public List getAllCriteria() { 100 | return criteria; 101 | } 102 | 103 | public List getCriteria() { 104 | return criteria; 105 | } 106 | 107 | protected void addCriterion(String condition) { 108 | if (condition == null) { 109 | throw new RuntimeException("Value for condition cannot be null"); 110 | } 111 | criteria.add(new Criterion(condition)); 112 | } 113 | 114 | protected void addCriterion(String condition, Object value, String property) { 115 | if (value == null) { 116 | throw new RuntimeException("Value for " + property + " cannot be null"); 117 | } 118 | criteria.add(new Criterion(condition, value)); 119 | } 120 | 121 | protected void addCriterion(String condition, Object value1, Object value2, String property) { 122 | if (value1 == null || value2 == null) { 123 | throw new RuntimeException("Between values for " + property + " cannot be null"); 124 | } 125 | criteria.add(new Criterion(condition, value1, value2)); 126 | } 127 | 128 | public Criteria andIdIsNull() { 129 | addCriterion("id is null"); 130 | return (Criteria) this; 131 | } 132 | 133 | public Criteria andIdIsNotNull() { 134 | addCriterion("id is not null"); 135 | return (Criteria) this; 136 | } 137 | 138 | public Criteria andIdEqualTo(Long value) { 139 | addCriterion("id =", value, "id"); 140 | return (Criteria) this; 141 | } 142 | 143 | public Criteria andIdNotEqualTo(Long value) { 144 | addCriterion("id <>", value, "id"); 145 | return (Criteria) this; 146 | } 147 | 148 | public Criteria andIdGreaterThan(Long value) { 149 | addCriterion("id >", value, "id"); 150 | return (Criteria) this; 151 | } 152 | 153 | public Criteria andIdGreaterThanOrEqualTo(Long value) { 154 | addCriterion("id >=", value, "id"); 155 | return (Criteria) this; 156 | } 157 | 158 | public Criteria andIdLessThan(Long value) { 159 | addCriterion("id <", value, "id"); 160 | return (Criteria) this; 161 | } 162 | 163 | public Criteria andIdLessThanOrEqualTo(Long value) { 164 | addCriterion("id <=", value, "id"); 165 | return (Criteria) this; 166 | } 167 | 168 | public Criteria andIdIn(List values) { 169 | addCriterion("id in", values, "id"); 170 | return (Criteria) this; 171 | } 172 | 173 | public Criteria andIdNotIn(List values) { 174 | addCriterion("id not in", values, "id"); 175 | return (Criteria) this; 176 | } 177 | 178 | public Criteria andIdBetween(Long value1, Long value2) { 179 | addCriterion("id between", value1, value2, "id"); 180 | return (Criteria) this; 181 | } 182 | 183 | public Criteria andIdNotBetween(Long value1, Long value2) { 184 | addCriterion("id not between", value1, value2, "id"); 185 | return (Criteria) this; 186 | } 187 | 188 | public Criteria andAuthorIsNull() { 189 | addCriterion("author is null"); 190 | return (Criteria) this; 191 | } 192 | 193 | public Criteria andAuthorIsNotNull() { 194 | addCriterion("author is not null"); 195 | return (Criteria) this; 196 | } 197 | 198 | public Criteria andAuthorEqualTo(String value) { 199 | addCriterion("author =", value, "author"); 200 | return (Criteria) this; 201 | } 202 | 203 | public Criteria andAuthorNotEqualTo(String value) { 204 | addCriterion("author <>", value, "author"); 205 | return (Criteria) this; 206 | } 207 | 208 | public Criteria andAuthorGreaterThan(String value) { 209 | addCriterion("author >", value, "author"); 210 | return (Criteria) this; 211 | } 212 | 213 | public Criteria andAuthorGreaterThanOrEqualTo(String value) { 214 | addCriterion("author >=", value, "author"); 215 | return (Criteria) this; 216 | } 217 | 218 | public Criteria andAuthorLessThan(String value) { 219 | addCriterion("author <", value, "author"); 220 | return (Criteria) this; 221 | } 222 | 223 | public Criteria andAuthorLessThanOrEqualTo(String value) { 224 | addCriterion("author <=", value, "author"); 225 | return (Criteria) this; 226 | } 227 | 228 | public Criteria andAuthorLike(String value) { 229 | addCriterion("author like", value, "author"); 230 | return (Criteria) this; 231 | } 232 | 233 | public Criteria andAuthorNotLike(String value) { 234 | addCriterion("author not like", value, "author"); 235 | return (Criteria) this; 236 | } 237 | 238 | public Criteria andAuthorIn(List values) { 239 | addCriterion("author in", values, "author"); 240 | return (Criteria) this; 241 | } 242 | 243 | public Criteria andAuthorNotIn(List values) { 244 | addCriterion("author not in", values, "author"); 245 | return (Criteria) this; 246 | } 247 | 248 | public Criteria andAuthorBetween(String value1, String value2) { 249 | addCriterion("author between", value1, value2, "author"); 250 | return (Criteria) this; 251 | } 252 | 253 | public Criteria andAuthorNotBetween(String value1, String value2) { 254 | addCriterion("author not between", value1, value2, "author"); 255 | return (Criteria) this; 256 | } 257 | 258 | public Criteria andContentIsNull() { 259 | addCriterion("content is null"); 260 | return (Criteria) this; 261 | } 262 | 263 | public Criteria andContentIsNotNull() { 264 | addCriterion("content is not null"); 265 | return (Criteria) this; 266 | } 267 | 268 | public Criteria andContentEqualTo(String value) { 269 | addCriterion("content =", value, "content"); 270 | return (Criteria) this; 271 | } 272 | 273 | public Criteria andContentNotEqualTo(String value) { 274 | addCriterion("content <>", value, "content"); 275 | return (Criteria) this; 276 | } 277 | 278 | public Criteria andContentGreaterThan(String value) { 279 | addCriterion("content >", value, "content"); 280 | return (Criteria) this; 281 | } 282 | 283 | public Criteria andContentGreaterThanOrEqualTo(String value) { 284 | addCriterion("content >=", value, "content"); 285 | return (Criteria) this; 286 | } 287 | 288 | public Criteria andContentLessThan(String value) { 289 | addCriterion("content <", value, "content"); 290 | return (Criteria) this; 291 | } 292 | 293 | public Criteria andContentLessThanOrEqualTo(String value) { 294 | addCriterion("content <=", value, "content"); 295 | return (Criteria) this; 296 | } 297 | 298 | public Criteria andContentLike(String value) { 299 | addCriterion("content like", value, "content"); 300 | return (Criteria) this; 301 | } 302 | 303 | public Criteria andContentNotLike(String value) { 304 | addCriterion("content not like", value, "content"); 305 | return (Criteria) this; 306 | } 307 | 308 | public Criteria andContentIn(List values) { 309 | addCriterion("content in", values, "content"); 310 | return (Criteria) this; 311 | } 312 | 313 | public Criteria andContentNotIn(List values) { 314 | addCriterion("content not in", values, "content"); 315 | return (Criteria) this; 316 | } 317 | 318 | public Criteria andContentBetween(String value1, String value2) { 319 | addCriterion("content between", value1, value2, "content"); 320 | return (Criteria) this; 321 | } 322 | 323 | public Criteria andContentNotBetween(String value1, String value2) { 324 | addCriterion("content not between", value1, value2, "content"); 325 | return (Criteria) this; 326 | } 327 | 328 | public Criteria andCreateTimeIsNull() { 329 | addCriterion("create_time is null"); 330 | return (Criteria) this; 331 | } 332 | 333 | public Criteria andCreateTimeIsNotNull() { 334 | addCriterion("create_time is not null"); 335 | return (Criteria) this; 336 | } 337 | 338 | public Criteria andCreateTimeEqualTo(Date value) { 339 | addCriterion("create_time =", value, "createTime"); 340 | return (Criteria) this; 341 | } 342 | 343 | public Criteria andCreateTimeNotEqualTo(Date value) { 344 | addCriterion("create_time <>", value, "createTime"); 345 | return (Criteria) this; 346 | } 347 | 348 | public Criteria andCreateTimeGreaterThan(Date value) { 349 | addCriterion("create_time >", value, "createTime"); 350 | return (Criteria) this; 351 | } 352 | 353 | public Criteria andCreateTimeGreaterThanOrEqualTo(Date value) { 354 | addCriterion("create_time >=", value, "createTime"); 355 | return (Criteria) this; 356 | } 357 | 358 | public Criteria andCreateTimeLessThan(Date value) { 359 | addCriterion("create_time <", value, "createTime"); 360 | return (Criteria) this; 361 | } 362 | 363 | public Criteria andCreateTimeLessThanOrEqualTo(Date value) { 364 | addCriterion("create_time <=", value, "createTime"); 365 | return (Criteria) this; 366 | } 367 | 368 | public Criteria andCreateTimeIn(List values) { 369 | addCriterion("create_time in", values, "createTime"); 370 | return (Criteria) this; 371 | } 372 | 373 | public Criteria andCreateTimeNotIn(List values) { 374 | addCriterion("create_time not in", values, "createTime"); 375 | return (Criteria) this; 376 | } 377 | 378 | public Criteria andCreateTimeBetween(Date value1, Date value2) { 379 | addCriterion("create_time between", value1, value2, "createTime"); 380 | return (Criteria) this; 381 | } 382 | 383 | public Criteria andCreateTimeNotBetween(Date value1, Date value2) { 384 | addCriterion("create_time not between", value1, value2, "createTime"); 385 | return (Criteria) this; 386 | } 387 | 388 | public Criteria andTitleIsNull() { 389 | addCriterion("title is null"); 390 | return (Criteria) this; 391 | } 392 | 393 | public Criteria andTitleIsNotNull() { 394 | addCriterion("title is not null"); 395 | return (Criteria) this; 396 | } 397 | 398 | public Criteria andTitleEqualTo(String value) { 399 | addCriterion("title =", value, "title"); 400 | return (Criteria) this; 401 | } 402 | 403 | public Criteria andTitleNotEqualTo(String value) { 404 | addCriterion("title <>", value, "title"); 405 | return (Criteria) this; 406 | } 407 | 408 | public Criteria andTitleGreaterThan(String value) { 409 | addCriterion("title >", value, "title"); 410 | return (Criteria) this; 411 | } 412 | 413 | public Criteria andTitleGreaterThanOrEqualTo(String value) { 414 | addCriterion("title >=", value, "title"); 415 | return (Criteria) this; 416 | } 417 | 418 | public Criteria andTitleLessThan(String value) { 419 | addCriterion("title <", value, "title"); 420 | return (Criteria) this; 421 | } 422 | 423 | public Criteria andTitleLessThanOrEqualTo(String value) { 424 | addCriterion("title <=", value, "title"); 425 | return (Criteria) this; 426 | } 427 | 428 | public Criteria andTitleLike(String value) { 429 | addCriterion("title like", value, "title"); 430 | return (Criteria) this; 431 | } 432 | 433 | public Criteria andTitleNotLike(String value) { 434 | addCriterion("title not like", value, "title"); 435 | return (Criteria) this; 436 | } 437 | 438 | public Criteria andTitleIn(List values) { 439 | addCriterion("title in", values, "title"); 440 | return (Criteria) this; 441 | } 442 | 443 | public Criteria andTitleNotIn(List values) { 444 | addCriterion("title not in", values, "title"); 445 | return (Criteria) this; 446 | } 447 | 448 | public Criteria andTitleBetween(String value1, String value2) { 449 | addCriterion("title between", value1, value2, "title"); 450 | return (Criteria) this; 451 | } 452 | 453 | public Criteria andTitleNotBetween(String value1, String value2) { 454 | addCriterion("title not between", value1, value2, "title"); 455 | return (Criteria) this; 456 | } 457 | } 458 | 459 | /** 460 | */ 461 | public static class Criteria extends GeneratedCriteria { 462 | 463 | protected Criteria() { 464 | super(); 465 | } 466 | } 467 | 468 | public static class Criterion { 469 | private String condition; 470 | 471 | private Object value; 472 | 473 | private Object secondValue; 474 | 475 | private boolean noValue; 476 | 477 | private boolean singleValue; 478 | 479 | private boolean betweenValue; 480 | 481 | private boolean listValue; 482 | 483 | private String typeHandler; 484 | 485 | public String getCondition() { 486 | return condition; 487 | } 488 | 489 | public Object getValue() { 490 | return value; 491 | } 492 | 493 | public Object getSecondValue() { 494 | return secondValue; 495 | } 496 | 497 | public boolean isNoValue() { 498 | return noValue; 499 | } 500 | 501 | public boolean isSingleValue() { 502 | return singleValue; 503 | } 504 | 505 | public boolean isBetweenValue() { 506 | return betweenValue; 507 | } 508 | 509 | public boolean isListValue() { 510 | return listValue; 511 | } 512 | 513 | public String getTypeHandler() { 514 | return typeHandler; 515 | } 516 | 517 | protected Criterion(String condition) { 518 | super(); 519 | this.condition = condition; 520 | this.typeHandler = null; 521 | this.noValue = true; 522 | } 523 | 524 | protected Criterion(String condition, Object value, String typeHandler) { 525 | super(); 526 | this.condition = condition; 527 | this.value = value; 528 | this.typeHandler = typeHandler; 529 | if (value instanceof List) { 530 | this.listValue = true; 531 | } else { 532 | this.singleValue = true; 533 | } 534 | } 535 | 536 | protected Criterion(String condition, Object value) { 537 | this(condition, value, null); 538 | } 539 | 540 | protected Criterion(String condition, Object value, Object secondValue, String typeHandler) { 541 | super(); 542 | this.condition = condition; 543 | this.value = value; 544 | this.secondValue = secondValue; 545 | this.typeHandler = typeHandler; 546 | this.betweenValue = true; 547 | } 548 | 549 | protected Criterion(String condition, Object value, Object secondValue) { 550 | this(condition, value, secondValue, null); 551 | } 552 | } 553 | } --------------------------------------------------------------------------------