mybatis-spring-starter 配置

本贴最后更新于 370 天前,其中的信息可能已经时移世异

数据源配置

首先需要安装数据库驱动

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>${mysql.version}</version>
</dependency>

然后再 application.yml 文件中配置数据源. 如果没有安装数据库驱动,那么 Intellij 在 driver-class-name 这一行会有报错提示.

# data source
spring:
  datasource:
    url: jdbc:mysql://localhost/LearnBatis
    username: root
    password: root
    driver-class-name: com.mysql.cj.jdbc.Driver

MyBatis 依赖

mybatis-spring-boot-starter 官方文档: mybatis-spring-boot-autoconfigure – 简介

能够帮我们快速的基于 SpringBoot 构建 MyBaits 应用. 让我们可以编写更少的 XML 配置.

<dependency>
  <groupId>org.mybatis.spring.boot</groupId>
  <artifactId>mybatis-spring-boot-starter</artifactId>
  <version>${mybatis.version}</version>
 </dependency>

MyBatisConfig 类

编写下面的代码时,如果数据源配置相关操作没有完成 Intellij 会提示找不到 DataSource 实例

@Configuration
//@MapperScan("xxxx.xxxx.dao")
class MyBatisConfig {

	@Bean
	fun sqlSessionFactory(dataSource: DataSource):SqlSessionFactory{
 		val factoryBean = SqlSessionFactoryBean()
        factoryBean.setDataSource(dataSource)
    	return factoryBean.`object`
            ?: throw IllegalStateException("SqlSessionFactory creation failed")
	}
}

使用 Kotlin 编写时,注意一些 getXX() 方法在 Kotlin 中是不能够直接使用的.

这里还要注意,如果你把一些 Java 代码直接复制到 Kotlin 项目中, 让 Intellij 帮助你自动将其转换为 Kotlin 代码. 可能会出现一些 @Throws 标签. 这些标签是为了在 Kotlin 和 Java 互相调用时发挥作用,纯 Kotlin 项目不需要 @Throws

根据官方文档 mybatis-spring ,可以知道,这里的配置代码主要作用是提供一个 SqlSessionFactory 实例. 后续在各个业务请求中, MyBaits 会通过 SqlSessionFactory 来创建 SqlSession 对数据库进行操作. 各自的作用可以参考 MyBatis 作用域和生命周期1

在 Config 类中配置 Mybatis 时, SqlSessionFactoryBean 对象唯一必须需要设置的属性是: ==DataSource 数据源==

其他常用的配置属性有:

configLocation: 它用来指定 MyBatis 的 XML 配置文件路径

mapperLocations 指定 MyBatis 的映射器 XML 配置文件的位置。属性的值是一个 Ant 风格的字符串,可以指定加载一个目录中的所有文件,或者从一个目录开始递归搜索所有目录

mapperLocations

当然也可以通过代码来对 映射器 XML 配置文件进行配置. 注意这里是 **getResources ** 而不是 getResource (这地方卡了我两三个小时)

val mapperLocations = "classpath*:mapper/**/*Mapper.xml"  
factoryBean.setMapperLocations(
	*PathMatchingResourcePatternResolver().getResources(mapperLocations)
)

这里的 * 是 Kotlin 中的展开操作符(spread operator) ,用于将数组展开作为可变数量参数3.

因为 setMapperLocations 中可以接收多个资源

public void setMapperLocations(Resource... mapperLocations) 

编写 DAO 和 XML 映射器

@Mapper
interface DiaryTagDAO {
    @Select("SELECT TagID,TagName FROM Tags")
    fun getTagList():List<DiaryTag>

    @Select("SELECT TagID,TagName FROM Tags WHERE TagID=#{id}")
    fun getTagById(id:Long):DiaryTag

    fun selectTagByName(name:String):DiaryTag
}

这里注意, 如果我们在 DAO 中标注了 @Mapper 标签,那么我就可以不需要在 Config 类添加 @MapperScan 标签

<?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.crowds.learnMybatis.dao.DiaryTagDAO">
    <resultMap id="diaryTag" type="com.crowds.learnMybatis.domain.DiaryTag">
        <id property="tagID" column="TagID"/>
        <result property="tagName" column="TagName"/>
    </resultMap>
    <select id="selectTagByName" parameterType="String" resultMap="diaryTag">
        SELECT Tags.TagID , Tags.TagName FROM Tags
        WHERE Tags.TagName = #{name}
    </select>
</mapper>

这里需要注意,传入参数使用 #{para} 时,一定不要写成 '#{para}' 把他当成字符串.

测试类

编写一个简单的测试类,测试一下是否运行正常

@SpringBootTest
class DiaryTagServiceImplTest {

    @Autowired
    private lateinit var diaryTagService: DiaryTagServiceImpl

    @Test
    fun getTagList() {
        val result = diaryTagService.getTagList()
        assert(result.size == 1)
    }

    @Test
    fun getTagById() {
        val result = diaryTagService.getTagById(1L)
        assert( result.tagID == 1L)
    }

    @Test
    fun getTagByName() {
        var result = diaryTagService.getTagByName("MyBaits")
        println("TagName: ${result.tagName}")
        assert(result.tagName == "MyBaits")
    }
}

  1. MyBatis 作用域和生命周期

    依赖注入框架可以创建线程安全的、基于事务的 SqlSession 和映射器,并将它们直接注入到你的 bean 中,因此可以直接忽略它们的生命周期。 如果对如何通过依赖注入框架使用 MyBatis 感兴趣,可以研究一下 MyBatis-Spring1 或 MyBatis-Guice 两个子项目

    SqlSessionFactoryBuilder

    这个类可以被实例化、使用和丢弃,创建了 SqlSessionFactory 后就不再需要 SqlSessionFactoryBuilder

    因此 SqlSessionFactoryBuilder 实例的最佳作用域是 方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它

    以保证所有的 XML 解析资源可以被释放给更重要的事情

    SqlSessionFactory

    MyBatis 中的 SqlSessionFactory 的生命周期为: ==被创建就应该在应用的运行期间一直存在==

    并且没有任何理由丢弃它或重新创建另一个实例

    MyBatis 中的 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次

    MyBatis 中的 SqlSessionFactory 的最佳作用域是**==应用作用域==**。 有很多方法可以做到,最简单的就是使用**==单例模式==**或者**==静态单例模式==**

    SqlSession

    每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。

    • MyBatis 中的 SqlSession 是否是线程安全的,能否被共享

      • 不是线程安全的, 所以也不能被共享

    MyBatis 中的 SqlSession 的最佳作用域是 ==请求==或==方法==作用域.

    因为一个请求或方法刚好就只执行一次 SqlSession

    MyBatis 中的 SqlSession 的正确做法是: 每次收到一个请求就==打开一个 SqlSession==,返回响应后,==就关闭 SqlSession==

    绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。

    如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。

    try (SqlSession session = sqlSessionFactory.openSession()) {
      // 你的应用逻辑代码
    }
    

    在所有代码中都遵循这种使用模式,可以保证所有数据库资源都能被正确地关闭

    映射器实例

    映射器是一些绑定映射语句的接口。

    映射器接口的实例是从 SqlSession 中获得的。虽然从技术层面上来讲,任何映射器实例的最大作用域与请求它们的 SqlSession 相同。但方法作用域才是映射器实例的最合适的作用域。

    也就是说,映射器实例应该在调用它们的方法中被获取,使用完毕之后即可丢弃。 映射器实例并不需要被显式地关闭。

    尽管在整个请求作用域保留映射器实例不会有什么问题,但是你很快会发现,在这个作用域上管理太多像 SqlSession 的资源会让你忙不过来。 因此,最好将映射器放在方法作用域内。就像下面的例子一样:

    try (SqlSession session = sqlSessionFactory.openSession()) {
        BlogMapper mapper = session.getMapper(BlogMapper.class);
        // 你的应用逻辑代码
    }
    

    MyBatis 中的映射器实例应该在==调用它们的方法==中被获取,在使用完毕之后**丢弃**

    MyBatis 中的映射器实例应该在调用它们的方法中被获取,在使用完毕之后**==丢弃==**

    MyBatis 中的映射器应该被放在**==方法作用域内==**

  2. MyBatis-Spring

  3. 可变数量参数

    可变数量参数1就是就是函数可以接受任意数量的参数, 在 Kotlin 和 Java 中使用不同的方式定义.

    // Java
    void printNumbers(int... numbers)
    // Kotlin
    fun printNumbers(vararg numbers: Int)
    
  • MyBatis

    MyBatis 本是 Apache 软件基金会 的一个开源项目 iBatis,2010 年这个项目由 Apache 软件基金会迁移到了 google code,并且改名为 MyBatis ,2013 年 11 月再次迁移到了 GitHub。

    170 引用 • 414 回帖 • 384 关注
  • Spring

    Spring 是一个开源框架,是于 2003 年兴起的一个轻量级的 Java 开发框架,由 Rod Johnson 在其著作《Expert One-On-One J2EE Development and Design》中阐述的部分理念和原型衍生而来。它是为了解决企业应用开发的复杂性而创建的。框架的主要优势之一就是其分层架构,分层架构允许使用者选择使用哪一个组件,同时为 JavaEE 应用程序开发提供集成的框架。

    944 引用 • 1459 回帖 • 16 关注
  • Kotlin

    Kotlin 是一种在 Java 虚拟机上运行的静态类型编程语言,由 JetBrains 设计开发并开源。Kotlin 可以编译成 Java 字节码,也可以编译成 JavaScript,方便在没有 JVM 的设备上运行。在 Google I/O 2017 中,Google 宣布 Kotlin 成为 Android 官方开发语言。

    19 引用 • 33 回帖 • 65 关注

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...