当前位置:   article > 正文

springboot2.0 Mybatis 整合 (springboot2.0版本)

parent的版本是2那么org.mybatis.spring的版本该是多少

springboot终于迎来了2.0版本,很多新的特性让springboot更加强大,之前使用1.5.6版本整合了Mybatis,现在2.0版本就已经不适用了,所以,在摸索中搭建了2.0版本整合Mybatis

<!-- more -->

写在前面

本来这篇博文老在就写好了,但是后来发现很多功能其实根本就没有检验通过就发出来了,导致遗留了很多坑,比如最难搞的就是SqlSessionFactory和PageHelper,之前写过关于springboot1.5.6版本的整合,这段时间刚好springboot发布了2.0的正式版本,很多同学可能没有注意版本,导致了整合的时候出现了很多很多的问题,这几天刚好有空就试着整合一下springboot2.0 mybatis,发现了很多很多的坑,而且网上的资源也不多,终于在两天的踩坑中成功整合了,并且将翻页功能修复好了,废话不多说了,看代码:

环境/版本一览:

  • 开发工具:Intellij IDEA 2017.1.3
  • springboot: 2.0.1.RELEASE
  • jdk:1.8.0_40
  • maven:3.3.9
  • alibaba Druid 数据库连接池:1.1.0

额外功能:

开始搭建:

创建项目:

添加基础的依赖:

依赖文件:

按照pom文件补齐需要的依赖:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  4. <modelVersion>4.0.0</modelVersion>
  5. <groupId>com.winterchen</groupId>
  6. <artifactId>springboot2-mybatis-demo</artifactId>
  7. <version>0.0.1-SNAPSHOT</version>
  8. <packaging>jar</packaging>
  9. <name>springboot2-mybatis-demo</name>
  10. <description>Demo project for Spring Boot</description>
  11. <parent>
  12. <groupId>org.springframework.boot</groupId>
  13. <artifactId>spring-boot-starter-parent</artifactId>
  14. <version>2.0.1.RELEASE</version>
  15. <relativePath/> <!-- lookup parent from repository -->
  16. </parent>
  17. <properties>
  18. <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  19. <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
  20. <java.version>1.8</java.version>
  21. </properties>
  22. <dependencies>
  23. <dependency>
  24. <groupId>org.springframework.boot</groupId>
  25. <artifactId>spring-boot-starter-web</artifactId>
  26. </dependency>
  27. <dependency>
  28. <groupId>org.mybatis.spring.boot</groupId>
  29. <artifactId>mybatis-spring-boot-starter</artifactId>
  30. <version>1.3.2</version>
  31. </dependency>
  32. <dependency>
  33. <groupId>mysql</groupId>
  34. <artifactId>mysql-connector-java</artifactId>
  35. <scope>runtime</scope>
  36. </dependency>
  37. <dependency>
  38. <groupId>org.springframework.boot</groupId>
  39. <artifactId>spring-boot-starter-test</artifactId>
  40. <scope>test</scope>
  41. </dependency>
  42. <dependency>
  43. <groupId>org.apache.commons</groupId>
  44. <artifactId>commons-lang3</artifactId>
  45. <version>3.4</version>
  46. </dependency>
  47. <dependency>
  48. <groupId>com.fasterxml.jackson.core</groupId>
  49. <artifactId>jackson-core</artifactId>
  50. </dependency>
  51. <dependency>
  52. <groupId>com.fasterxml.jackson.core</groupId>
  53. <artifactId>jackson-databind</artifactId>
  54. </dependency>
  55. <dependency>
  56. <groupId>com.fasterxml.jackson.datatype</groupId>
  57. <artifactId>jackson-datatype-joda</artifactId>
  58. </dependency>
  59. <dependency>
  60. <groupId>com.fasterxml.jackson.module</groupId>
  61. <artifactId>jackson-module-parameter-names</artifactId>
  62. </dependency>
  63. <!-- 分页插件 -->
  64. <dependency>
  65. <groupId>com.github.pagehelper</groupId>
  66. <artifactId>pagehelper</artifactId>
  67. <version>5.1.3</version>
  68. </dependency>
  69. <!-- alibaba的druid数据库连接池 -->
  70. <dependency>
  71. <groupId>com.alibaba</groupId>
  72. <artifactId>druid-spring-boot-starter</artifactId>
  73. <version>1.1.0</version>
  74. </dependency>
  75. </dependencies>
  76. <build>
  77. <plugins>
  78. <plugin>
  79. <groupId>org.springframework.boot</groupId>
  80. <artifactId>spring-boot-maven-plugin</artifactId>
  81. </plugin>
  82. </plugins>
  83. </build>
  84. </project>

项目结构:

项目结构

项目启动类:
  1. package com.winterchen;
  2. import org.springframework.boot.SpringApplication;
  3. import org.springframework.boot.autoconfigure.SpringBootApplication;
  4. @SpringBootApplication
  5. public class Springboot2MybatisDemoApplication {
  6. public static void main(String[] args) {
  7. SpringApplication.run(Springboot2MybatisDemoApplication.class, args);
  8. }
  9. }

配置:

可以根据个人使用习惯选择使用properties或者yml文件,本项目使用的是yml配置文件,所以把原本application.properties删除,创建一个application.yml文件

在resource文件夹下创建application.yml

  1. server:
  2. port: 8080
  3. spring:
  4. datasource:
  5. name: test
  6. url: jdbc:mysql://127.0.0.1:3306/mytest?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true
  7. username: root
  8. password: root
  9. # 使用druid数据源
  10. type: com.alibaba.druid.pool.DruidDataSource
  11. driver-class-name: com.mysql.jdbc.Driver
  12. filters: stat
  13. maxActive: 20
  14. initialSize: 1
  15. maxWait: 60000
  16. minIdle: 1
  17. timeBetweenEvictionRunsMillis: 60000
  18. minEvictableIdleTimeMillis: 300000
  19. validationQuery: select 'x'
  20. testWhileIdle: true
  21. testOnBorrow: false
  22. testOnReturn: false
  23. poolPreparedStatements: true
  24. maxPoolPreparedStatementPerConnectionSize: 20
  25. maxOpenPreparedStatements: 20
  26. mybatis:
  27. mapper-locations: classpath:mapper/*.xml
  28. type-aliases-package: com.winterchen.model
  29. mapper:
  30. mappers: com.winterchen.dao
  31. not-empty: false
  32. identity: MYSQL
  33. #pagehelper
  34. pagehelper:
  35. helperDialect: mysql
  36. reasonable: true
  37. supportMethodsArguments: true
  38. params: count=countSql
  39. returnPageInfo: check

创建包:

modeldaomapper,config

新建配置类:

PageHelperConfig.java

以下配置非常的重要,PageHelper的Page拦截器PageInterceptor ,如果不进行配置,那么分页功能将没有效果

  1. package com.winterchen.config;
  2. import com.github.pagehelper.PageInterceptor;
  3. import org.springframework.beans.factory.annotation.Value;
  4. import org.springframework.context.annotation.Bean;
  5. import org.springframework.context.annotation.Configuration;
  6. import java.util.Properties;
  7. /**
  8. * 分页插件的配置
  9. * Created by Donghua.Chen on 2018/4/20.
  10. */
  11. @Configuration
  12. public class PageHelperConfig {
  13. @Value("${pagehelper.helperDialect}")
  14. private String helperDialect;
  15. @Bean
  16. public PageInterceptor pageInterceptor(){
  17. PageInterceptor pageInterceptor = new PageInterceptor();
  18. Properties properties = new Properties();
  19. properties.setProperty("helperDialect", helperDialect);
  20. pageInterceptor.setProperties(properties);
  21. return pageInterceptor;
  22. }
  23. }

DataSourceConfig.java

在springboot2.0版本,如果不定义SqlSessionFactory,那么将会导致错误,因为无法注入SqlSessionFactory并且下面注释部分的内容非常的重要,这也是整合当中遇到的很大的坑,如果不将PageInterceptor作为插件设置到SqlSessionFactoryBean中,导致分页失效

  1. package com.winterchen.config;
  2. import com.github.pagehelper.PageHelper;
  3. import com.github.pagehelper.PageInterceptor;
  4. import org.apache.ibatis.plugin.Interceptor;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.mybatis.spring.SqlSessionFactoryBean;
  7. import org.mybatis.spring.annotation.MapperScan;
  8. import org.slf4j.Logger;
  9. import org.slf4j.LoggerFactory;
  10. import org.springframework.beans.factory.annotation.Autowired;
  11. import org.springframework.beans.factory.annotation.Qualifier;
  12. import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
  13. import org.springframework.boot.context.properties.ConfigurationProperties;
  14. import org.springframework.boot.jdbc.DataSourceBuilder;
  15. import org.springframework.context.annotation.Bean;
  16. import org.springframework.context.annotation.Configuration;
  17. import org.springframework.core.env.Environment;
  18. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  19. import org.springframework.transaction.annotation.EnableTransactionManagement;
  20. import javax.sql.DataSource;
  21. /**
  22. * 2018/4/19 18:46
  23. */
  24. @Configuration
  25. @MapperScan("com.winterchen.dao")
  26. @EnableTransactionManagement
  27. public class DataSourceConfig {
  28. private static Logger logger = LoggerFactory.getLogger(DataSourceConfig.class);
  29. @Autowired
  30. private Environment env;
  31. @Autowired
  32. private PageInterceptor pageInterceptor;
  33. @Bean
  34. public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
  35. SqlSessionFactoryBean fb = new SqlSessionFactoryBean();
  36. fb.setDataSource(dataSource);
  37. //该配置非常的重要,如果不将PageInterceptor设置到SqlSessionFactoryBean中,导致分页失效
  38. fb.setPlugins(new Interceptor[]{pageInterceptor});
  39. fb.setTypeAliasesPackage(env.getProperty("mybatis.type-aliases-package"));
  40. fb.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(env.getProperty("mybatis.mapper-locations")));
  41. return fb.getObject();
  42. }
  43. }

DruidDBConfig.java

在Spring Boot1.4.0中驱动配置信息没有问题,但是连接池的配置信息不再支持这里的配置项,即无法通过配置项直接支持相应的连接池;这里列出的这些配置项可以通过定制化DataSource来实现。 目前Spring Boot中默认支持的连接池有dbcp,dbcp2, tomcat, hikari三种连接池。

由于Druid暂时不在Spring Bootz中的直接支持,故需要进行配置信息的定制:

  1. package com.winterchen.config;
  2. import com.alibaba.druid.pool.DruidDataSource;
  3. import org.slf4j.Logger;
  4. import org.slf4j.LoggerFactory;
  5. import org.springframework.beans.factory.annotation.Value;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.context.annotation.Primary;
  9. import javax.sql.DataSource;
  10. import java.sql.SQLException;
  11. /**
  12. * Created by Donghua.Chen on 2018/4/19.
  13. */
  14. @Configuration
  15. public class DruidDBConfig {
  16. private Logger logger = LoggerFactory.getLogger(DruidDBConfig.class);
  17. @Value("${spring.datasource.url}")
  18. private String dbUrl;
  19. @Value("${spring.datasource.username}")
  20. private String username;
  21. @Value("${spring.datasource.password}")
  22. private String password;
  23. @Value("${spring.datasource.driver-class-name}")
  24. private String driverClassName;
  25. @Value("${spring.datasource.initialSize}")
  26. private int initialSize;
  27. @Value("${spring.datasource.minIdle}")
  28. private int minIdle;
  29. @Value("${spring.datasource.maxActive}")
  30. private int maxActive;
  31. @Value("${spring.datasource.maxWait}")
  32. private int maxWait;
  33. @Value("${spring.datasource.timeBetweenEvictionRunsMillis}")
  34. private int timeBetweenEvictionRunsMillis;
  35. @Value("${spring.datasource.minEvictableIdleTimeMillis}")
  36. private int minEvictableIdleTimeMillis;
  37. @Value("${spring.datasource.validationQuery}")
  38. private String validationQuery;
  39. @Value("${spring.datasource.testWhileIdle}")
  40. private boolean testWhileIdle;
  41. @Value("${spring.datasource.testOnBorrow}")
  42. private boolean testOnBorrow;
  43. @Value("${spring.datasource.testOnReturn}")
  44. private boolean testOnReturn;
  45. @Value("${spring.datasource.poolPreparedStatements}")
  46. private boolean poolPreparedStatements;
  47. @Value("${spring.datasource.maxPoolPreparedStatementPerConnectionSize}")
  48. private int maxPoolPreparedStatementPerConnectionSize;
  49. @Value("${spring.datasource.filters}")
  50. private String filters;
  51. @Value("{spring.datasource.connectionProperties}")
  52. private String connectionProperties;
  53. @Bean //声明其为Bean实例
  54. @Primary //在同样的DataSource中,首先使用被标注的DataSource
  55. public DataSource dataSource(){
  56. DruidDataSource datasource = new DruidDataSource();
  57. datasource.setUrl(this.dbUrl);
  58. datasource.setUsername(username);
  59. datasource.setPassword(password);
  60. datasource.setDriverClassName(driverClassName);
  61. //configuration
  62. datasource.setInitialSize(initialSize);
  63. datasource.setMinIdle(minIdle);
  64. datasource.setMaxActive(maxActive);
  65. datasource.setMaxWait(maxWait);
  66. datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
  67. datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
  68. datasource.setValidationQuery(validationQuery);
  69. datasource.setTestWhileIdle(testWhileIdle);
  70. datasource.setTestOnBorrow(testOnBorrow);
  71. datasource.setTestOnReturn(testOnReturn);
  72. datasource.setPoolPreparedStatements(poolPreparedStatements);
  73. datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
  74. try {
  75. datasource.setFilters(filters);
  76. } catch (SQLException e) {
  77. logger.error("druid configuration initialization filter", e);
  78. }
  79. datasource.setConnectionProperties(connectionProperties);
  80. return datasource;
  81. }
  82. }

创建数据库和数据表

  1. CREATE DATABASE mytest;
  2. CREATE TABLE t_user(
  3. userId INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
  4. userName VARCHAR(255) NOT NULL ,
  5. password VARCHAR(255) NOT NULL ,
  6. phone VARCHAR(255) NOT NULL
  7. ) ENGINE=INNODB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8;

创建实体类:UserDomain.java

  1. package com.winterchen.model;
  2. public class UserDomain {
  3. private Integer userId;
  4. private String userName;
  5. private String password;
  6. private String phone;
  7. // get,set方法略...
  8. }

创建dao:

UserDao.java

  1. package com.winterchen.dao;
  2. import com.winterchen.model.UserDomain;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import java.util.List;
  5. public interface UserDao {
  6. int insert(UserDomain record);
  7. List<UserDomain> selectUsers();
  8. }

创建mybatis映射文件: UserMapper.xml

  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
  3. <mapper namespace="com.winterchen.dao.UserDao" >
  4. <sql id="BASE_TABLE">
  5. t_user
  6. </sql>
  7. <sql id="BASE_COLUMN">
  8. userId,userName,password,phone
  9. </sql>
  10. <insert id="insert" parameterType="com.winterchen.model.UserDomain">
  11. INSERT INTO
  12. <include refid="BASE_TABLE"/>
  13. <trim prefix="(" suffix=")" suffixOverrides=",">
  14. userName,password,
  15. <if test="phone != null">
  16. phone,
  17. </if>
  18. </trim>
  19. <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
  20. #{userName, jdbcType=VARCHAR},#{password, jdbcType=VARCHAR},
  21. <if test="phone != null">
  22. #{phone, jdbcType=VARCHAR},
  23. </if>
  24. </trim>
  25. </insert>
  26. <select id="selectUsers" resultType="com.winterchen.model.UserDomain">
  27. SELECT
  28. <include refid="BASE_COLUMN"/>
  29. FROM
  30. <include refid="BASE_TABLE"/>
  31. </select>
  32. </mapper>

创建剩余的controllerservice包和文件

UserService.java

  1. package com.winterchen.service.user;
  2. import com.winterchen.model.UserDomain;
  3. import java.util.List;
  4. /**
  5. * Created by Administrator on 2018/4/19.
  6. */
  7. public interface UserService {
  8. int addUser(UserDomain user);
  9. List<UserDomain> findAllUser(int pageNum, int pageSize);
  10. }

UserServiceImpl

  1. package com.winterchen.service.user.impl;
  2. import com.github.pagehelper.PageHelper;
  3. import com.winterchen.dao.UserDao;
  4. import com.winterchen.model.UserDomain;
  5. import com.winterchen.service.user.UserService;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.stereotype.Service;
  8. import java.util.List;
  9. /**
  10. * Created by Administrator on 2017/8/16.
  11. */
  12. @Service(value = "userService")
  13. public class UserServiceImpl implements UserService {
  14. @Autowired
  15. private UserDao userDao;//这里会报错,但是并不会影响
  16. @Override
  17. public int addUser(UserDomain user) {
  18. return userDao.insert(user);
  19. }
  20. /*
  21. * 这个方法中用到了我们开头配置依赖的分页插件pagehelper
  22. * 很简单,只需要在service层传入参数,然后将参数传递给一个插件的一个静态方法即可;
  23. * pageNum 开始页数
  24. * pageSize 每页显示的数据条数
  25. * */
  26. @Override
  27. public List<UserDomain> findAllUser(int pageNum, int pageSize) {
  28. //将参数传给这个方法就可以实现物理分页了,非常简单。
  29. PageHelper.startPage(pageNum, pageSize);
  30. return userDao.selectUsers();
  31. }
  32. }

UserController.java

  1. package com.winterchen.controller;
  2. import com.github.pagehelper.PageHelper;
  3. import com.winterchen.model.UserDomain;
  4. import com.winterchen.service.user.UserService;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.stereotype.Controller;
  7. import org.springframework.web.bind.annotation.*;
  8. /**
  9. * Created by Administrator on 2017/8/16.
  10. */
  11. @Controller
  12. @RequestMapping(value = "/user")
  13. public class UserController {
  14. @Autowired
  15. private UserService userService;
  16. @ResponseBody
  17. @PostMapping("/add")
  18. public int addUser(UserDomain user){
  19. return userService.addUser(user);
  20. }
  21. @ResponseBody
  22. @GetMapping("/all")
  23. public Object findAllUser(
  24. @RequestParam(name = "pageNum", required = false, defaultValue = "1")
  25. int pageNum,
  26. @RequestParam(name = "pageSize", required = false, defaultValue = "10")
  27. int pageSize){
  28. //开始分页
  29. PageHelper.startPage(pageNum,pageSize);
  30. return userService.findAllUser(pageNum,pageSize);
  31. }
  32. }

项目最终的结构

项目结构

到这里如果项目就成功搭建完成了,如果还是报错的话,请仔细看看配置,后面会给出源码地址,程序员就是要不断和bug进行斗争,加油。

测试

启动项目

启动项目

这样就表示启动成功了

然后,开始测试吧,博主使用的是postMan,一个进行http请求的测试工具

添加数据

添加数据

查询数据

查询数据

源码地址:

https://github.com/WinterChenS/springboot2-mybatis-demo

转载于:https://my.oschina.net/u/3941962/blog/1925530

声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号