springboot作為一個微服務框架,給我們開發人員提供極大的便利,秉着約定大於配置的原則,通過starter包的形式為我們做了許多默認的配置,在進行數據持久化到關系型數據庫時,我們一般都會首選spring data jpa,springboot為我們提供了starter包,只需配置很少的參數,就能滿足我們的需求,非常方便。但是當我們遇到一些比較復雜的查詢、多表關聯查詢及動態sql時,mybatis則在這方面更出色,並且在使用mybatis時我們可以通過sql優化來提高查詢效率,springboot並沒有給我們提供整合mybatis的starter包,因此我們需要自己整合。記錄一下我的整合過程,以供后續參考。
本人使用的是sts,新建springboot項目加入web、mysql、mybatis模塊,springboot版本2.0.1。
1、pom.xml
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.example</groupId> <artifactId>springboot-mybatis</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>springboot-mybatis</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.0.BUILD-SNAPSHOT</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!-- 分頁插件 --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <!-- alibaba的druid數據庫連接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.9</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </repository> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </repository> </repositories> <pluginRepositories> <pluginRepository> <id>spring-snapshots</id> <name>Spring Snapshots</name> <url>https://repo.spring.io/snapshot</url> <snapshots> <enabled>true</enabled> </snapshots> </pluginRepository> <pluginRepository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> <snapshots> <enabled>false</enabled> </snapshots> </pluginRepository> </pluginRepositories> </project>
2、實體類UserDomain.java
package com.example.demo.model; public class UserDomain { private Integer userId; private String userName; private String password; private String phone; //get和set方法 }
3、持久化接口
package com.example.demo.dao; import java.util.List; import com.example.demo.model.UserDomain; public interface UserDao { int insert(UserDomain record); List<UserDomain> selectUsers(); }
4、建表語句,注意數據庫的ip和名稱
CREATE TABLE t_user( user_id INT NOT NULL PRIMARY KEY AUTO_INCREMENT, user_name VARCHAR(255) NOT NULL , password VARCHAR(255) NOT NULL , phone VARCHAR(255) NOT NULL ) ENGINE=INNODB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8;
5、service層
package com.example.demo.service; import com.example.demo.model.UserDomain; import com.github.pagehelper.PageInfo; public interface UserService { int addUser(UserDomain user); PageInfo<UserDomain> findAllUser(int pageNum, int pageSize); } package com.example.demo.service.impl; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import com.example.demo.dao.UserDao; import com.example.demo.model.UserDomain; import com.example.demo.service.UserService; import com.github.pagehelper.PageHelper; import com.github.pagehelper.PageInfo; @Service(value = "userService") public class UserServiceImpl implements UserService { @Autowired private UserDao userDao; @Override public int addUser(UserDomain user) { return userDao.insert(user); } //分頁查詢 @Override public PageInfo<UserDomain> findAllUser(int pageNum, int pageSize) { PageHelper.startPage(pageNum, pageSize); List<UserDomain> userDomains = userDao.selectUsers(); PageInfo result = new PageInfo(userDomains); return result; } }
6、控制層
package com.example.demo.controller; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.ResponseBody; import com.example.demo.model.UserDomain; import com.example.demo.service.UserService; @Controller @RequestMapping(value = "/user") public class UserController { @Autowired private UserService userService; @ResponseBody @PostMapping("/add") public int addUser(UserDomain user){ return userService.addUser(user); } @ResponseBody @GetMapping("/all") public Object findAllUser( @RequestParam(name = "pageNum", required = false, defaultValue = "1") int pageNum, @RequestParam(name = "pageSize", required = false, defaultValue = "10") int pageSize){ return userService.findAllUser(pageNum,pageSize); } }
7、application.yml
server: port: 8080 spring: datasource: name: mysql_test type: com.alibaba.druid.pool.DruidDataSource #druid相關配置 druid: #監控統計攔截的filters filters: stat driver-class-name: com.mysql.jdbc.Driver #基本屬性 url: jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=UTF-8&allowMultiQueries=true username: root password: root #配置初始化大小/最小/最大 initial-size: 1 min-idle: 1 max-active: 20 #獲取連接等待超時時間 max-wait: 60000 #間隔多久進行一次檢測,檢測需要關閉的空閑連接 time-between-eviction-runs-millis: 60000 #一個連接在池中最小生存的時間 min-evictable-idle-time-millis: 300000 validation-query: SELECT 'x' test-while-idle: true test-on-borrow: false test-on-return: false #打開PSCache,並指定每個連接上PSCache的大小。oracle設為true,mysql設為false。分庫分表較多推薦設置為false pool-prepared-statements: false max-pool-prepared-statement-per-connection-size: 20 mybatis: mapper-locations: classpath:mapper/*.xml type-aliases-package: com.example.demo.model #pagehelper pagehelper: helperDialect: mysql reasonable: true supportMethodsArguments: true params: count=countSql returnPageInfo: check
8、UserMapper.xml
<?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.demo.dao.UserDao" > <sql id="BASE_TABLE"> t_user </sql> <sql id="BASE_COLUMN"> userId,userName,password,phone </sql> <insert id="insert" parameterType="com.example.demo.model.UserDomain"> INSERT INTO <include refid="BASE_TABLE"/> <trim prefix="(" suffix=")" suffixOverrides=","> userName,password, <if test="phone != null"> phone, </if> </trim> <trim prefix="VALUES(" suffix=")" suffixOverrides=","> #{userName, jdbcType=VARCHAR},#{password, jdbcType=VARCHAR}, <if test="phone != null"> #{phone, jdbcType=VARCHAR}, </if> </trim> </insert> <select id="selectUsers" resultType="com.example.demo.model.UserDomain"> SELECT <include refid="BASE_COLUMN"/> FROM <include refid="BASE_TABLE"/> </select> </mapper>
9、項目目錄結構如下
在項目啟動類SpringbootMybatisApplication上加上@MapperScan("com.example.demo.dao")注解,以便spring容器可以掃描到持久化接口,創建對應的代理類。springboot默認為mybatis、jpa、jdbc等開啟了事務,如果需要開啟事務,則在service層對應的方法上加上@Transactional即可。啟動項目,訪問localhost:8080/user/add,添加用戶;訪問localhost:8080/user/all,可以看到分頁查詢效果。
補充:相比與映射文件方式,注解方式會更加方便,但是功能有限,使用注解方式只需做如下修改即可
1、持久化接口修改為如下
package com.example.demo.dao; import java.util.List; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Mapper; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import com.example.demo.model.UserDomain; @Mapper public interface UserDao { @Insert("INSERT INTO t_user(name, password, phone) VALUES(#{name}, #{password}, #{phone})") int insert(@Param("name") String name, @Param("password") String password, @Param("phone") String phone); @Select("SELECT * FROM t_user ") List<UserDomain> selectUsers(); }
2、刪除掉UserMappper.xml文件即可。