Mybatis 的使用(集成Spring、SpringBoot)

3,641 阅读7分钟

昨天在学习项目工程时发现项目对mybatis用的还是挺多的,之前也是有用过,觉得还是自己做下笔记记录一下。Mybatis是一个数据访问层框架,和大多数同类框架一样,Mybatis节省了开发人员使用jdbc底层操作数据库很大一部分代码,使用mybatis,开发人员只需要将sql写在配置文件中,并声明该sql返回值和java类型的映射即可。当然mybatis还支持针对接口编程,如果你把mybatis和spring两者做一个集成,你将发现你无须为接口声明实现类就可以操作数据库,而你需要做的,只是在xml文件中做相关声明告诉mybatis即可,mybatis底层会帮我们处理和数据库的链接等操作。

下面我不会讲解mybatis的相关理论知识,因为官网其实说的很明白了,而我需要做的,只是从3个应用方式层面展开讲解,这3个层面分别是编程方式使用mybatis,基于注解使用mybatis,spring集成mybatis,所有工程均采用maven进行构建。

为了方便演示,在此我贴出相关数据库脚本和一些公共的组件如(mapper接口):

create database test;
CREATE TABLE `test`.`student` (
  `id` INT NOT NULL AUTO_INCREMENT,
  `NAME` VARCHAR(45) NULL,
  `AGE` INT NULL,
  `ADDRESS` VARCHAR(45) NULL,
  PRIMARY KEY (`id`),
  UNIQUE INDEX `id_UNIQUE` (`id` ASC));

StudentMapper.java接口

package com.wokao666.mappers;

import java.util.List;
import java.util.Map;

import com.wokao666.entity.Student;

/**
 * 
 * The class StudentMapper.
 *
 * Description:学生mapper
 *
 * @author: huangjiawei
 * @since: 2018年6月7日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
public interface StudentMapper {

    public Student getById(Map<String, Object> param);

    public List<Student> listStudents();
}

实体类Student.java

package com.wokao666.entity;

/**
 * 
 * The class Student.
 *
 * Description:学生实体类
 *
 * @author: huangjiawei
 * @since: 2018年6月7日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
public class Student {

    private int id;
    
    public int getId() {
        return id;
    }
    
    public void setId(int id) {
        this.id = id;
    }
    
    private String name;
    private String address;
    private int age;
    
    public String getName() {
        return name;
    }
    
    public void setName(String name) {
        this.name = name;
    }
    
    public String getAddress() {
        return address;
    }
    
    public void setAddress(String address) {
        this.address = address;
    }
    
    public int getAge() {
        return age;
    }
    
    @Override
    public String toString() {
        return "Student [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]";
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public Student(int id, String name, String address, int age) {
        super();
        this.id = id;
        this.name = name;
        this.address = address;
        this.age = age;
    }
    
    public Student() {
    }
}

StudentMapper.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,为了更好的进行区别,我们通常会将该值设置为包名的全限定路径 -->
<mapper namespace="com.wokao666.mappers.StudentMapper">
    
    <!-- 表示你的sql查询结果和java类型的一个映射,java类型通常是java bean -->
    <resultMap type="com.wokao666.entity.Student" id="studentMap">
        <result property="id" column="ID"/>
        <result property="name" column="NAME" />
        <result property="age" column="AGE" />
        <result property="address" column="ADDRESS" />
    </resultMap>
    
    <!-- select语句 ,根据条件进行查询,指定参数类型为map类型-->
    <select id="getById" resultMap="studentMap" parameterType="java.util.Map">
        select * from Student where id = #{id};
    </select>	
    
    <select id="listStudents" resultMap="studentMap">
        select * from Student;
    </select>
</mapper>

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>
    <!-- 属性配置,类似于全局变量   -->
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver" />
        <property name="url"
            value="jdbc:mysql://localhost:3306/test?serverTimezone=UTC" />
        <property name="username" value="root" />
        <property name="password" value="root" />
    </properties>
    <!-- 在此,你可以定义多个环境,表示开发、测试、预生产、生产 -->
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC" />
            <dataSource type="POOLED">
                <property name="driver" value="${driver}" />
                <property name="url" value="${url}" />
                <property name="username" value="${username}" />
                <property name="password" value="${password}" />
            </dataSource>
        </environment>
    </environments>
    <!-- mapper文件路径配置,默认会加载类路径下的资源,更多配置可以参见官方文档 -->
    <mappers>
        <mapper resource="StudentMapper.xml" />
    </mappers>
</configuration>

一、使用mybatis编程方式操作数据库

在mybatis中,程序的构建式通过一个叫SqlSessionFactory开始的,SqlSessionFactory可以通过SqlSessionFactoryBuilder进行构建,SqlSessionFactoryBuilder支持从一个配置文件流中进行构建。

pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    <modelVersion>4.0.0</modelVersion>
    
    <groupId>mybatisTest</groupId>
    <artifactId>mybatisTest</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>jar</packaging>
    <name>mybatisTest</name>
    
    <properties>
        <java.version>1.8</java.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.4.6</version>
        </dependency>
        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.11</version>
        </dependency>
    </dependencies>
</project>

Test.java

package com.wokao666.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import com.wokao666.entity.Student;
import com.wokao666.mappers.StudentMapper;

/**
 * 
 * The class Test.
 *
 * Description:编程方式使用mybatis
 *
 * @author: huangjiawei
 * @since: 2018年6月8日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
public class Test {

public static void main(String[] args) throws IOException {
    //	读取我们的配置文件
    InputStream input = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(input);
    
    // 打开一个会话session
    SqlSession session = factory.openSession();
    
    // 构建查询参数
    Map<String, Object> paramMap = new HashMap<String, Object>();
    paramMap.put("id", 2);
    
    //	测试使用id获取一条记录
    Student stu = session.selectOne("getById", paramMap);
    System.err.println(stu.toString());
    
    // 测试使用命名空间查询一条记录(接口)
    StudentMapper mapper = session.getMapper(StudentMapper.class);
    System.err.println(mapper.getById(paramMap));
    
    // 测试获取一个列表
    List<Student> stuList = session.selectList("listStudents");
    System.err.println(Arrays.toString(stuList.toArray()));
    }
}

程序输出

Loading class `com.mysql.jdbc.Driver'. This is deprecated. The new driver class is `com.mysql.cj.jdbc.Driver'. The driver is automatically registered via the SPI and manual loading of the driver class is generally unnecessary.
Fri Jun 08 14:50:11 CST 2018 WARN: Establishing SSL connection without server's identity verification is not recommended. According to MySQL 5.5.45+, 5.6.26+ and 5.7.6+ requirements SSL connection must be established by default if explicit option isn't set. For compliance with existing applications not using SSL the verifyServerCertificate property is set to 'false'. You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
Student [id=2, name=Mike, address=浙江省, age=24]
Student [id=2, name=Mike, address=浙江省, age=24]
[Student [id=1, name=HUANGJIAWEI, address=广东省, age=23], Student [id=2, name=Mike, address=浙江省, age=24]]

二、基于注解的mybatis

这篇博客只是演示了对于简单sql的使用,像那些复杂的sql(如关联查询join)等,官网有做相关讲解,后续小编也可能会进行总结。因为我们都知道,mybatis推荐我们将sql语句写到各种mapper.xml中,当我们的业务非常庞大时,系统中无疑就会有很多我们新建的各种xml文件,当然我们更希望xml文件越少越好,因此,mybatis支持开发者使用基于接口和注解的方式使用mybatis,对于一些简单的sql而言,我们没有必要将它写在xml文件中,相反我们更加推荐将简单的sql写在注解中,而复杂的sql交给xml文件管理。

下面我将演示两种基于注解使用mybatis的方式,一种是改写第一种基于编程的方式,第二种将使用spring-boot来集成mybatis,当然,第二种方式会更加地实用,更加贴近我们的真实开发,或者说跟多开发者本来就是这么用的,哈哈!

1、基于编程方式的注解使用

StudentMapper.java接口中增加一个新方法,如下:

package com.wokao666.mappers;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.Select;

import com.wokao666.entity.Student;

/**
 * 
 * The class StudentMapper.
 *
 * Description:学生mapper
 *
 * @author: huangjiawei
 * @since: 2018年6月7日
 * @version: $Revision$ $Date$ $LastChangedBy$
 *
 */
public interface StudentMapper {
    
    // 此处将sql写在接口的注解上,简单粗暴
    @Select("select * from Student where id=1")
    public Student get();
    
    public Student getById(Map<String, Object> param);
    
    public List<Student> listStudents();

}

然后在第一小结的Test.java最后加上这一行代码即可。

System.err.println(mapper.get());
2、基于spring-boot使用mybatis

代码下载地址: github.com/SmallerCode…

工程结构图如下:

该工程分为三层,即controllerservicedao层,即传统的mvc模型。

导入工程之后启动MybatisDemoApplication.java类,然后浏览器输入http://localhost:7000/get.json?id=1即可!

三、集成Spring

任何时候,当我们在应用代码层面对数据库进行操作时,我们首先要做的,那么就是配置一个合适的数据源,数据源可以很简单的配置jdbc的url、driver、username、password等参数,当然更高级的做法是我们可以采用像c3p0druid这样的数据库连接池来管理我们的数据源,在此处,小编采用阿里巴巴提供的连接池druid

Spring集成mybatis最关键的就是加入一个依赖包,即:

<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.1</version>
</dependency>

官网项目地址:www.mybatis.org/spring/zh/i…

上面第一、第三小节实例代码下载地址:github.com/SmallerCode…

如果本实例代码对你有所帮助,给小弟一个start哟~~~

最后总结下,mybatis就是一个数据访问框架,大体上其特性就是尽可能减少写底层jdbc链接的代码,同时,对于数据库实体和java对象之间的映射,mybatis也帮我们完成了。当然,如果你想深入学习mybatis,我建议你去mybatis官网系统学习,mybatis功能很强大的,如果你的sql中需要进行条件判断,mybatis运行你在mapper文件的sql中使用诸如<if>标签进行判断,加油,骚年、朋友们,欢迎多交流!