MyBatis简介(了解)

73 阅读13分钟

MyBatis简介(了解)

什么是MyBatis

MyBatis 本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。

MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注SQL本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。

Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。

总之,Mybatis对JDBC访问数据库的过程进行了封装,简化了JDBC代码,解决JDBC将结果集封装为Java对象的麻烦。

下图是MyBatis架构图:

(1)mybatis-config.xml是Mybatis的核心配置文件,通过其中的配置可以生成SqlSessionFactory,也就是SqlSession工厂

(2)基于SqlSessionFactory可以生成SqlSession对象

(3)SqlSession是一个既可以发送SQL去执行,并返回结果,类似于JDBC中的Connection对象,也是Mybatis中至关重要的一个对象。

(4)Executor是SqlSession底层的对象,用于执行SQL语句

(5)MapperStatement对象也是SqlSession底层的对象,用于接收输入映射(SQL语句中的参数),以及做输出映射(即将SQL查询的结果映射成相应的结果)

为什么要使用MyBatis

思考:在开始之前,思考下如何通过JDBC查询Emp表中的所有记录,并封装到一个List集合中返回。(演示:准备数据、导包、导入JDBC程序)

1、使用传统方式JDBC访问数据库:

(1)使用JDBC访问数据库有大量重复代码(比如注册驱动、获取连接、获取传输器、释放资源等);

(2)JDBC自身没有连接池,会频繁的创建连接和关闭连接,效率低;

(3)SQL是写死在程序中,一旦修改SQL,需要对类重新编译;

(4)对查询SQL执行后返回的ResultSet对象,需要手动处理,有时会特别麻烦;

...

2、使用mybatis框架访问数据库:

(1)Mybatis对JDBC对了封装,可以简化JDBC代码;

(2)Mybatis自身支持连接池(也可以配置其他的连接池),因此可以提高程序的效率;

(3)Mybatis是将SQL配置在mapper文件中,修改SQL只是修改配置文件,类不需要重新编译。

(4)对查询SQL执行后返回的ResultSet对象,Mybatis会帮我们处理,转换成Java对象。

...

总之,JDBC中所有的问题(代码繁琐、有太多重复代码、需要操作太多对象、释放资源、对结果的处理太麻烦等),在Mybatis框架中几乎都得到了解决!!

MyBatis快速入门

准备数据,创建库和表

创建test库、emp表,并插入若干条记录






1
-- 1、创建数据库 test 数据库
2
create database if not exists test charset utf8;
3
use test ; -- 选择yonghedb数据库
4
-- 2、删除emp表(如果存在)
5
drop table if exists emp;
6
-- 3、在 test 库中创建 emp 表
7
create table emp(
8
    id int primary key auto_increment,
9
    name varchar(50),
10
    job varchar(50),
11
    salary double
12
);
13
-- 4、往 emp 表中, 插入若干条记录
14
insert into emp values(null, '张三', '程序员', 3300);
15
insert into emp values(null, '李四', '程序员', 2800);
16
insert into emp values(null, '王五', '程序员鼓励师', 2700);
17
insert into emp values(null, '王二', '部门总监', 4200);
18
insert into emp values(null, '麻子', '程序员', 3000);
19
insert into emp values(null, '最帅三太子', '程序员', 3500);
20
insert into emp values(null, '苍老师', '程序员', 3700);
21
insert into emp values(null, '波多野结衣', 'CEO', 5000);

创建工程,导入所需jar包、创建测试类

1、创建Maven的java工程

2、导入junit、mysql、mybaits、log4j等开发包

在pom.xml文件中引入相关依赖包即可







1
<dependencies>
2
    <!-- junit单元测试 -->
3
    <dependency>
4
        <groupId>junit</groupId>
5
        <artifactId>junit</artifactId>
6
        <version>4.9</version>
7
    </dependency>
8
    <!-- mysql驱动 -->
9
    <dependency>
10
        <groupId>mysql</groupId>
11
        <artifactId>mysql-connector-java</artifactId>
12
        <version>5.1.32</version>
13
    </dependency>
14
    <!-- mybatis -->
15
    <dependency>
16
        <groupId>org.mybatis</groupId>
17
        <artifactId>mybatis</artifactId>
18
        <version>3.2.8</version>
19
    </dependency>
20
    <!-- 整合log4j -->
21
    <dependency>
22
        <groupId>org.slf4j</groupId>
23
        <artifactId>slf4j-log4j12</artifactId>
24
        <version>1.6.4</version>
25
    </dependency>
26
</dependencies>

3、创建com.tedu.mybatis.TestMybatis01测试类,并提供findAll方法(查询emp表中所有的员工信息),开发步骤如下:







1
/** 练习1(快速入门): 查询emp表中的所有员工, 返回一个List<Emp>集合
2
* @throws IOException */
3
@Test
4
public void findAll() throws IOException {
5
    //1.读取mybatis的核心配置文件(mybatis-config.xml)
6
    //2.通过配置信息获取一个SqlSessionFactory工厂对象
7
    //3.通过工厂获取一个SqlSession对象
8
    //4.通过namespace+id找到要执行的sql语句并执行sql语句
9
    //5.输出结果
10
}

添加mybatis-config.xml文件

1、在src/main/resources目录下,创建mybatis-config.xml文件(MyBatis的核心配置文件)

2、mybatis-config.xml文件配置如下:

mybatis-config文件头信息如下:



1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE configuration
3
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
5
    
6
<!-- MyBatis的全局配置文件 -->
7
<configuration >
8
    
9
</configuration>

mybatis-config文件详细配置如下:



1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE configuration
3
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
5
    
6
<!-- MyBatis的全局配置文件 -->
7
<configuration >
8
    <!-- 1.配置环境,可配置多个环境(比如:develop开发、test测试) -->
9
    <environments default="develop">
10
        <environment id="develop">
11
            
12
            <!-- 1.1.配置事务管理方式:JDBC/MANAGED
13
            JDBC:将事务交给JDBC管理(推荐)
14
            MANAGED:自己管理事务
15
              -->
16
            <transactionManager type="JDBC"></transactionManager>
17
            
18
            <!-- 1.2.配置数据源,即连接池 JNDI/POOLED/UNPOOLED
19
                JNDI:已过时
20
                POOLED:使用连接池(推荐)
21
                UNPOOLED:不使用连接池
22
             -->
23
            <dataSource type="POOLED">
24
                <property name="driver" value="com.mysql.jdbc.Driver"/>
25
                <property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
26
                <property name="username" value="root"/>
27
                <property name="password" value="root"/>
28
            </dataSource>
29
        </environment>
30
    </environments>
31
    
32
    <!-- 2.导入Mapper配置文件,如果mapper文件有多个,可以通过多个mapper标签导入 -->
33
    <mappers>
34
        <mapper resource="EmpMapper.xml"/>
35
    </mappers>
36
</configuration>

添加EmpMapper.xml文件

1、在src/main/resources目录下,创建EmpMapper.xml文件 (实体类的映射文件)

2、EmpMapper.xml文件配置如下:

EmpMapper文件头信息如下:


1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE mapper
3
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
​
6
<!-- 
7
    不同Mapper文件的namespace值应该保证唯一
8
    在程序中通过[ namespace + id ]定位到要执行哪一条SQL语句
9
 -->
10
<mapper namespace="">
11
    
12
    
13
</mapper>

EmpMapper文件详细配置如下:


1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE mapper
3
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
​
6
<!-- 
7
    不同Mapper文件的namespace值应该保证唯一
8
    在程序中通过[ namespace + id ]定位到要执行哪一条SQL语句
9
 -->
10
<mapper namespace="EmpMapper">
11
    <!-- 通过select、insert、update、delete标签声明要执行的SQL -->
12
    <!-- 练习1: 查询emp表中的所有员工信息
13
        resultType指定查询的结果将会封装到什么类型中
14
        即使最终返回的结果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
15
    -->
16
    <select id="findAll" resultType="com.tedu.pojo.Emp">
17
        select * from emp
18
    </select>
19
​
20
</mapper>

添加并编写Emp实体类

注意:在当前实例中,Emp类中的属性和数据库表的字段名称必须一致,否则将会无法将结果集封装到Java对象中。

在src/main/java目录下创建 com.tedu.pojo.Emp类,并编辑Emp类:提供私有属性以及对应的getter方法、setter方法,并重写toString方法


1
package com.tedu.pojo;
2
/**
3
 * 实体类,用于封装Emp表中的一条用户信息
4
 */
5
public class Emp {
6
    //1.声明实体类中的属性
7
    private Integer id;
8
    private String name;
9
    private String job;
10
    private Double salary;
11
    
12
    //2.提供对应的getter和setter方法
13
    public Integer getId() {
14
        return id;
15
    }
16
    public void setId(Integer id) {
17
        this.id = id;
18
    }
19
    public String getName() {
20
        return name;
21
    }
22
    public void setName(String name) {
23
        this.name = name;
24
    }
25
    public String getJob() {
26
        return job;
27
    }
28
    public void setJob(String job) {
29
        this.job = job;
30
    }
31
    public Double getSalary() {
32
        return salary;
33
    }
34
    public void setSalary(Double salary) {
35
        this.salary = salary;
36
    }
37
    
38
    //3.重写toString方法
39
    @Override
40
    public String toString() {
41
        return "Emp [id=" + id + ", name=" + name + ", job=" + job + ", salary=" + salary + "]";
42
    }
43
}

实现测试类,并测试

1、实现findAll方法,代码如下:

1
/** 练习1(快速入门):  查询emp表中的所有员工, 返回一个List<Emp>集合
2
 * @throws IOException */
3
@Test
4
public void findAll() throws IOException {
5
    //1.读取mybatis的核心配置文件(mybatis-config.xml)
6
    InputStream in = Resources
7
            .getResourceAsStream("mybatis-config.xml");
8
    //2.通过配置信息获取一个SqlSessionFactory工厂对象
9
    SqlSessionFactory fac = 
10
            new SqlSessionFactoryBuilder().build( in );
11
    //3.通过工厂获取一个SqlSession对象
12
    SqlSession session = fac.openSession();
13
    //4.通过namespace+id找到要执行的sql语句并执行sql语句
14
    List<Emp> list = session
15
            .selectList("EmpMapper.findAll");
16
    //5.输出结果
17
    for(Emp e : list) {
18
        System.out.println( e );
19
    }
20
}

2、执行findAll方法,输出结果为:


就会遍历出来

MyBatis入门细节

mybatis-config.xml配置文件







1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE configuration
3
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
5
    
6
<!-- MyBatis的全局配置文件 -->
7
<configuration >
8
    <!-- 1.配置环境,可配置多个环境(比如:develop开发、test测试) -->
9
    <environments default="develop">
10
        <environment id="develop">
11
            
12
            <!-- 1.1.配置事务管理方式:JDBC/MANAGED
13
            JDBC:将事务交给JDBC管理(推荐)
14
            MANAGED:自己管理事务
15
              -->
16
            <transactionManager type="JDBC"></transactionManager>
17
            
18
            <!-- 1.2.配置数据源,即连接池 JNDI/POOLED/UNPOOLED
19
                JNDI:已过时
20
                POOLED:使用连接池(推荐)
21
                UNPOOLED:不使用连接池
22
             -->
23
            <dataSource type="POOLED">
24
                <property name="driver" value="com.mysql.jdbc.Driver"/>
25
                <property name="url" value="jdbc:mysql://localhost:3306/yonghedb?characterEncoding=utf-8"/>
26
                <property name="username" value="root"/>
27
                <property name="password" value="root"/>
28
            </dataSource>
29
        </environment>
30
    </environments>
31
    
32
    <!-- 2.导入Mapper配置文件,如果mapper文件有多个,可以通过多个mapper标签导入 -->
33
    <mappers>
34
        <mapper resource="EmpMapper.xml"/>
35
    </mappers>
36
</configuration>

environments标签:该标签内部可以配置多个environment,即多种环境,每种环境可以做不同配置或连接不同数据库。例如,开发、测试、生产环境可能需要不同的配置,连接的数据库可能也不相同,因此我们可以配置三个environment,分别对应上面三种不同的环境。

但是要记住,environment可以配置多个,但是最终要使用的只能是其中一个!

environment标签:内部可以配置多种配置信息,下面介绍事务管理配置和数据源配置。

transactionManage标签:事务管理配置,mybatis中有两种事务管理方式,也就是

type="[JDBC|MANAGED]。







1
JDBC:这个配置就是直接使用了 JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务范围。推荐使用。
2
MANAGED:这个配置几乎没做什么。它从来不提交或回滚一个连接。需要自己手动添加并管理。不推荐使用。

dataSource标签:数据源,也就是连接池配置。这里type指定数据源类型,有三种内建的类型:JNDI、POOLED、UNPOOLED







1
JNDI:已过时,不推荐使用!
2
POOLED:使用连接池,mybatis会创建连接池,并从连接池中获取连接访问数据库,在操作完成后,将会把连接返回连池。
3
UNPOOLED:不使用连接池,该方式适用于只有小规模数量并发用户的简单应用程序上。

mappers标签:用于导入mapper文件的位置,其中可以配置多个mapper,即可以导入多个mapper文件。

EmpMapper.xml配置文件







1
<?xml version="1.0" encoding="UTF-8"?>
2
<!DOCTYPE mapper
3
    PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5
​
6
<!-- 
7
    不同Mapper文件的namespace值应该保证唯一
8
    在程序中通过[ namespace + id ]定位到要执行哪一条SQL语句
9
 -->
10
<mapper namespace="EmpMapper">
11
    <!-- 通过select、insert、update、delete标签声明要执行的SQL -->
12
    <!-- 练习1: 查询emp表中的所有员工信息
13
        resultType指定查询的结果将会封装到什么类型中
14
        即使最终返回的结果是集合(List<Emp>),resultType也只需要指定集合中的泛型即可!
15
    -->
16
    <select id="findAll" resultType="com.tedu.pojo.Emp">
17
        select * from emp
18
    </select>
19
​
20
</mapper>

(1)第1行是xml的文档声明,用于声明xml的版本和编码

(2)第2、3、4行,引入了xml约束文档,当前xml文档将会按照mybatis-3-mapper.dtd文件所要求的规则进行书写。

(3)Mapper标签:根标签,其中namespace(名称空间,也叫命名空间),要求不能重复。在程序中通过【namespace + id 】定位到要执行哪一条SQL语句

(4)select标签:用于指定将来要执行的各种SQL语句。标签上可以声明属性,下面介绍常用的属性:id、resultType、resultMap

  • id属性:要求值不能重复。将来在执行SQL时,可以通过【namespace + id】找到指定SQL并执行。
  • resultType属性:从这条SQL语句中返回所期望类型的类的完全限定名称(包名+类名)。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。
    简而言之,resultType控制查询SQL执行后返回值的类型或集合中的泛型,例如查询emp表中的单条记录,返回值是一个Emp对象,因此,resultType="com.tedu.pojo.Emp";
    如果查询emp表中的多条记录,返回值是一个List,此时resultType的值应该集合中的泛型,因此resultType="com.tedu.pojo.Emp";
  • resultMap属性:复杂对象结构(例如多表关联查询等)。 使用 resultType 或 resultMap,但不能同时使用。

MyBatis增删改查

新增员工

1、编辑EmpMapper.xml文件, 添加新增员工对应的sql.







1
<!-- 练习2: 新增员工信息: 赵云 保安 6000
2
增删改的标签上不用指定resultType, 因为返回值都是int类型
3
-->
4
<update id="insert" >
5
    insert into emp value(null, '赵云', '保安', 6000)
6
</update>

2、编写TestMybatis类,添加testInsert方法,实现新增员工操作。







1
/** 练习2: 新增员工信息: 赵云 保安 6000 */
2
@Test
3
public void testInsert() {
4
  //执行sql语句, 返回执行结果
5
  int rows = session.update("EmpMapper.insert");
6
  //提交事务
7
  session.commit();
8
  System.out.println("影响的行数: "+rows);
9
}

修改员工

1、编辑EmpMapper.xml文件, 添加新增员工对应的sql。







1
<!-- 练习3:修改员工信息:赵云 保镖 20000 -->
2
<update id="update">
3
    update emp set job='保镖', salary=20000 where name='赵云'
4
</update>

2、编写TestMybatis类,添加testUpdate方法,实现修改员工信息。







1
/** 练习3: 修改员工信息, 将赵云的job改为'保镖',salary改为20000 */
2
@Test
3
public void testUpdate() {
4
  //执行sql语句, 返回执行结果
5
  int rows = session.update("EmpMapper.update");
6
  //提交事务
7
  session.commit();
8
  System.out.println("影响行数:"+rows);
9
}

删除员工

1、编辑EmpMapper.xml文件, 添加新增员工对应的sql。







1
<!-- 练习4: 删除name为'赵云'的记录 -->
2
<update id="delete">
3
    delete from emp where name='赵云'
4
</update>

2、编写TestMybatis类,添加testDelete方法,实现删除员工。

1
/** 练习4: 删除name为'赵云'的记录 */
2
@Test
3
public void testDelete() {
4
  //执行sql语句, 返回执行结果
5
  int rows = session.update("EmpMapper.delete");
6
  //提交事务
7
  session.commit();
8
  System.out.println("影响行数:"+rows);
9
}