第五篇:SpringBoot整合Mybatis

前言

  前面两篇文章和读者聊了Spring Boot中最简单的数据持久化方案JdbcTemplate,JdbcTemplate虽然简单,但是用的并不多,因为它没有MyBatis方便,在Spring+SpringMVC中整合MyBatis步骤还是有点复杂的,要配置多个Bean,Spring Boot中对此做了进一步的简化,使MyBatis基本上可以做到开箱即用,本文就来看看在Spring Boot中MyBatis要如何使用。

工程创建

pom依赖

<!-- web支持: 1、web mvc; 2、restful; 3、jackjson支持; 4、aop ... -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
 
<!-- servlet依赖 -->
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>javax.servlet-api</artifactId>
    <scope>provided</scope>
</dependency>
 
<dependency>
    <groupId>javax.servlet</groupId>
    <artifactId>jstl</artifactId>
</dependency>
 
<!-- tomcat 的支持. -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-tomcat</artifactId>
    <scope>provided</scope>
</dependency>
<dependency>
    <groupId>org.apache.tomcat.embed</groupId>
    <artifactId>tomcat-embed-jasper</artifactId>
    <scope>provided</scope>
</dependency>
 
<!-- FreeeMarker模板引擎所需依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-freemarker</artifactId>
</dependency>
 
<!-- springboot测试 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
</dependency>
 
<!-- mysql数据库驱动 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- jdbc依赖 -->
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
 
<!-- spring-boot mybatis依赖:注意:不要使用1.0.0版本,因为还不支持拦截器插件,我这里 1.1.1 目前可用 -->
<dependency>
    <groupId>org.mybatis.spring.boot</groupId>
    <artifactId>mybatis-spring-boot-starter</artifactId>
    <version>1.1.1</version>
</dependency>
 
<!-- 分页插件 -->
<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>4.1.0</version>
</dependency>
 
<dependency>
    <groupId>junit</groupId>
    <artifactId>junit</artifactId>
    <version>4.12</version>
    <scope>test</scope>
</dependency>

实体类

public class User {
    private Long id;
    private String username;
    private String address;
    // 省略get set  
}

application.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
    username: root
    password: 123456
    type: com.alibaba.druid.pool.DruidDataSource

注解方式

mapper接口

@Mapper
public interface UserMapper1 {
    @Select("select * from user")
    List<User> getAllUsers();
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "username", column = "u"),
            @Result(property = "address", column = "a")
    })
    @Select("select id as id, username as u, address as a from user where id = #{id}")
    User getUserById(Long id);

    @Select("select * from user where username like CONCAT('%',#{name},'%')")
    List<User> getUsersByName(String name);

    @Insert({"insert into user(username, address) values(#{username},#{address})"})
    @SelectKey(statement = "", keyProperty = "", before = false, resultType = Integer.class)
    Integer addUser(User user);

    @Update("update user set username = #{username}, address = #{address} where id = #{id}")
    Integer updateUserById(User user);

    @Delete("delete from user where id = #{id}")
    Integer deleteUserById(Integer id);
}

UserService

@Service
public class UserService1 {
    @Autowired
    private UserMapper1 userMapper1;

    public List<User> getAllUser(){
        return userMapper1.getAllUsers();
    }

    public List<User> getUsersByName(String name){
        return userMapper1.getUsersByName(name);
    }

    public User getUserById(Long id){
        return userMapper1.getUserById(id);
    }

    public Integer addUser(User user){
        return userMapper1.addUser(user);
    }

    public Integer updateUserById(User user){
        return userMapper1.updateUserById(user);
    }

    public Integer deleteUserById(Integer id){
        return userMapper1.deleteUserById(id);
    }
}

xml方式

mapper接口

import java.util.List;
@Mapper
public interface UserMapper {
    List<User> getAllUser();

    Integer addUser(User user);

    Integer updateUserById(User user);

    Integer deleteUserById(Integer id);
}

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.demo.dao.UserMapper">
    <select id="getAllUser" resultType="com.demo.entity.User">
        select * from user;
    </select>
    <insert id="addUser" parameterType="com.demo.entity.User">
        insert into user (username,address) values (#{username},#{address});
    </insert>
    <update id="updateUserById" parameterType="com.demo.entity.User">
        update user set username=#{username},address=#{address} where id=#{id}
    </update>
    <delete id="deleteUserById">
        delete from user where id=#{id}
    </delete>
</mapper>

修改pomapplication.yml

 

整体测试

package com.demo;

import com.demo.entity.User;
import com.demo.service.UserService1;
import com.demo.service.UserService2;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.List;

@RunWith(SpringRunner.class)
@SpringBootTest
public class MybatisTest {
    @Autowired
    private UserService1 userService1;

    @Autowired
    private UserService2 userService2;

    //mybatis注解测试

    @Test
    public void addUser(){
        User user = new User();
        user.setUsername("2神经薛之谦2");
        user.setAddress("上海");
        int result = userService1.addUser(user);
        System.out.println(result==1 ? "Success":"fail");
    }

    @Test
    public void updateUser(){
        User user = new User();
        user.setId(3L);
        user.setUsername("岳云鹏");
        user.setAddress("北京");
        int result = userService1.updateUserById(user);
        System.out.println(result==1 ? "Success":"fail");
    }

    @Test
    public void delUser(){
        int result = userService1.deleteUserById(2);
        System.out.println(result==1 ? "Success":"fail");
    }

    @Test
    public void getUserById(){
        User user = userService1.getUserById(1L);
        System.out.println(user.toString());
    }

    @Test
    public void getUserByName(){
        List<User> users = userService1.getUsersByName("薛");
        for (User user : users){
            System.out.println(user.toString());
        }
    }

    @Test
    public void getAllUsers(){
        List<User> users = userService1.getAllUser();
        for (User user : users){
            System.out.println(user.toString());
        }
    }

    //xml测试
    @Test
    public void addUserXml(){
        User user = new User();
        user.setUsername("张佳宁");
        user.setAddress("北京");
        int result = userService2.addUser(user);
        System.out.println(result==1 ? "Success":"fail");
    }

    @Test
    public void updateUserXml(){
        User user = new User();
        user.setId(5L);
        user.setUsername("薛之谦");
        user.setAddress("北京");
        int result = userService2.updateUserById(user);
        System.out.println(result==1 ? "Success":"fail");
    }

    @Test
    public void delUserXml(){
        int result = userService2.deleteUserById(6);
        System.out.println(result==1 ? "Success":"fail");
    }

    @Test
    public void getAllUsersXml(){
        List<User> users = userService2.getAllUser();
        for (User user : users){
            System.out.println(user.toString());
        }
    }
}

原理分析

在SSM整合中,开发者需要自己提供两个Bean,一个SqlSessionFactoryBean,还有一个是MapperScannerConfigurer,在Spring Boot中,这两个东西虽然不用开发者自己提供了,但是并不意味着这两个Bean不需要了,在org.mybatis.spring.boot.autoconfigure.MybatisAutoConfiguration类中,我们可以看到Spring Boot提供了这两个Bean,部分源码如下:

@org.springframework.context.annotation.Configuration
@ConditionalOnClass({ SqlSessionFactory.class, SqlSessionFactoryBean.class })
@ConditionalOnSingleCandidate(DataSource.class)
@EnableConfigurationProperties(MybatisProperties.class)
@AutoConfigureAfter(DataSourceAutoConfiguration.class)
public class MybatisAutoConfiguration implements InitializingBean {

  @Bean
  @ConditionalOnMissingBean
  public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
    SqlSessionFactoryBean factory = new SqlSessionFactoryBean();
    factory.setDataSource(dataSource);
    return factory.getObject();
  }
  @Bean
  @ConditionalOnMissingBean
  public SqlSessionTemplate sqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
    ExecutorType executorType = this.properties.getExecutorType();
    if (executorType != null) {
      return new SqlSessionTemplate(sqlSessionFactory, executorType);
    } else {
      return new SqlSessionTemplate(sqlSessionFactory);
    }
  }
  @org.springframework.context.annotation.Configuration
  @Import({ AutoConfiguredMapperScannerRegistrar.class })
  @ConditionalOnMissingBean(MapperFactoryBean.class)
  public static class MapperScannerRegistrarNotFoundConfiguration implements InitializingBean {

    @Override
    public void afterPropertiesSet() {
      logger.debug("No {} found.", MapperFactoryBean.class.getName());
    }
  }
}

  从类上的注解可以看出,当当前类路径下存在SqlSessionFactory、 SqlSessionFactoryBean以及DataSource时,这里的配置才会生效,SqlSessionFactory和SqlTemplate都被提供了。

posted @ 2019-11-23 19:21  王大军  阅读(156)  评论(0编辑  收藏  举报