30分鐘帶你瞭解Springboot與Mybatis整合最佳實踐

前言:Springboot怎麼使用想必也無需我多言,Mybitas做爲實用性極強的ORM框架也深受廣大開發人員喜好,有關如何整合它們的文章在網絡上隨處可見。可是今天我會從實戰的角度出發,談談我對兩者結合與使用的最佳實踐。java

1、依賴與pommysql

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.0.4.RELEASE</version>
    <relativePath /> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
    </dependency>
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>1.3.1</version>
    </dependency>
</dependencies>

目前SpringBoot官方的最新版本是2.0.4.RELEASE咱們就以這個版本爲基礎,2.0如下版本可能會有些區別這裏很少解釋。web

2、建立配置文件和啓動類spring

Spring官方推薦使用yml文件,既然是最佳實踐咱們就按照官方的要求來作。sql

application.ymlapache

server:
   port: 8090
spring:
   datasource:
      mimas:
         driverClassName: com.mysql.jdbc.Driver
         jdbcUrl: jdbc:mysql://192.168.56.101:3306/mimas
         username: root
         password: 12345678
logging:
   level:
      com.learnhow.springboot.mybatis.dao: debug

 解釋一下三個部分的含義:springboot

(1)server:表明當前服務經過8090端口訪問。服務器

(2)spring:配置了一個名爲mimas的數據源,若是項目須要多個數據源能夠按照這樣的方式將數據源配置成不一樣的名稱。網絡

(3)logging:定義dao包下的日誌記錄級別爲debug,標準輸出會顯示sql語句(這一點對開發仍是很重要的)session

Application.java

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

3、xml文件與接口

Springboot與Mybatis整合之後可使用annotation(註解)和xml(配置文件)兩種方式編寫sql語句,我推薦的作法是後者。就目前我接觸到的項目來講,項目部署環境都比較嚴格,每每修改一個BUG到從新部署完成少則2個小時,多則數天。而不少BUG有時候僅僅須要修改幾條SQL語句。若是採用配置文件的方式,這類問題只須要在服務器上修改一下文件而後再重啓一下服務就能完成。其次,我我的也很不喜歡Java代碼和SQL代碼混再一塊兒開發方式,既不美觀也不便於維護。因此一般在項目初期我都會盡可能避免這類爲之後埋坑的行爲。

如下是一個典型的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.learnhow.springboot.mybatis.dao.mimas.UserDao">
    <resultMap type="User" id="UserMap">
        <id column="id" property="id" jdbcType="BIGINT" />
        <result column="user_name" property="username" jdbcType="VARCHAR" />
        <result column="user_age" property="age" jdbcType="INTEGER" />
        <result column="user_gender" property="gender" jdbcType="INTEGER" />
        <result column="ep_id" property="enterpriseId" jdbcType="BIGINT" />
    </resultMap>
    <select id="getAll" resultType="User">
        select * from user_t
    </select>
    
    <select id="getOne" resultType="User" parameterType="Long">
        select * from user_t t where t.id = #{id}
    </select>
    
    <insert id="saveUsers">
        insert into user_t(user_name, user_age, user_gender, ep_id) values    
        <foreach collection="users" item="user" separator=",">
            (#{user.username}, #{user.age}, #{user.gender}
            <trim prefix="," suffix=")">
                <choose>
                    <when test="user.enterpriseId != null and user.enterpriseId != 0">
                        #{user.enterpriseId}
                    </when>
                    <otherwise>
                        null
                    </otherwise>
                </choose>
            </trim>
        </foreach>
    </insert>
    
    <update id="modifyEnterpriseId">
        update user_t set ep_id = #{eid} where id = #{uid}
    </update>
</mapper>

具體語句和表原型你們不用過度關心,一個mybatis的sql配置文件主要有幾個細節須要注意:

(1)配置文件中的sql語句與dao接口是如何結合的?

實際上mybatis先掃描配置文件而後將sql語句經過namespace和id反向註冊到dao接口中,因此namespace屬性表示接口類的全限定名,每個方法的id則對應接口類中的每個接口方法。

(2)查詢中遇到多個參數的狀況怎麼辦?

若是多個參數都屬於一個單一實體,咱們能夠直接使用實體對象最爲參數。例如配置文件中的兩條select語句。若是實體的屬性名與表的字段明稱不一致能夠經過resultMap作關聯。

若是多個參數不屬於單一實體,咱們能夠在接口方法中經過@Param指定參數的名字而後在語句中使用(參考update方法)。咱們應儘可能避免在配置文件中使用parameterMap方法和在接口中使用Map對象,由於這樣都不利於大型代碼的維護。

(3)根據狀況的不一樣動態生成SQL語句也是Mybatis的一大亮點,我很喜歡這個特徵(參考insert方法)。不過在實際開發中我不併要求開發人員大量使用(任何一種增長編寫難度和提升維護成本的行爲都應該被謹慎選擇)。

import java.util.List;
import java.util.Set;

import org.apache.ibatis.annotations.Param;

import com.learnhow.springboot.mybatis.entity.User;

public interface UserDao {
    List<User> getAll();

    User getOne(long id);

    int saveUsers(@Param("users") Set<User> users);
    
    int modifyEnterpriseId(@Param("uid") long userId, @Param("eid") long enterpriseId);
}

4、Mybatis配置文件

DataSourceConfig.java

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.DataSourceBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

@Configuration
@MapperScan(basePackages = "com.learnhow.springboot.mybatis.dao.mimas", // 爲指定包中的DAO注入SqlSessionTemplate
            sqlSessionTemplateRef = "mimasSqlSessionTemplate") // 指定SqlSessionTemplate
public class DataSourceConfig {
    @Bean(name = "mimasDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.mimas")
    @Primary
    public DataSource testDataSource() {
        return DataSourceBuilder.create().build();
    }
    
    @Bean(name = "mimasSqlSessionFactory")
    @Primary
    public SqlSessionFactory testSqlSessionFactory(@Qualifier("mimasDataSource") DataSource dataSource)
            throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(
                new PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/mimas/*.xml"));
        bean.setTypeAliasesPackage("com.learnhow.springboot.mybatis.entity"); // 指定entity的別名
        return bean.getObject();
    }
    
    @Bean(name = "mimasSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate testSqlSessionTemplate(
            @Qualifier("mimasSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

Springboot的項目都須要配置主數據源,MapperScan表示掃描dao.mimas.*下的全部接口並注入指定的SessionTemplate。下面的三個方法就是產生這個SessionTemplate的過程。

5、事務控制

傳統的方法是在service中作事務控制,咱們仍是沿用這樣的開發邏輯。

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.learnhow.springboot.mybatis.dao.mimas.UserDao;
import com.learnhow.springboot.mybatis.entity.User;

@Component
public class UserService {
    @Autowired
    private UserDao userDao;
    
    @Transactional
    public int saveUsers(Set<User> users) {
        return userDao.saveUsers(users);
    }
    
    @Transactional
    public void modifyEnterpriseIdByUserId(Set<User> users) {
        for(User u : users) {
            userDao.modifyEnterpriseId(u.getId(), u.getEnterpriseId());
        }
    }
}

 

至此,有關Springboot和mybatis的整合咱們已經完成。完整代碼因爲十分簡單我就不提供連接了,有須要幫助的小夥伴能夠私信@我。

相關文章
相關標籤/搜索