Spring Boot学习笔记

Maven创建Spring Boot的方法

在某些情况下,start.spring.io无法访问时,可以直接使用Maven创建Spring Boot项目

  1. 新建Maven项目

  2. 在pom.xml文件中添加parent节点

    1
    2
    3
    4
    5
    <parent>    
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.3.0.RELEASE</version>
    </parent>
  3. 添加spring-boot-starter-webspring-boot-starter-test依赖

  4. 添加spring-boot-maven-plugin插件

  5. 创建启动类

    1
    2
    3
    4
    5
    6
    @SpringBootApplication
    public class Application {
    public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
    }
    }

HttpMessageConverter

在Spring MVC中自动配置了JacksonGsonHttpMessageConverter

  1. 将服务端返回的对象序列化成JSON字符串
  2. 将前端传递的JSON字符串反序列化成Java对象

自定义HttpMessageConverter的方式

  • Jackson
  1. 提供MappingJackson2HttpMessageConverterbean

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Bean
    MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter() {
    MappingJackson2HttpMessageConverter converter = new
    MappingJackson2HttpMessageConverter();
    ObjectMapper om = new ObjectMapper();
    om.setDateFormat(new SimpleDateFormat("yyyy/MM/dd hh:mm:SSS"));
    converter.setObjectMapper(om);
    return converter;
    }
    //起主要作用的是ObjectMapper
  2. 提供ObjectMapper

    1
    2
    3
    4
    5
    6
    @Bean
    ObjectMapper objectMapper() {
    ObjectMapper om = new ObjectMapper();
    om.setDateFormat(new SimpleDateFormat("yyyy/MM/dd hh/mm/SSS"));
    return om;
    }
  • Gson
  1. 修改spring-boot-starter-web中默认的Jackson依赖,添加Gson依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
    <exclusion>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
    </exclusion>
    </exclusions>
    </dependency>
    <dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    </dependency>
  2. 提供GsonHttpMessageConverterbean

    1
    2
    3
    4
    5
    6
    7
    8
    @Bean
    GsonHttpMessageConverter gsonHttpMessageConverter(){
    GsonHttpMessageConverter converter = new GsonHttpMessageConverter();
    converter.setGson(new
    GsonBuilder().setDateFormat("yyyy/MM/dd").create());
    return converter;
    }
    //起主要作用的是Gson
  3. 提供Gson

    1
    2
    3
    4
    @Bean
    Gson gson(){
    return new GsonBuilder().setDateFormat("yyyy/MM/dd").create();
    }
  • FastJson
  1. 修改spring-boot-starter-web中默认的Jackson依赖,添加Fastjson依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    <exclusions>
    <exclusion>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-json</artifactId>
    </exclusion>
    </exclusions>
    </dependency>

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>fastjson</artifactId>
    <version>1.2.68</version>
    </dependency>
  2. 提供FastJsonHttpMessageConverter

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Bean
    FastJsonHttpMessageConverter fastJsonHttpMessageConverter(){
    FastJsonHttpMessageConverter converter = new
    FastJsonHttpMessageConverter();
    FastJsonConfig fastJsonConfig = new FastJsonConfig();
    fastJsonConfig.setDateFormat("yyyy/MM/dd");
    converter.setFastJsonConfig(fastJsonConfig);
    return converter;
    }

静态资源的访问

在Spring Boot的WebMvcAutoConfiguration中已经默认设置了五个静态资源的访问路径,按优先级顺序依次为META-INF/resourcesresourcesstaticpublic/

自定义静态资源的位置

  1. application.properties中添加

    1
    2
    3
    spring.resources.static-locations=classpath:/xxx/
    # 也可以添加规则
    spring.mvc.static-path-pattern=/**
  2. Java类中配置

    1
    2
    3
    4
    5
    6
    7
    @Configuration
    public class WebMVCConfig implements WebMvcConfigurer {
    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
    registry.addResourceHandler("/**").addResourceLocations("classpath:/xxx/");
    }
    }

文件上传

主要使用MultipartFile

  1. 创建Controller

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    @RestController
    public class FileUploadController {
    SimpleDateFormat sdf = new SimpleDateFormat("/yyyy/MM/dd/");

    @PostMapping("/upload")
    public String upload(MultipartFile file, HttpServletRequest req) {
    String format = sdf.format(new Date());
    String realPath = req.getServletContext().getRealPath("/img") + format;
    File folder = new File(realPath);
    if (!folder.exists()) {
    folder.mkdirs();
    }
    String oldName = file.getOriginalFilename();
    String newName = UUID.randomUUID().toString() + oldName.substring(oldName.lastIndexOf("."));
    try {
    file.transferTo(new File(realPath, newName));
    String url = req.getScheme() + "://" + req.getServerName() + ":" + req.getServerPort() + "/img" + format + newName;
    return url;
    } catch (IOException e) {
    e.printStackTrace();
    }
    return "error";
    }
    }
  2. 创建index.html

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    <!DOCTYPE html>
    <html lang="en">
    <head>
    <meta charset="UTF-8">
    <title>Title</title>
    </head>
    <body>
    <form action="/upload" method="post" enctype="multipart/form-data">
    <input type="file" name="file">
    <input type="submit" value="submit">
    </form>
    </body>
    </html>
  3. 关于上传文件大小的限制需要在application.properties中进行修改

    1
    spring.servlet.multipart.max-file-size=1MB

@ControllerAdvice

  • 全局异常处理

    1. 创建MyCustomException

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      @ControllerAdvice
      public class MyCustomException {
      //以response的方式返回
      @ExceptionHandler(MaxUploadSizeExceededException.class)
      public void myException(MaxUploadSizeExceededException e, HttpServletResponse res) throws IOException {
      res.setContentType("text/html;charset=utf-8");
      PrintWriter out = res.getWriter();
      out.write("上传文件大小超出限制!");
      out.flush();
      out.close();
      }

      //以视图的方式返回
      @ExceptionHandler(MaxUploadSizeExceededException.class)
      public ModelAndView myException(MaxUploadSizeExceededException e) throws IOException {
      ModelAndView modelAndView = new ModelAndView("myerror");
      modelAndView.addObject("error", "文件大小超过限制!");
      return modelAndView;
      }
      }
    2. ModelAndView的方式返回需要创建错误页面myerror.html以及thymeleaf的依赖

      1
      2
      3
      4
      5
      6
      7
      8
      9
      <!DOCTYPE html>
      <head xmlns:th="http://www.thymeleaf.org">
      <meta charset="UTF-8">
      <title>Title</title>
      </head>
      <body>
      <h1 th:text="${error}"></h1>
      </body>
      </html>
  • 预设全局数据

    1. 创建全局数据类,使用Map保存数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      @ControllerAdvice
      public class GlobalData {
      @ModelAttribute(value = "person")
      public Map<String,Object> mydata(){
      Map<String,Object> map = new HashMap<>();
      map.put("name","wan");
      map.put("gender","male");
      return map;
      }
      }
    2. Controller中使用Model调用数据

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      @RestController
      public class HelloController {
      @GetMapping("/hello")
      public String hello(Model model){
      Map<String, Object> map = model.asMap();
      Set<String> keySet = map.keySet();
      for (String s : keySet) {
      System.out.println(s+":"+map.get(s));
      }
      return "hello";
      }
      }
  • 请求参数预处理

现在出现如下需求,前端向后端发送请求参数时出现命名冲突:

key value
name 三国演义
price 99
name 吴冠中
age 100

此时在服务器端接受的数据会有问题,解决方法如下:

  1. 给接收参数重命名

    1
    2
    3
    4
    5
    6
    7
    8
    @RestController
    public class BookController {
    @PostMapping("/book")
    public void addBook(@ModelAttribute("b") Book book, @ModelAttribute("a") Author author){
    System.out.println(book);
    System.out.println(author);
    }
    }
  2. 创建@ControllerAdvice类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @InitBinder(value = "a")
    public void initA(WebDataBinder binder){
    binder.setFieldDefaultPrefix("a.");
    }

    @InitBinder(value = "b")
    public void initB(WebDataBinder binder){
    binder.setFieldDefaultPrefix("b.");
    }

@ModelAttribute

WebDataBinder

@InitBinder

ControllerAdvice

Model

ModelAndView

@ExceptionHandler

自定义异常

  1. classpath下的statictemplate目录中创建error目录并创建静态错误页面和动态错误页面,按优先级依次访问:精确大于模糊,动态大于静态

  2. 自定义错误数据

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @Component
    public class MyErrorConfig extends DefaultErrorAttributes {
    @Override
    public Map<String, Object> getErrorAttributes(WebRequest webRequest, ErrorAttributeOptions options) {
    Map<String, Object> errorAttributes = super.getErrorAttributes(webRequest, options);
    errorAttributes.put("myerror","自定义异常信息!");
    return errorAttributes;
    }
    }
  3. 自定义错误视图

    1. 自定义ErrorViewResolver继承自DefaultErrorViewResolver
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    @Component
    public class MyErrorViewResolver extends DefaultErrorViewResolver {
    /**
    * Create a new {@link DefaultErrorViewResolver} instance.
    *
    * @param applicationContext the source application context
    * @param resourceProperties resource properties
    */
    public MyErrorViewResolver(ApplicationContext applicationContext, ResourceProperties resourceProperties) {
    super(applicationContext, resourceProperties);
    }

    @Override
    public ModelAndView resolveErrorView(HttpServletRequest request, HttpStatus status, Map<String, Object> model) {
    ModelAndView modelAndView = super.resolveErrorView(request, status, model);
    modelAndView.setViewName("myerror");
    modelAndView.addObject(model);
    return modelAndView;
    }
    }
    1. 自定义视图myerror.html

ErrorMvcAutoConfiguration

DefaultErrorAttributes

getErrorAttributes()

DefaultErrorViewResolver

resolveErrorView()

CORS解决跨域问题

  1. 在请求中添加注解@CrosOrigin(origins = "http://xxxx:xxxx")即可

  2. 创建配置类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    @Configuration
    public class MyMVCConfig implements WebMvcConfigurer {
    @Override
    public void addCorsMappings(CorsRegistry registry) {
    registry.addMapping("/**")
    .allowedOrigins("http://xxxx:xxxx")
    .allowedHeaders("*")
    .allowedMethods("*");
    }
    }

WebMvcConfigurer

addCorsMappings(CorsRegistry registry)

XML

  1. 创建beans.xml

    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean class="org.wan.xml.Hello" id="hello"/>
    </beans>
  2. 创建MyWebNvcConfig

    1
    2
    3
    4
    @Configuration
    @ImportResource(locations = "classpath:beans.xml")
    public class WebMvcConfig {
    }

注册拦截器

  1. 自定义Interceptor

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class MyInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
    System.out.println("preHandle");
    return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
    System.out.println("postHandle");
    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    System.out.println("afterCompletion");
    }
    }

  2. 创建WebMvcConfig

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    @Configuration
    public class WebMvcConfig implements WebMvcConfigurer {
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
    registry.addInterceptor(myInterceptor()).addPathPatterns("/**");
    }

    @Bean
    MyInterceptor myInterceptor(){
    return new MyInterceptor();
    }
    }

定义系统启动任务

  1. CommandLineRunner

    • 创建MyCommanderLineRunner

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      @Component
      @Order(1)
      public class MyCommandLineRunner1 implements CommandLineRunner {
      @Override
      public void run(String... args) throws Exception {

      }
      }

      @Component
      @Order(2)
      public class MyCommandLineRunner2 implements CommandLineRunner {
      @Override
      public void run(String... args) throws Exception {

      }
      }
      //order表示优先级,值越小优先级越高
  2. ApplicationRunner(获取参数的类型更丰富)

    • 创建MyApplicationRunner

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      @Component
      @Order(2)
      public class MyApplicationRunner1 implements ApplicationRunner {
      @Override
      public void run(ApplicationArguments args) throws Exception {

      }
      }

      @Component
      @Order(1)
      public class MyApplicationRunner2 implements ApplicationRunner {
      @Override
      public void run(ApplicationArguments args) throws Exception {

      }
      }

CommandLineRunner

ApplicationRunner

类型转换器

需求:前端向后端传递日期的字符串,后端使用Date对象无法接收,此时需要自定义转换器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Component
public class MyConverter implements Converter<String, Date> {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");

@Override
public Date convert(String s) {
if (s != null) {
try {
return sdf.parse(s);
} catch (ParseException e) {
e.printStackTrace();
}
}
return null;
}
}

AOP

1
2
3
4
5
6
7
8
9
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
@Component
@Aspect
public class MyLogger {
@Pointcut("execution(* org.wan.aop.service.*.*(..))")
public void pc1() {
}

@Before(value = "pc1()")
public void before(JoinPoint jp) {
String name = jp.getSignature().getName();
System.out.println("before:" + name);
}

@After(value = "pc1()")
public void after(JoinPoint jp) {
String name = jp.getSignature().getName();
System.out.println("after:" + name);
}

@AfterReturning(value = "pc1()",returning = "result")
public void afterReturning(JoinPoint jp, Object result) {
String name = jp.getSignature().getName();
System.out.println("afterReturning:" + name+"----"+result);
}

@Around("pc1()")
public Object around(ProceedingJoinPoint pjp) throws Throwable {
return pjp.proceed();
}

@AfterThrowing(value = "pc1()",throwing = "e")
public void afterThrowing(JoinPoint jp,Exception e) {
String name = jp.getSignature().getName();
System.out.println("afterThrowing:" + name+"----"+e.getMessage());
}
}

@Aspect

@Pointcut(“execution( org.wan.aop.service..*(..))”)

@Before(value = “pc1()”)

@After(value = “pc1()”)

@AfterReturning(value = “pc1()”,returning = “result”)

@Around(“pc1()”)

@AfterThrowing(value = “pc1()”,throwing = “e”)

JdbcTemplate

  1. 依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
    </dependency>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>8.0.16</version>
    </dependency>
  1. MySQL配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    spring.datasource.one.url=jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=true&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL
    spring.datasource.one.username=root
    spring.datasource.one.password=123456
    spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource


    spring.datasource.two.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf8&useSSL=true&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL
    spring.datasource.two.username=root
    spring.datasource.two.password=123456
    spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
  2. 自定义DataSource

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    @Configuration
    public class DataSourceConfig {
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.one")
    DruidDataSource dsOne(){
    return DruidDataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.two")
    DruidDataSource dsTwo(){
    return DruidDataSourceBuilder.create().build();
    }
    }
  3. 自定义JdbcTemplate

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    @Configuration
    public class JdbcTemplateConfig {

    @Bean
    JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne") DataSource ds){
    return new JdbcTemplate(ds);
    }

    @Bean
    JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo") DataSource ds){
    return new JdbcTemplate(ds);
    }
    }

@ConfigurationProperties(prefix = “spring.datasource.one”)

DruidDataSource

DruidDataSourceBuilder.create().build()

JdbcTemplate

@Qualifier(“dsOne”) DataSource ds

MyBatis

  1. 添加依赖以及配置resource

    1
    2
    3
    4
    5
    6
    7
    8
    9
    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
    <dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>2.1.2</version>
    </dependency>

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
    </dependency>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>8.0.16</version>
    </dependency>

    <!--添加resource的目的在于,将mapper.xml和对应的Mapper.java文件放在同一个package下-->
    <!--也可以在resource目录下创建和对应Mapper.java相同路径的mapper.xml-->
    <!--也可以将mapper.xml放于resource中的文件夹中,然后在application.properties中设置mybatis.mapper-locations=classpath:/mapper/*.xml-->
    <build>
    <resources>
    <resource>
    <directory>src/main/java</directory>
    <includes>
    <include>**/*.xml</include>
    </includes>
    </resource>
    <resource>
    <directory>src/main/resources</directory>
    </resource>
    </resources>
    </build>
  1. MySQL配置

    1
    2
    3
    4
    5
    6
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
    spring.datasource.url=jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=true&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL

  2. 配置mapper.xmlmapper.java

    1
    2
    3
    4
    5
    6
    7
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.example.mybatis.mapper.UserMapper">
    <select id="getAllUser" resultType="com.example.mybatis.bean.User">
    select * from user;
    </select>
    </mapper>
    1
    2
    3
    public interface UserMapper {
    List<User> getAllUser();
    }
  3. 配置多数据源

    • 配置数据源

      1
      2
      3
      4
      5
      6
      7
      8
      9
      spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
      spring.datasource.one.username=root
      spring.datasource.one.password=123456
      spring.datasource.one.url=jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=true&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL

      spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
      spring.datasource.two.username=root
      spring.datasource.two.password=123456
      spring.datasource.two.url=jdbc:mysql://localhost:3306/test2?characterEncoding=utf8&useSSL=true&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL
    • 创建mapper1mapper2两个package,在各自包下创建mapper.xmlmapper.java

    • 创建自定义DataSource

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      @Configuration
      public class DataSourceConfig {

      @Bean
      @ConfigurationProperties(prefix = "spring.datasource.one")
      DataSource dataSourceOne(){
      return DruidDataSourceBuilder.create().build();
      }

      @Bean
      @ConfigurationProperties(prefix = "spring.datasource.two")
      DataSource dataSourceTwo(){
      return DruidDataSourceBuilder.create().build();
      }
      }
    • 创建配置类MyBatisConfigOneMyBatisConfigTwo

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      @Configuration
      @MapperScan(basePackages = "com.example.mybatis.mapper1",sqlSessionFactoryRef = "sqlSessionFactory1",
      sqlSessionTemplateRef = "sqlSessionTemplate1")
      public class MyBatisConfigOne {
      @Resource(name = "dataSourceOne")
      DataSource dsOne;

      @Bean
      SqlSessionFactory sqlSessionFactory1(){
      SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
      ssfb.setDataSource(dsOne);
      try {
      return ssfb.getObject();
      } catch (Exception e) {
      e.printStackTrace();
      }
      return null;
      }

      @Bean
      SqlSessionTemplate sqlSessionTemplate1(){
      return new SqlSessionTemplate(sqlSessionFactory1());
      }
      }
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      @Configuration
      @MapperScan(basePackages = "com.example.mybatis.mapper2",sqlSessionFactoryRef = "sqlSessionFactory2",
      sqlSessionTemplateRef = "sqlSessionTemplate2")
      public class MyBatisConfigTwo {
      @Resource(name = "dataSourceTwo")
      DataSource dsTwo;

      @Bean
      SqlSessionFactory sqlSessionFactory2(){
      SqlSessionFactoryBean ssfb = new SqlSessionFactoryBean();
      ssfb.setDataSource(dsTwo);
      try {
      return ssfb.getObject();
      } catch (Exception e) {
      e.printStackTrace();
      }
      return null;
      }

      @Bean
      SqlSessionTemplate sqlSessionTemplate2(){
      return new SqlSessionTemplate(sqlSessionFactory2());
      }
      }
src/main/java **/*.xml src/main/resources

@MapperScan(basePackages = “com.example.mybatis.mapper1”,sqlSessionFactoryRef = “sqlSessionFactory1”,
sqlSessionTemplateRef = “sqlSessionTemplate1”)

SqlSessionFactory

SqlSessionTemplate

JPA

  1. 依赖

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
    </dependency>

    <dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.10</version>
    </dependency>

    <dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <scope>runtime</scope>
    <version>8.0.16</version>
    </dependency>
  2. MySQL配置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
    spring.datasource.url=jdbc:mysql://localhost:3306/test1?characterEncoding=utf8&useSSL=true&serverTimezone=UTC&zeroDateTimeBehavior=CONVERT_TO_NULL
    spring.datasource.username=root
    spring.datasource.password=123456
    spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver


    spring.jpa.show-sql=true
    spring.jpa.database=mysql
    spring.jpa.database-platform=mysql
    spring.jpa.hibernate.ddl-auto=update
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
  3. 创建bean

    1
    2
    3
    4
    5
    6
    7
    8
    @Entity(name = "t_book")
    public class Book {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private String author;
    }
  4. 创建dao

    1
    2
    public interface BookDao extends JpaRepository<Book,Integer> {
    }

spring.jpa.show-sql=true
spring.jpa.database=mysql
spring.jpa.database-platform=mysql
spring.jpa.hibernate.ddl-auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect

@Entity(name = “t_book”)

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)

JpaRepository

Redis

Session

Nginx

MongoDB

Docker

RESTful