第一个Mybatis程序示例 Mybatis简介(一)

在 JDBC 小结中(可以参阅本人 JDBC 系列文章),介绍到了 ORM,其中 Mybatis 就是一个不错的 ORM 框架
MyBatis 由 iBatis 演化而来
iBATIS 一词来源于“internet”和“abatis”的组合,是一个由 Clinton Begin 在 2001 年发起的开放源代码项目。于 2010 年 6 月 16 号被谷歌托管,改名为 MyBatis。
是一个基于 SQL 映射支持 Java 和·NET 的持久层框架。
 
MyBatis 是一个优秀的持久层框架,对 JDBC 操作数据库进行了封装,封装后的 Mybatis 使应用程序开发者只需要关注 SQL 本身
完全不需要再次花精力去处理例如注册驱动、创建 connection、创建 statement、手动设置参数、结果集检索等 jdbc 繁杂的过程代码(最初的 Mybatis 环境搭建只需要立项之初配置即可)
  • 要求通过 xml 或注解的方式将要执行的各种 statement(statement、preparedStatemnt、CallableStatement)配置起来
  • 并通过 java 对象和 statement 中的 sql 进行映射生成最终执行的 sql 语句
  • mybatis 框架执行 sql 并将结果映射成 java 对象并返回。
项目环境搭建好之后我们需要做的就是通过 XML 或者注解将要执行的 SQL 配置起来,也就是仅仅关注 SQL
 
中文版文档
http://www.mybatis.org/mybatis-3/zh/index.html
github 地址
https://github.com/mybatis/mybatis-3
截止本文,最新版本为:mybatis-3.4.6
 
本文不涉及架构解析,首先演示了一个最简单的示例,然后以这个简单示例为基础,简单介绍了从外部看过去的 Mybatis 的呈现样子
帮助简单了解 Mybatis
原文地址: 第一个 Mybatis 程序示例 Mybatis 简介(一)

第一个 Mybatis 程序

1. 新建项目

新建一个 Java 项目
我取名为 mybatis,并且新建了一个包 first
image_5c4fb3c7_7089

2. 包获取与导入

基础的两个包
mybatis 和 mysql-connector(因为要用 MYSQL) ,可以从官方下载  
https://dev.mysql.com/downloads/connector/j/
https://github.com/mybatis/mybatis-3/releases
image_5c4fb3c7_4d8d

3. 数据库准备

本人已经有本地数据库,MYSQL,以 student 表为测试
CREATE TABLE `student` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL DEFAULT '默认姓名' COMMENT '姓名',
  `age` int(11) DEFAULT '1',
  `sex` varchar(255) DEFAULT NULL,
  `random` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8;

 

image_5c4fb3c7_2ce3
数据库信息为:
    String user = "root";
    String password = "123456";
    String url = "jdbc:mysql://localhost:3306/sampledb?useUnicode=true&characterEncoding=utf-8";

4. 配置文件设置

src 下新建 config,然后新建 xml 文件名为 mybatis-config.xml
内容从官方文档中复制:  http://www.mybatis.org/mybatis-3/zh/getting-started.html 
image_5c4fb3c7_45ef
如下图所示官方示例的配置 XML
image_5c4fb3c8_4712

5.SQL 映射文件设置

src 下新建 mapper 文件夹,创建 xml 文件名为 myBatis.xml
内容从官方文档复制
image_5c4fb3c8_4a84
 
image_5c4fb3c8_288d

6. 调整配置文件

image_5c4fb3c9_1e82
主要任务就是将数据库链接信息设置准确,并且将 SQL 映射文件的位置设置准确
image_5c4fb3c9_70e9
 
对于 url 的设置需要注意“&”符号,在 xml 的配置文件中 要用  &   代替 &
这是 XML 的语法本身的问题与 mybatis 没关系
 
image_5c4fb3c9_6f94
五个在 XML 文档中预定义好的实体:
&lt; < 小于号
&gt; > 大于号
&amp; & 和
&apos; ' 单引号
&quot; " 双引号
实体必须以符号 "&" 开头,以符号 ";" 结尾

7. 创建实体类 Student

image_5c4fb3c9_504d

8. 修改 myMapper.xml 文件

需要调整 namespace 设置 resultType 类型,需要设置使用的 sql
image_5c4fb3c9_548e

9. 测试

image_5c4fb3c9_31ed
每一次的业务开发时,其实需要的仅仅是编写 myMapper.xml 文件,然后对其调用
环境配置等工作环境搭建之初就已经完成了

初识 Mybatis

在第一个 Mybatis 程序示例中的代码几乎都是官方文档中的,根据官方的提示一步一步操作即可建立
 
不管是 Mybatis 还是 JDBC 还是其他,终归是需要连接数据库的,不管以何种形式,连接以后就是需要执行 SQL,所以你还得准备好你想要执行的 SQL
在 Mybatis 中,SQL 以 XML 文件的形式设置 ,也就是上例中的 myMapper.xml 文件
所以在上例中的主配置文件 mybatis-config.xml 中我们配置了数据库的连接信息以及 SQL XML 文件的位置
每个基于 Mybatis 的应用都是以一个 SqlSessionFactory 的实例为中心的,这一部分核心的配置文件就是提供给 SqlSessionFactory 实例的。
 
既然是操作数据库,很重要的一部分自然是 SQL 语句
mapper 文件的格式是什么?对于一个 SQL 到底是查询还是 delete?返回类型是什么?如下图所示,我们的类型是 first.Student,SQL 的内容又是什么?
image_5c4fb3c9_619
此处不深入,但是很显然,对于 Mybatis mapper 映射文件的编写是很重要的一部分学习内容
 
有了核心配置文件就可以构建 SqlSessionFactory 实例,通过 SqlSessionFactory 实例就可以获取到 SqlSession 对象
SqlSession 是 Mybatis 最重要的构建之一,可以简单的认为 Mybatis 一系列的配置目的是生成类似 JDBC 生成的 Connection 对象的 SqlSession 对象
有了这个“Connection”对象之后才能进一步与数据库进行交流
这个“Connection”对象就可以根据我们 mapper xml 配置文件中设置的标识符,比如上例中的 selectStudent 的全名,以及参数执行 SQL
image_5c4fb3ca_777b
如上图所示,我们从头简单的理一下 Mybatis 的基本流程
需要两个重要信息:数据库配置以及 mapper 文件位置
通过这两个核心信息可以生成 SqlSessionFactory,通过 SqlSessionFactory 就可以创建 SqlSession
SqlSession 就可以根据名称标识符识别需要执行哪个文件里面的哪个 SQL,比如上面就是执行 mapper/myMapper.xml 文件中,标识符为 selectStudent 的那一条
而执行该 SQL 以及周边的信息,都在文件中指定了,比如 SQL 内容是什么?返回类型又是什么?
 
通过配置文件到 SqlSessionFactory 实例的创建,完成了宏观上 Mybatis 的配置,两个主要任务:
  • 要从哪个数据库进行操作?
  • 要操作的 SQL 在哪里?
通过 SqlSession 完成了具体一次执行的任务
  • 执行哪个 SQL?通过层级的命名标识符定位
  • 执行 SQL 的细节信息有哪些?SQL 内容,参数内容,返回类型等
image_5c4fb3ca_4a57
 
比如现在的中国好声音,形式变化了
所有的参赛选手在等待大厅内坐等,所有的人的姓名和演唱曲目形成了歌单,导师点歌的形式选择选手表演。
这个过程很类似 Mybatis 的处理
 
所有的选手形成了一个等待集合,这就相当于是一系列的 mapper.xml 文件,每个选手都有一个名字,这就相当于是一个文件(一个文件名,或者说一个命名空间)
但是重名的有很多,当导师叫名字 xxx 的时候,其实是在说“本次参加中国好声音,等待大厅的 xxx”,但是不说大家也都知道,说王伟的时候,肯定不会是你身边坐着那个同事
但是程序不知道,这个“本次参加中国好声音,等待大厅的 xxx”就相当于上例中 namespace="mapper.myMapper"
 
整个节目组,导师,时间,场地等这些环境信息因素构成了整个的节目核心,这些零散的数据就是配置项目
构成的整体就相当于一个运行的机器,这就相当于 SqlSessionFactory 
他作为核心知道整个节目组所有的信息,导师的信息等等,学员以及学员表演曲目也呈现在了导师面前
 
当一个导师进行点歌时,就类似 SqlSession 执行一次数据库操作
导师通过姓名,也就是我们上面说的“一个隐含的命名空间”,进行点歌,选择选手进行表演
这就相当于从等候大厅定位了一个 Mapper 文件,而他表演的那个曲目就好像是 mapper 文件中的 ID,因为你唱了《止战之殇》,别人也可以再唱一次。
而针对于歌曲自身的更多信息,自然要看你接下来的表演了,是不是改变了? 变化了哪些内容等等,这都属于某一个 id 对应的 mapper 文件中的具体内容信息。
 
Mybatis 核心为配置以及映射
  • 配置信息搭建了 Mybatis 应用框架
  • 映射设置了一次执行的所需信息
image_5c4fb3ca_4aa9
Mybatis 细化实现为核心的协调组装
核心信息包含了将要执行的目标数据库信息以及需要执行的 SQL 映射,有了这两部分信息如果是在 Navicat 等客户端的话就足够了,使用数据库信息连接,然后执行 SQL
对于 Mybatis 也是足够了,不过代码中毕竟不是可以手动连接数据库,手动输入 SQL,肉眼查看结果这么简单
所以还有很多的周边业务需要处理,比如配置文件如何表示?都有哪些属性需要配置?另外 MyBatis 是一个功能强大的工具,所以还提供了更多的细节调优参数以供设置
对于 mapper 文件的位置如何描述?
image_5c4fb3ca_552c
前面示例中使用了上面的形式,另外你也可以指定一个包,比如 下面的形式,那么这个包下面所有的 xml 都会被扫描,相当于你全部都罗列了出来
<mappers>
  <package name="org.mybatis.builder"/>
</mappers>
对于映射如何表述?可以使用 XML 也还可以使用注解的形式
他们又有哪些语法?每种形式的利弊是什么?字段属性都有哪些?
参数如何设置? 返回结果又是如何设置呢?等等
尽管这一系列的实现都很复杂,但是,仍旧是围绕着核心信息来的
 
所以对于 Mybatis 的学习,最开始应该了解整体的处理过程, 了解各块
然后就是深入学习配置文件以及映射的设置配置
最后就是了解源码的架构
如果还有精力,最好的文档就是源码了
 

附录:完整代码

数据库
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) NOT NULL DEFAULT '默认姓名' COMMENT '姓名',
`age` int(11) DEFAULT '1',
`sex` varchar(255) DEFAULT NULL,
`random` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

项目结构

image_5c4fb3ca_70aa

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>
<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://localhost:3306/sampledb?useUnicode=true&amp;characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/myMapper.xml"/>
</mappers>
</configuration>

myMapper.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="mapper.myMapper">
<select id="selectStudent" resultType="first.Student">
select * from student where id = #{id}
</select>
</mapper>

Student

package first;

public class Student {

private Long id;

private String name;

private Integer age;

private String sex;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Integer getAge() {
return age;
}

public void setAge(Integer age) {
this.age = age;
}

public String getSex() {
return sex;
}

public void setSex(String sex) {
this.sex = sex;
}

@Override
public String toString() {
final StringBuilder sb = new StringBuilder("Student{");
sb.append(
"id=").append(id);
sb.append(
", name='").append(name).append(''');
sb.append(
", age=").append(age);
sb.append(
", sex='").append(sex).append(''');
sb.append(
'}');
return sb.toString();
}
}

测试代码

package first;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Test {

public static void main(String[] args) throws Exception {

/*

  • 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。
  • SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
  • 而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
  • /
    String resource
    = "config/mybatis-config.xml";
    InputStream inputStream
    = Resources.getResourceAsStream(resource);
    SqlSessionFactory sqlSessionFactory
    = new SqlSessionFactoryBuilder().build(inputStream);
    /
  • 从 SqlSessionFactory 中获取 SqlSession
  • */
    SqlSession session
    = sqlSessionFactory.openSession();
    try {
    Student student
    = (Student) session.selectOne("mapper.myMapper.selectStudent", 2);
    System.out.println(student);
    }
    finally {
    session.close();
    }
    }
    }

接口应用

而对于 SQL 的执行更好的一种方式是使用接口,而不是直接通过字符串去定位需要执行的目标资源
借助于接口不是基于字符串常量的,就会更安全,而且使用接口逻辑概念更加清晰
 
在原有结构上增加一个接口和一个映射文件
image_5c4fb3ca_14ce
 
MyMapper.java
package first;
public interface MyMapper {Student selectStudent(Integer id);
}
myMapper2.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="first.MyMapper">
<select id="selectStudent" resultType="first.Student">
select * from student where id = #{id}
</select>
</mapper>
从下图可以看得出来接口与 XML 映射的数据对照关系,XML 映射文件的 namespace 需要与接口的全限定名对应
接口的方法名对应 XML 映射的 id
接口方法返回类型为 XML 映射的 ResultMap(resultType)
接口方法的参数对应 XML 映射的入参
image_5c4fb3ca_d79
新增加了一个 XML 映射文件,需要将路径添加到配置中
image_5c4fb3ca_5963
增加一个测试类
package first;

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

public class Test2 {

</span><span style="color: rgba(0, 0, 255, 1)">public</span> <span style="color: rgba(0, 0, 255, 1)">static</span> <span style="color: rgba(0, 0, 255, 1)">void</span> main(String[] args) <span style="color: rgba(0, 0, 255, 1)">throws</span><span style="color: rgba(0, 0, 0, 1)"> Exception {
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为中心的。
* SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。
* 而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先定制的 Configuration 的实例构建出 SqlSessionFactory 的实例。
* </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
String resource </span>= "config/mybatis-config.xml"<span style="color: rgba(0, 0, 0, 1)">;
InputStream inputStream </span>=<span style="color: rgba(0, 0, 0, 1)"> Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory </span>= <span style="color: rgba(0, 0, 255, 1)">new</span> SqlSessionFactoryBuilder().build(inputStream,"development"<span style="color: rgba(0, 0, 0, 1)">);
 
</span><span style="color: rgba(0, 128, 0, 1)">/*</span><span style="color: rgba(0, 128, 0, 1)">
* 从 SqlSessionFactory 中获取 SqlSession
* </span><span style="color: rgba(0, 128, 0, 1)">*/</span><span style="color: rgba(0, 0, 0, 1)">
SqlSession session </span>=<span style="color: rgba(0, 0, 0, 1)"> sqlSessionFactory.openSession();
</span><span style="color: rgba(0, 0, 255, 1)">try</span><span style="color: rgba(0, 0, 0, 1)"> {
    MyMapper mapper </span>= session.getMapper(MyMapper.<span style="color: rgba(0, 0, 255, 1)">class</span><span style="color: rgba(0, 0, 0, 1)">);
    Student student </span>= mapper.selectStudent(2<span style="color: rgba(0, 0, 0, 1)">);
    System.out.println(student);
} </span><span style="color: rgba(0, 0, 255, 1)">finally</span><span style="color: rgba(0, 0, 0, 1)"> {
    session.close();
}

}

}

关键代码为
      MyMapper mapper = session.getMapper(MyMapper.class);
      Student student = mapper.selectStudent(2);
结果与前面一致
原文地址:第一个 Mybatis 程序示例 Mybatis 简介(一)