• Spring boot 入门(二):Spring boot集成MySql,Mybatis和PageHelper插件


      上一篇文章,写了如何搭建一个简单的Spring boot项目,本篇是接着上一篇文章写得:Spring boot入门:快速搭建Spring boot项目(一),主要是spring boot集成mybatis和pagehelper

    关于mybatis和pagehelper的介绍,可以自行博客,网上很多类似的博客,这里,我直接上代码和项目搭建教程。

    1.配置文件:在配置文件application.yml中配置MySql数据库连接池和Mybatis扫描包以及PageHelper分页插件

     1 mybatis:
     2   mapper-locations: classpath:mapper/*.xml
     3   type-aliases-package: com.tswc.edu.entity
     4 
     5 mapper:
     6   mappers:
     7   - com.tswc.edu.util.MyMapper
     8   not-empty: false
     9   identity: MYSQL
    10   #identity: SQLSERVER
    11 
    12 pagehelper:
    13   helperDialect: MYSQL
    14   reasonable: true
    15   supportMethodsArguments: true
    16   params: count=countSql
    17 
    18 spring:
    19   datasource:
    20     type: com.alibaba.druid.pool.DruidDataSource
    21     driverClassName: com.mysql.jdbc.Driver
    22     url: jdbc:mysql://127.0.0.1:3306/edu?useUnicode=true&characterEncoding=utf8
    23     username: root
    24     password: 123456
    25     initialSize: 1
    26     minIdle: 3
    27     maxActive: 20
    28     # 配置获取连接等待超时的时间
    29     maxWait: 60000
    30     # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
    31     timeBetweenEvictionRunsMillis: 60000
    32     # 配置一个连接在池中最小生存的时间,单位是毫秒
    33     minEvictableIdleTimeMillis: 30000
    34     validationQuery: select 'x'
    35     testWhileIdle: true
    36     testOnBorrow: false
    37     testOnReturn: false
    38     # 打开PSCache,并且指定每个连接上PSCache的大小
    39     poolPreparedStatements: true
    40     maxPoolPreparedStatementPerConnectionSize: 20
    41     # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
    42     filters: stat,wall,slf4j
    43     # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
    44     connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000
    45     # 合并多个DruidDataSource的监控数据
    46     #useGlobalDataSourceStat: true

    同时,需要在pom.xml中添加相应的jar包依赖,如果存在jar包无法下载,可以手动下载,然后放到相应的jar包文件夹中

    ***********************************这里面需要注意Spring boot和mybatis的jar包之间的版本,sping boot2+要求高版本,eg:spring boot2+不能识别pagehelper1.2以下的版本

     1  <!--mybatis -->
     2         <dependency>
     3             <groupId>mysql</groupId>
     4             <artifactId>mysql-connector-java</artifactId>
     5             <version>5.1.6</version>
     6         </dependency>
     7         <dependency>
     8             <groupId>org.mybatis</groupId>
     9             <artifactId>mybatis</artifactId>
    10             <version>3.4.4</version>
    11         </dependency>
    12 
    13         <dependency>
    14             <groupId>org.mybatis.spring.boot</groupId>
    15             <artifactId>mybatis-spring-boot-starter</artifactId>
    16             <version>1.1.1</version>
    17         </dependency>
    18         <!--druid -->
    19         <dependency>
    20             <groupId>com.alibaba</groupId>
    21             <artifactId>druid</artifactId>
    22             <version>1.0.28</version>
    23         </dependency>
    24 
    25         <!--mapper-->
    26         <dependency>
    27             <groupId>tk.mybatis</groupId>
    28             <artifactId>mapper-spring-boot-starter</artifactId>
    29             <version>2.1.0</version>
    30         </dependency>
    31         <!--pagehelper,Spring boot2.0+只能设备pagehelper1.2+-->
    32         <dependency>
    33             <groupId>com.github.pagehelper</groupId>
    34             <artifactId>pagehelper-spring-boot-starter</artifactId>
    35             <version>1.2.5</version>
    36         </dependency>

    2:代码部分

    (1).更新入口主文件,主要增加了一些注解,

      此处需要注意@MapperSca的引用,这里有2个可引用的包,分别是tk.mybatis.spring.annotation.MapperScan和org.mybatis.spring.annotation.MapperScan;

      tk.mybatis.spring.annotation.MapperScan:为mubatis带的mapper扫描文件,org.mybatis.spring.annotation.MapperScan为spring自带的扫描文件,在低版本的mybatis上,2个包可以随意使用,但是Spring boot2+后,增加了一些特性(建议阅读spring boot2+的底层代码,加深理解),导致只能使用高版本的mtbatis,同时spring自带的MapperScan也无法使用,所以使用sping boot2+后,需要引用高版本的mybatis,同时这里只能使用mybatis的MapperScan的扫描包;spring在后期更新中,应该也会使其能够用于boot中

     1 @ServletComponentScan
     2 @MapperScan(basePackages = "com.tswc.edu.mapper")
     3 @SpringBootApplication
     4 public class EduApplication {
     5 
     6     public static void main(String[] args) {
     7         SpringApplication.run(EduApplication.class, args);
     8     }
     9 
    10 }

      如果在项目正常,启动,但是在使用mybatis时,报此类错误:

      后台错误:无法获取实体类对应的表名!

     1 2018-12-14 20:09:25.967 ERROR 29024 --- [nio-8085-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is tk.mybatis.mapper.MapperException: 无法获取实体类com.tswc.edu.entity.Index对应的表名!] with root caus 2 
     3 tk.mybatis.mapper.MapperException: 无法获取实体类com.tswc.edu.entity.Index对应的表名!
     4     at tk.mybatis.mapper.mapperhelper.EntityHelper.getEntityTable(EntityHelper.java:69) ~[mapper-core-1.1.0.jar:na]
     5     at tk.mybatis.mapper.entity.Example.<init>(Example.java:103) ~[mapper-core-1.1.0.jar:na]
     6     at tk.mybatis.mapper.entity.Example.<init>(Example.java:88) ~[mapper-core-1.1.0.jar:na]
     7     at tk.mybatis.mapper.entity.Example.<init>(Example.java:78) ~[mapper-core-1.1.0.jar:na]
     8     at com.tswc.edu.service.IndexService.getList(IndexService.java:33) ~[classes/:na]
     9     at com.tswc.edu.controller.IndexController.list(IndexController.java:35) ~[classes/:na]
    10     at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_151]
    11     at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_151]
    12     at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_151]
    13     at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_151]
    14     at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    15     at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    16     at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    17     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    18     at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    19     at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    20     at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    21     at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    22     at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    23     at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    24     at javax.servlet.http.HttpServlet.service(HttpServlet.java:634) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    25     at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882) ~[spring-webmvc-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    26     at javax.servlet.http.HttpServlet.service(HttpServlet.java:741) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    27     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    28     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    29     at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53) ~[tomcat-embed-websocket-9.0.13.jar:9.0.13]
    30     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    31     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    32     at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    33     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    34     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    35     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    36     at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    37     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    38     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    39     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    40     at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    41     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    42     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    43     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    44     at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    45     at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) ~[spring-web-5.1.3.RELEASE.jar:5.1.3.RELEASE]
    46     at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    47     at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    48     at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199) ~[tomcat-embed-core-9.0.13.jar:9.0.13]
    49     at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96) [tomcat-embed-core-9.0.13.jar:9.0.13]
    50     at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490) [tomcat-embed-core-9.0.13.jar:9.0.13]
    51     at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139) [tomcat-embed-core-9.0.13.jar:9.0.13]
    52     at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92) [tomcat-embed-core-9.0.13.jar:9.0.13]
    53     at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74) [tomcat-embed-core-9.0.13.jar:9.0.13]
    54     at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343) [tomcat-embed-core-9.0.13.jar:9.0.13]
    55     at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408) [tomcat-embed-core-9.0.13.jar:9.0.13]
    56     at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-9.0.13.jar:9.0.13]
    57     at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:791) [tomcat-embed-core-9.0.13.jar:9.0.13]
    58     at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1417) [tomcat-embed-core-9.0.13.jar:9.0.13]
    59     at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-9.0.13.jar:9.0.13]
    60     at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) [na:1.8.0_151]
    61     at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) [na:1.8.0_151]
    62     at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-9.0.13.jar:9.0.13]
    63     at java.lang.Thread.run(Thread.java:748) [na:1.8.0_151]

      前端错误是500

    1 Whitelabel Error Page
    2 This application has no explicit mapping for /error, so you are seeing this as a fallback.
    3 
    4 Fri Dec 14 20:09:25 CST 2018
    5 There was an unexpected error (type=Internal Server Error, status=500).
    6 ???????com.tswc.edu.entity.Index?????!

    那么,就是Mapper扫描包使用有误

     (2).通用接口mapper:此接口不能被扫描到,否则会报错,可以在application.yml中,排除此包的扫描

    1 public interface MyMapper<T> extends Mapper<T> {
    2     //TODO
    3     //FIXME 特别注意,该接口不能被扫描到,否则会出错
    4 }

    (3)后台代码,控制村层>服务层>接口

     1 @Controller
     2 public class IndexController {
     3     @Autowired
     4     private IndexService indexService;
     5 
     6     @RequestMapping(value = "/index")
     7     public void list(ModelMap modelMap) {
     8         List<Index> list = indexService.getList();
     9         modelMap.put("list", list);
    10     }
    11 }
     1 @Service
     2 public class IndexService {
     3     @Autowired
     4     private IndexMapper indexMapper;
     5 
     6     public List<Index> getList() {
     7         Example example = new Example(Index.class);
     8         example.setTableName("index_test");
     9         Criteria criteria = example.createCriteria();
    10         criteria.andEqualTo("age", 20);
    11         return indexMapper.selectByExample(example);
    12     }
    13 }
    1 public interface IndexMapper extends MyMapper<Index> {
    2 }
     1 @Table(name = "index_test")
     2 public class Index implements Serializable, IDynamicTableName {
     3     private static final long serialVersionUID = -8709793124943394842L;
     4 
     5     @Transient
     6     private String dynamicTableName;
     7     private String name;
     8     private Integer age;
     9 
    10     public String getName() {
    11         return name;
    12     }
    13 
    14     public void setName(String name) {
    15         this.name = name;
    16     }
    17 
    18     public Integer getAge() {
    19         return age;
    20     }
    21 
    22     public void setAge(Integer age) {
    23         this.age = age;
    24     }
    25 
    26     @Override
    27     public String getDynamicTableName() {
    28         return null;
    29     }
    30 }

      最后一个类为实体类,建议在建立实体类的时候,统一加上@Table的注解,方便后期Mybatis的使用,同时也提高了代码的规范性。当然,如果我们使用Mybatis的代码生成器,那么均会自动加上注解(代码生成器在后期的博客中会讲到)

    (4).前端ftl代码

     1 <!DOCTYPE html>
     2 <html>
     3 <head lang="en">
     4     <title>Spring Boot Demo - FreeMarker</title>
     5     <link href="/css/index.css" rel="stylesheet" />
     6 </head>
     7 <body>
     8     <table>
     9         <#list list as user>
    10         <tr>
    11             <td>第${user_index+1}个用户</td>
    12             <td>用户名:${user.name}</td>
    13             <td>年  龄: ${user.age}</td>
    14         </tr>
    15         </#list>
    16     </table>
    17 </body>
    18 </html>

    (5)添加mybatis的空配置文件,由于spring boot中,数据库是通过配置文件的形式,所以此文件是空的,但是没有此文件,mybatis就无法通过;当然,也可以通过在此文件作用配置数据库连接池的方式连接数据(已过时)

    1 <?xml version="1.0" encoding="UTF-8"?>
    2 <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD SQL MAP Config 3.1//EN"
    3     "http://mybatis.org/dtd/mybatis-3-config.dtd">
    4 <configuration>
    5   <settings>
    6     <setting name="callSettersOnNulls" value="true"/>
    7   </settings>
    8 </configuration>

    (6)数据库如下:添加了几条测试数据:

    (7).启动项目,并访问http://localhost:8085/index,结果如下:

     最终,项目代码的机构,如下:

  • 相关阅读:
    Postfix邮件服务
    Python
    LVS
    MFS
    Apache
    Zookeeper集群 + Kafka集群 + KafkaOffsetMonitor 监控
    shell 检测安装包
    shell ssh 批量执行
    shell 判断脚本参数
    bzoj 1500 修改区间 splay
  • 原文地址:https://www.cnblogs.com/dz-boss/p/10119193.html
Copyright © 2020-2023  润新知