1. 程式人生 > >Spring Boot(3)--使用Mybatis

Spring Boot(3)--使用Mybatis

本章內容

  • 新增mybatis支援
  • 多資料來源配置
  • 總結

        前一章也說過,連線使用資料庫主要有兩種方式,一種是ORM框架,使用對像來生成需要的SQL,代表的有JPA和Hibernate。另一種方式就是直接使用SQL操作,最常用的就是Mybatis。


新增mybatis


    首先,新增相關的jar包

<!--mybatis連線-->
<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>1.2.0</version>
</dependency>
<!--mybatis分頁外掛-->
<dependency>
   <groupId>com.github.miemiedev</groupId>
   <artifactId>mybatis-paginator</artifactId>
   <version>1.2.17</version>
</dependency>

其次,在application.yml配置檔案中,標明mybatis需要掃描的檔案,需要在resources目錄下新增mapper包用於存放mybatis的SQL配置檔案,如果業務比較多,想區分不同的資料夾,也可以,只需要按一定的規則配置即可,例如:classpath:mapper/*/*.xml

mybatis:
  config-location: classpath:mybatis-config.xml
  mapper-locations: classpath:mapper/*.xml

mybatis-config.xml檔案內容

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>
    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer" />
        <typeAlias alias="Long" type="java.lang.Long" />
        <typeAlias alias="HashMap" type="java.util.HashMap" />
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap" />
        <typeAlias alias="ArrayList" type="java.util.ArrayList" />
        <typeAlias alias="LinkedList" type="java.util.LinkedList" />
        <!--實體類包-->
        <package name="com.xps.sc.springbootdemo.entity"></package>
    </typeAliases>

    <!--引用分頁外掛-->
    <plugins>
        <plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor">
            <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.MySQLDialect"/>
        </plugin>
    </plugins>
</configuration>

最後,需要在啟動入口,使用@MapperScan標註mybatis掃描的Dao層的包名(或者在每一個Dao上使用@Mapper,這樣比較麻煩)。

@SpringBootApplication
//@EnableTransactionManagement
@MapperScan("com.xps.sc.springbootdemo.mapper")
public class SpringBootDemoApplication {


   public static void main(String[] args) {

      SpringApplication.run(SpringBootDemoApplication.class, args);
   }

}

這樣配置的部分就已經完成了。接下來我們來測試一下。新增一個BatisUserMapper的介面

public interface BatisUserMapper {

    @Select("select * from T_TEST_USER where user_id = #{userId}")
    @Results({
            @Result(property = "userId",column = "user_id",javaType = Long.class),
            @Result(property = "userName",column = "user_name",javaType = String.class),
            @Result(property = "nickName",column = "nick_name",javaType = String.class),
            @Result(property = "email",column = "email",javaType = String.class),
            @Result(property = "createTime",column = "create_time",javaType = Date.class)
    })
    User getUserById(Long userId);

    @Insert("insert into T_TEST_USER(user_id,user_name,nick_name,pass_word,email,reg_time,create_time) values(" +
            "#{userId,jdbcType=BIGINT},#{userName,jdbcType=VARCHAR},#{nickName},#{passWord},#{email},#{regTime},#{createTime,jdbcType=TIMESTAMP})")
    void insert(User user);

    @Update("update T_TEST_USER set email=#{email} where user_id = #{userId}")
    void update(User user);

    //以下是使用mapper.xml配置檔案來配置sql

    List<User> getUserList(String nickName);

    void insertUser(User user);

    void updateUser(User user);

    void delete(Long userId);
}

可以看到,mybatis提供了相關的註解來配置SQL及欄位元素等等,與xml中的元素類似。兩者可以同時使用,一般來說比較簡單的增、刪、改可以使用註解的方式,比較複雜的業務還是使用xml直接寫sql比較方便。
測試:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class BatisUserTests {

    private Logger logger = LoggerFactory.getLogger(HelloBootController.class);

    @Autowired
    private BatisUserMapper userMapper;
    @Before
    public void setUp() throws Exception {
    }

    @Test
    public void save() throws Exception {
        User user = new User();
        user.setUserName("eea");
        user.setPassWord("eea");
        user.setEmail("[email protected]");
        user.setNickName("eea在");
        user.setRegTime("2018-12-13 11:19:10");
        user.setCreateTime(new Date());
        //userMapper.insert(user);
        userMapper.insertUser(user);
    }
}

我與jpa一起使用的時候,總是報找不到entityFactory的錯誤。不知道是不是不能一起使用,還是我配置的有問題。這個以後再研究。

 

多資料來源配置


       在比較複雜的業務中我們可能需要跨多個數據庫來操作業務,這樣就需要mybatis對多資料來源的支援。在spring boot中使用多資料來源也是非常簡單的。
   首先,配置相關的資料來源

spring:
  datasource:
    master: #注意這裡只能使用jdbc-url,直接使用url會報jdbcUrl is required with driverClassName的錯誤
    jdbc-url: jdbc:mysql://localhost:3306/world?serverTimezone=UTC
     username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver
slave:
 jdbc-url: jdbc:mysql://localhost:3306/sys?serverTimezone=UTC
 username: root
 password: root
 driver-class-name: com.mysql.cj.jdbc.Driver

然後,寫兩個配置類(有多少個數據源就寫多少個配置類,但要注意DataSource只能有一個@Primary),例如,master資料來源的配置如下(其它的都類似只是相關的名稱需要換一下):

@Configuration
@MapperScan(basePackages = "com.xps.sc.springbootdemo.mapper1",
        sqlSessionTemplateRef  = "masterSqlSessionTemplate")
public class DataSourceMasterConfig {

   // @Bean(name = "masterDataSourceProperties")
   // @ConfigurationProperties(prefix = "spring.datasource.master")
    //@Qualifier("masterDataSourceProperties")
   // @Primary
    public DataSourceProperties masterDataSourceProperties(){
        return new DataSourceProperties();
    }

    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        //return masterDataSourceProperties().initializeDataSourceBuilder().build();
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
        bean.setDataSource(dataSource);
        bean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapper1/*.xml"));
        return bean.getObject();
    }

    @Bean(name = "masterTransactionManager")
    @Primary
    public DataSourceTransactionManager masterTransactionManager(@Qualifier("masterDataSource") DataSource dataSource) {
        return new DataSourceTransactionManager(dataSource);
    }

    @Bean(name = "masterSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

最後,根據相關的配置 增加對應的包,再編寫相應的Dao(與上面的UserMapper.java一樣,只是所放置的目錄不同)和mapper.xml配置檔案即可。
測試,只查詢出各自庫中的資料,說明多資料來源已經配置成功:

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
@WebAppConfiguration
public class BatisUserTests {

    private Logger logger = LoggerFactory.getLogger(HelloBootController.class);

    @Autowired
    private BatisUserMapper userMapper;

    @Autowired
    private UserMasterMapper masterMapper;

    @Autowired
    private UserSlaveMapper slaveMapper;

    @Before
    public void setUp() throws Exception {

    }
@Test
public void findByDiffDataSource() throws Exception {
    User user = masterMapper.getUserById(6l);
    logger.debug("查詢出來的user:{}", JSON.toJSONString(user));

    user = slaveMapper.getUserById(6l);
    logger.debug("查詢出來的user:{}", JSON.toJSONString(user));

    user = userMapper.getUserById(6l);
    logger.debug("查詢出來的user:{}", JSON.toJSONString(user));
}
}

附,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.xps.sc.springbootdemo.mapper.BatisUserMapper" >
    <resultMap id="BaseResultMap" type="com.xps.sc.springbootdemo.entity.User" >
        <id column="user_id" property="userId" jdbcType="BIGINT" />
        <result column="user_name" property="userName" jdbcType="VARCHAR" />
        <result column="pass_word" property="passWord" jdbcType="VARCHAR" />
        <result column="email" property="email" jdbcType="VARCHAR"/>
        <result column="nick_name" property="nickName" jdbcType="VARCHAR" />
        <result column="reg_time" property="regTime" jdbcType="VARCHAR" />
        <result column="create_time" property="createTime" jdbcType="TIMESTAMP" />
    </resultMap>

    <sql id="Base_Column_List" >
        user_id, user_name, pass_word, nick_name, email,reg_time,create_time,nick_name
    </sql>

    <select id="getUserList" resultMap="BaseResultMap"  parameterType="java.lang.String">
        SELECT
        <include refid="Base_Column_List" />
        FROM t_test_user
        where nick_name= #{nickName,jdbcType=VARCHAR}

    </select>

    <insert id="insertUser" parameterType="com.xps.sc.springbootdemo.entity.User" >
        insert into T_TEST_USER(user_id,user_name,nick_name,pass_word,email,reg_time,create_time)
        values(#{userId,jdbcType=BIGINT},#{userName,jdbcType=VARCHAR},
        #{nickName,jdbcType=VARCHAR},#{passWord,jdbcType=VARCHAR},#{email,jdbcType=VARCHAR},
        #{regTime,jdbcType=VARCHAR},#{createTime,jdbcType=TIMESTAMP})
    </insert>

    <update id="updateUser" parameterType="com.xps.sc.springbootdemo.entity.User" >
        UPDATE T_TEST_USER
       <set>
           <if test="userName != null" >
               user_name = #{userName,jdbcType=VARCHAR},
           </if>
           <if test="nickName != null" >
               nick_name = #{nickName,jdbcType=VARCHAR},
           </if>
           <if test="passWord != null" >
               pass_word = #{passWord,jdbcType=VARCHAR},
           </if>
           <if test="email != null" >
               email = #{email,jdbcType=VARCHAR},
           </if>
           <if test="regTime != null" >
               reg_time = #{regTime,jdbcType=VARCHAR},
           </if>
           <if test="createTime != null" >
               create_time = #{createTime,jdbcType=TIMESTAMP},
           </if>
       </set>
       where user_id = #{userId,jdbcType=BIGINT}
    </update>

    <delete id="delete" parameterType="java.lang.Long" >
        DELETE FROM T_TEST_USER WHERE user_id = #{userId,jdbcType=BIGINT}
    </delete>
</mapper>


總結


        mybatis一般用於比較大型的專案,簡單的sql無法滿足業務需要。雖然說jpa也可以寫出複雜業務的sql,但用相對於mybatis沒有後者直接寫sql的方式簡單,易讀懂,易修改和維護。關於多資料來源的配置主要的思路是針對不同的package使用不同的資料來源。當然,還可以使用spring或spring aop等方式來配置多資料。


感謝以下博主的分享,學習中:http://www.ityouknow.com/springboot/2016/11/25/spring-boot-multi-mybatis.html