Spring Boot集成MyBatis访问数据库

2,522 views

基于spring boot开发的微服务应用,与MyBatis如何集成?

集成方法

可行的方法有:

  1. 基于XML或者Java Config,构建必需的对象,配置MyBatis。
  2. 使用MyBatis官方提供的组件,实现MyBatis的集成。

方法一

建议参考如下文章,完成集成的验证。

由于不是本文的重点,因此不附上样例。

方法二

有如下步骤:

  • 修改pom.xml,增加软件依赖
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.2.0</version>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.21</version>
    </dependency>
    
  • 修改application.yml,增加数据源的定义
    spring:
        datasource:
            url: jdbc:mysql://localhost:3306/test
            username: root
            password: 123456
            driver-class-name: com.mysql.jdbc.Driver
    
  • 修改application.yml,增加MyBatis的配置
    mybatis:
        type-aliases-package: com.example.domain.model
        type-handlers-package: com.example.typehandler
        configuration:
            map-underscore-to-camel-case: true
            default-fetch-size: 100
            default-statement-timeout: 30
    

日志的配置

通过观察日志,可有效的分析MyBatis生成的SQL,检查SQL配置的正确性。
修改application.yml,增加如下配置

logging:
    level:
        net: 
            jackieathome:
                db:
                    mapper: DEBUG

其中net.jackieathome.db.mapper下定义了访问数据库的mapper接口。

输出的日志样例如下

2017-04-16 11:32:23.266 DEBUG 27801 --- [io-11002-exec-1] n.j.db.mapper.UserMapper.createUser      : ==>  Preparing: insert into `user`(id, name, password) values(?, ?, ?) 
2017-04-16 11:32:23.293 DEBUG 27801 --- [io-11002-exec-1] n.j.db.mapper.UserMapper.createUser      : ==> Parameters: id1492313542(String), null, null
2017-04-16 11:32:23.366 DEBUG 27801 --- [io-11002-exec-1] n.j.db.mapper.UserMapper.createUser      : <==    Updates: 1
2017-04-16 11:32:23.372 DEBUG 27801 --- [io-11002-exec-1] n.j.db.mapper.UserMapper.findUserById    : ==>  Preparing: select * from `user` where id = ? 
2017-04-16 11:32:23.373 DEBUG 27801 --- [io-11002-exec-1] n.j.db.mapper.UserMapper.findUserById    : ==> Parameters: id1492313542(String)
2017-04-16 11:32:23.417 DEBUG 27801 --- [io-11002-exec-1] n.j.db.mapper.UserMapper.findUserById    : <==      Total: 1

事务的使用

依据MyBatis的官方文档,允许用户将事务交给Spring来管理,使用编程和注解来控制事务。这里以注解方式来举例说明使用方法,样例代码如下:

  1. mapper的定义,如下
    package net.jackieathome.db.mapper;
    
    import java.util.List;
    
    import org.apache.ibatis.annotations.Mapper;
    import org.apache.ibatis.annotations.Param;
    
    import net.jackieathome.bean.User;
    
    @Mapper
    public interface UserMapper {
        // 创建用户
        void createUser(User user);
        // 查找用户
        User findUserById(@Param("id") String id);
    }
    
  2. 数据库访问的中间层代码,对上述mapper进行了封装。

    使用@Transactional标记该类,表明该类的公有方法全部都启用了事务的支持。关于@Transactional的使用,可以参考相关的官方文档。

    package net.jackieathome.dao;
    
    import java.util.ArrayList;
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Component;
    import org.springframework.transaction.annotation.Transactional;
    
    import net.jackieathome.bean.User;
    import net.jackieathome.db.mapper.UserMapper;
    
    @Component
    @Transactional
    public class UserDao {
        @Autowired
        private UserMapper userMapper;
    
        /**
         * 重复插入相同的用户数据,确认事务是否生效
         */
        public List<String> createBatch() {
    
            long time = System.currentTimeMillis() / 1000;
            User user = null;
            List<String> ids = new ArrayList<>();
    
            String id = "id" + time;
            String name = "name" + time;
            String password = "password" + time;
    
            user = new User();
            user.setId(id);
            user.setName(name);
            user.setPassword(password);
            userMapper.createUser(user);
            ids.add(id);
    
            user = new User();
            user.setId(id);
            user.setName(name);
            user.setPassword(password);
            userMapper.createUser(user);
            ids.add(id);
    
            return ids;
        }
    }
    
  3. 业务层实现
    package net.jackieathome.controller;
    
    import java.util.List;
    
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.web.bind.annotation.PathVariable;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.bind.annotation.RestController;
    
    import net.jackieathome.bean.User;
    import net.jackieathome.dao.UserDao;
    import net.jackieathome.db.mapper.UserMapper;
    
    @RestController
    public class UserController {
        @Autowired
        private UserMapper userMapper;   
        @Autowired
        private UserDao userDao;
        
        @RequestMapping(method = RequestMethod.GET, value = "/user/create/batch")
        public List<User> createBatch() {
            try
            {
                userDao.createBatch();
            }
            catch (Exception e)
            {
                
            }
            return userMapper.loadAllUsers();
        }
    }
    

从实际测试看,上述事务的实现有效,可保证当数据出现主键冲突时,事务中的插入操作可全部撤销,不会出现部分数据插入成功、部分失败的现象。
注意事项:

由于注解事务的实现依赖Spring AOP,因此只有当注入行为存在时,注解事务的控制才会生效。

  1. 假如在上述UserController类中定义createBatch方法,并且使用注解@Transactional标记,经验证可确认此时注解事务是无效的。
  2. 假如在上述UserDao中定义了多个公有方法,存在相互调用的行为,基于相同的原因,这些方法相互调用时注解事务并不会生效。如果确实需要保证事务可用,可以考虑调整类的设计或者使用编程的方式来控制事务。

参考资料

Spring Boot与MyBatis

Spring与MyBatis



若非注明,均为原创,欢迎转载,转载请注明来源:Spring Boot集成MyBatis访问数据库

关于 JackieAtHome

基层程序员,八年之后重新启航

此条目发表在 Spring Boot 分类目录,贴了 , 标签。将固定链接加入收藏夹。