MyBatis基本入门

146 阅读4分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第24天,点击查看活动详情

MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

本篇文章我们就来一起学习这一优秀的持久层框架——MyBatis。

MyBatis初体验

持久层框架当然是操作数据库了,为此,创建数据库和数据表:

CREATE DATABASE mybatis;

CREATE TABLE tbl_employee(
 id INT(11) PRIMARY KEY AUTO_INCREMENT,
 last_name VARCHAR(255),
 gender CHAR(1),
 email VARCHAR(255)
);

INSERT INTO tbl_employee VALUES('tom',0,'tom@qq.com');

接下来我们创建一个maven项目,引入MyBatis的依赖:

<!-- mybatis -->
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>3.4.1</version>
</dependency>
<!-- 数据库驱动 -->
<dependency>
  <groupId>mysql</groupId>
  <artifactId>mysql-connector-java</artifactId>
  <version>5.1.37</version>
</dependency>

接着创建数据表对应的Bean类:

@Data
@ToString
public class Employee {

    private Integer id;
    private String lastName;
    private char gender;
    private String email;
}

需要知道的是,每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。

所以我们需要在类路径下编写一个XML文件(mybatis-config.xml)来完成SqlSessionFactory的构建:

<?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>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!-- 配置数据源 -->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver"/>
                <property name="url" value="jdbc:mysql:///mybatis"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 注册Mapper映射文件 -->
    <mappers>
        <mapper resource="EmployeeMapper.xml"/>
    </mappers>
</configuration>

该文件即为MyBatis的全局配置文件,用于配置MyBatis的一些功能,这里需要注意两点:首先是数据源的配置,然后是Mapper映射文件的注册,MyBatis的增删改查完全依赖于Mapper映射文件,所以我们还需要在类路径下编写Mapper映射文件(EmployeeMapper.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.wwj.mybatis.mapper.EmployeeMapper">
    <select id="selectEmp" resultType="com.wwj.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>
</mapper>

这里也需要注意几点, namespace 意为名称空间,主要起一个标识作用,可随意命名;其次是 <select> 标签,它表示的是一个查询操作,相应地,它还有 <insert> 、<delete> 、 <update> 标签分别用于插入、删除和更新;在 <select> 标签中指定了id和resultType属性,其中id仍然为一个标识符,resultType为本次查询得到的结果类型,MyBatis会自动将数据表中查询到的数据封装成该类型,最后在标签内编写sql语句即可, #{id} 能够取出传递过来的id值。

\

一切准备就绪后,我们就可以编写业务代码了:

@Test
public void test() throws IOException {
    String resource = "mybatis-config.xml";
    InputStream stream = Resources.getResourceAsStream(resource);
    // 构建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
    // 获取sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 执行sql
    Employee employee = sqlSession.selectOne("selectEmp", 1);
    System.out.println(employee);
}

通过全局配置文件构建sqlSessionFactory对象,并通过sqlSessionFactory获取sqlSession,调用selectOne方法即可查询到一个结果,第一个参数值为Mapper映射文件中操作标签的id值,为了避免重复引发的问题,一般以名称空间 + 操作标签id值为参数值: com.wwj.mybatis.mapper.EmployeeMapper.selectEmp ;第二个参数值会被MyBatis传递给sql,也就是说,第二个参数值1会被 #{id} 成功获取。

\

执行结果:

Employee(id=1, lastName=null, gender=0, email=tom@qq.com)

很显然,我们查询到了结果,然而会发现lastName属性值为空,这是为什么呢?

原来,JavaBean中的lastName与数据表中last_name字段不匹配,为了解决这一问题,我们可以重新编写一下sql语句:

select id,last_name lastName,gender,email from tbl_employee where id = #{id}

在查询的时候将字段重新设置属性名即可,不过MyBatis也考虑到了这一点,所以特地设置了一个全局属性,我们只需要开启它即可自动处理这一问题:

<settings>
  <!-- 开启驼峰命名 -->
  <setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

在全局配置文件中设置开启驼峰命名即可,但需要注意,它只能处理遵守驼峰命名规范的属性,比如lastName和last_name,empSalary和emp_salary。

接口式编程

在刚才我们体验了一下MyBatis框架的简单查询,会发现这种方式存在着一些问题,比如操作标识过长、第二个参数因为是Object类型,也会出现很多错误,为此,MyBatis提供了更加优雅的解决方案——接口式编程。

\

我们改造一下刚才的程序,首先编写一个接口:

public interface EmployeeMapper {

    Employee getEmpById(Integer id);
}

在该接口中我们可以声明各种操作方法而无需具体实现,比如通过id查询Employee,此时我们只需要稍加修改Mapper映射文件即可:

<?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.wwj.mybatis.mapper.EmployeeMapper">
    <select id="getEmpById" resultType="com.wwj.mybatis.bean.Employee">
        select * from tbl_employee where id = #{id}
    </select>
</mapper>

首先将名称空间写为接口的全类名,此时该映射文件会与接口进行唯一绑定,此时 <select> 标签的id属性值就需要写为接口方法名,resultType为接口方法的返回值。

\

到这里就改造完成了,当然,我们的业务代码也发生了相应的变化:

@Test
public void test() throws IOException {
    String resource = "mybatis-config.xml";
    InputStream stream = Resources.getResourceAsStream(resource);
    // 构建sqlSessionFactory
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
    // 获取sqlSession
    SqlSession sqlSession = sqlSessionFactory.openSession();
    // 获取Mapper接口的实现
    EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
    // 调用方法
    Employee employee = employeeMapper.getEmpById(1);
    System.out.println(employee);
}

仍然需要构建sqlSessionFactory对象,并通过其获得sqlSession,此时通过sqlSession调用getMapper方法就能够获取到MyBatis为我们创建的接口实现类,此时通过该实现类即可调用方法完成查询。

\

执行结果:

Employee(id=1, lastName=tom, gender=0, email=tom@qq.com)