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

实现基本的数据库操作功能的流程如下:

  1. 编写xml文件,配置运行环境。
  2. 通过IO流载入xml文件,创建SqlSessionFactory对象(会话工厂)。
  3. 由会话工厂,创建SqlSession对象(会话)。
  4. 通过SqlSession对象,操作数据库。注意增删改操作需要提交事务,否则对数据库做出的修改不会更改数据库中的记录。
  5. 最后需要关闭SqlSession对象和IO流,释放资源。

一、xml配置文件

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

1.MybatisConfig.xml

Mybatis的全局配置文件,主要用于配置Mybatis的运行环境(事务管理器、数据源等)。具体详情可见Mybatis说明文档

下面通过一个简单的示例,来简要说明这个配置文件。

 <?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文件 -->
<properties resource="db.properties"></properties>
<!-- 和spring整合后 environments配置将废除-->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事务管理,事务控制由mybatis管理-->
<transactionManager type="JDBC" />
<!-- 数据库连接池,由mybatis管理-->
<dataSource type="POOLED">
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
<property name="url" value="${url}"/>
<property name="driver" value="${driver}"/>
<property name="poolMaximumActiveConnections" value="${maxActive}"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
  1. 头文件(1~2行):第1行是xml声明,声明该xml文件的字符集为UTF-8;第2行是DTD文件类型声明(外部DTD),用于约束该xml文件的结构。引用的DTD约束的格式为<!DOCTYPE 根元素 SYSTEM "DTD文件路径">(本地文件),或<!DOCTYPE 根元素 PUBLIC "DTD名称" "DTD文件URL">(公共文件),这里是约束configuaration元素的结构为链接中的DTD文件所约束的那样。
  2. properties元素(5行):这里是用于引入外部properties文件。其实还可以在properties元素中定义一些属性,但不建议这么做,最好还是把所有属性放在外部文件中。
  3. environments元素(7~20行):用于配置要创建的SqlSessionFactory实例的环境。每个数据库对应一个SqlSessionFactory实例,每个SqlSessionFactory实例只能选择一种环境(environments元素中可以定义多个environment元素)。
    • 第7行:默认的环境id。
    • 第8行:定义一个environment元素,并设定环境id。
    • 第10行:事务管理器的配置,可选"JDBC"或"MANAGED"。【注:Spring+Mybatis不需要配置事务管理器,因为Spring会用自带管理器覆盖这些配置】
      • "JDBC":直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
      • "MANAGED":不提交或回滚一个连接,而是让容器来管理事务的整个生命周期,默认情况下它会关闭连接。
    • 第12~18行:数据源的配置。第12行是配置数据源类型,内置了"UNPOOLED","POOLED"和"JNDI";第13~18行是设定数据源。
      • "UNPOOLED":不使用数据库连接池。只有driver,url,username,password,defaultTransactionIsolationLevel五个属性,其中最后一个属性是指默认的连接事务隔离级别。
      • "POOLED":使用数据库连接池。除了"UNPOOLED"中的5个属性之外,还多了一些连接池属性,比如poolMaximumActiveConnections(最大活动连接数)、poolMaximumIdleConnections(最大空闲连接数)等(详见说明文档)。
      • "JNDI":为了能在如EJB或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个JNDI上下文的引用。只需"initial_context"和"data_source"两个属性。
      • 另外,也可以将type设置为一个数据源类,使用任何第三方数据源。
  4. mappers元素(22~24行):用于设定映射文件路径。可以通过classpath相对路径、文件系统绝对路径设定映射文件,还可以通过类名、包名设定映射接口。

2.StudentMapper.xml

sql映射文件,主要用于实现数据库操作的具体细节。此文件需要在MybatisConfig.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="cn.cage.student.StudentDAO"> <insert id="addStu" parameterType="cn.cage.student.Student">
INSERT INTO students
(name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom)
VALUES
(#{name},#{qq},#{major},#{entryTime},#{school},#{jnshuId},#{dailyUrl},#{desire},#{jnshuBro},#{knowFrom})
</insert> <delete id="delStuById" parameterType="long">
DELETE FROM students WHERE
id=#{id}
</delete>
<delete id="delStu" parameterType="cn.cage.student.Student"></delete> <update id="updateStu">
UPDATE students SET
name=#{stu.name},qq=#{stu.qq},major=#{stu.major},entrytime=#{stu.entryTime},gra_school=#{stu.school},id_jnshu=#{stu.jnshuId}
,daily_url=#{stu.dailyUrl},desire=#{stu.desire},bro_jnshu=#{stu.jnshuBro},knowfrom=#{stu.knowFrom}
WHERE id=#{id}
</update> <select id="queryStuById" resultMap="stuMap">
SELECT
id,create_at,update_at,name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom
FROM students WHERE id=#{id}
</select>
<select id="queryStuByName" resultMap="stuMap">
SELECT
id,create_at,update_at,name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom
FROM students WHERE name=#{name}
</select>
<select id="queryStuByJnshu" resultMap="stuMap">
SELECT
id,create_at,update_at,name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom
FROM students WHERE major=#{major} and id_jnshu=#{jnshuId}
</select>
<select id="queryStu"></select> <resultMap type="cn.cage.student.Student" id="stuMap">
<constructor>
<arg column="name" javaType="String" jdbcType="VARCHAR" />
<arg column="major" javaType="String" jdbcType="VARCHAR" />
<arg column="id_jnshu" javaType="int" jdbcType="INTEGER" />
</constructor>
<id property="id" column="id" />
<result property="createTime" column="create_at" />
<result property="updateTime" column="update_at" />
<result property="qq" column="qq" />
<!-- 此处虽然javaType为String,jdbcType为DATE,但并不需要特别的转换就可以映射 -->
<result property="entryTime" column="entrytime" />
<result property="school" column="gra_school" />
<result property="dailyUrl" column="daily_url" />
<result property="desire" column="desire" />
<result property="jnshuBro" column="bro_jnshu" />
<result property="knowFrom" column="knowfrom" />
</resultMap> </mapper>

>>关于类文件的别名:在MybatisConfig.xml的Configuration中,添加属性typeAlias即可:

<typeAlias type="cn.cage.Student" alias="Student"/>
  1. 头文件(1~2行):同上,这里是约束mapper元素的结构为链接中的DTD文件所约束的那样。
  2. 命名空间(3行):最基本的意义,是给这个mapper命名用于区分;更为高级的用法,则是接口绑定(面向接口编程)。namespace的命名方式分为两种:完全限定名和短名称。本例中使用的就是完全限定名。使用短名称时,必须确保这个短名称在系统中是唯一的,否则只能使用完全限定名。
    • 接口绑定:将namespace设为DAO接口,将接口中的方法都通过mapper中的元素实现(元素id与接口方法一一对应),就可以不用写DAO实现类,Mybatis会通过绑定自动找到要执行的sql语句。
  3. mapper顶级元素(4~61行):mapper中有8个顶级元素,分别是insert,delete,update,select(映射增删改查语句),sql(重用sql语句块),resultMap(描述如何从结果集中加载对象),cache(缓存配置),cache-ref(其他namespace缓存配置)。
    1. insert、delete、update(5~23行):基本格式就是<元素名 元素属性>sql语句</元素名>。其中,元素名即为insert/delete/update中的一个,可设定的元素属性有9个,这里只列出5个,一般设定1,2即可。在sql语句中,用#{}表示占位符,执行时将#{}替换为?,然后将括号内的参数传递给?。
      常用元素属性:(详见说明文档
      1. id:元素标识。
      2. parameterType:接受的参数类型,可为完全限定名或别名。默认为unset。传入多个参数时,这个属性应忽略,在#{}中直接以各参数名表示。(如:18~23行)
      3. flushCache:为true时,调用sql会清空本地缓存和二级缓存。在insert,delete,update中默认为true,在select中默认为false。
      4. timeout:驱动程序等待数据库返回结果的最大时间,超出则抛出异常。默认为unset。
      5. statementType:可选STATEMENT/PREPARED/CALLABLE,分别让Mybatis使用Statement,PreparedStatement,CallableStatement。默认为PREPARED。
    2. select(25~40行):基本格式同上。select可设定的元素属性有13个,除了上述的5个属性之外,还有2个常用属性。当数据库列名与POJO属性名不一致时,可以在sql语句中使用别名(as),或使用resultMap。
      1. resultType:此select语句的返回值类型。如果返回集合,应该写集合包含的类型。
      2. resultMap:外部resultMap的引用。和resultType不能同时使用。
    3. resultMap(42~59行):基本属性有id,type和autoMapping,分别是本resultMap的标识,对应的POJO类,是否自动映射。
      resultMap有6个可用元素:(详见说明文档
      1. constructor:在类实例化时,注入结果到构造方法中。其中,idArg是ID参数(详见下一条),arg是注入到构造函数的普通结果。
        其中,idArg和arg常用属性如下:

        • column:对应数据库中的列名。
        • javaType:完全限定名/别名。映射到HashMap时必须指定,其他时候可以省略。
        • name:构造函数的形式参数名。
      2. id:id会将结果标记为标识符(给结果取个名字),以便在比较对象时使用。这可以提升整体性能,特别是缓存和嵌入结果映射(比如联合映射) 。
      3. result:注入到属性的普通结果。
        id和result的常用属性如下:
        • property:POJO类中的属性名。
        • column:对应数据库中的列。
        • javaType:完全限定名/别名。映射到HashMap时必须指定,其他时候可以省略。
      4. association:关联。
      5. collection:集合。
        主要处理多个表之间的联合映射。
      6. discriminator:鉴别器。可以根据某一列结果的值的不同,来决定接下来的行为(比如将另一列的结果映射到某个POJO属性)。
        4,5,6三个属性本例中无需使用,暂不详细介绍。详情见说明文档

二、Java代码

通过StudentMapper.xml进行DAO接口绑定后,不需要编写接口的实现类,就能直接根据接口规定的参数列表传入参数,进行数据操作。值得注意的是,如果不编写实现类的话,接口中增删改函数的返回值设定是无用的,只能返回SqlSession类中对应函数指定的返回值类型。

数据库操作在代码中的实现步骤大体如下:

  1. 创建IO流,通过Resources类中的getResourceAsStream方法载入全局配置文件(MybatisConfig.xml)。
  2. 由SqlSessionFactoryBuilder对象的build方法,创建SqlSessionFactory对象。
  3. 由SqlSessionFactory对象的openSession方法,创建SqlSession对象。
  4. 由SqlSession对象,操作数据库。
  5. 关闭SqlSession对象,然后关闭IO流。

下面主要讲解一下通过SqlSession对象操作数据库的内容。

1.SqlSession类中的常用方法

目前主要用到过的方法有:

  1. insert,delete,update:对数据库进行增/删/改操作。注意:进行了这些操作之后,必须调用commit()提交事务,否则数据库记录不会改变。
    返回值:int,操作所影响的行数。
    参数:("sqlID",param):
    1. sqlID:StudentMapper.xml中对应的sql元素的id,若有多个mapper,可以通过mapper.sqlID的形式指定。
    2. param:若对应的接口函数只需要传入一个参数,直接将这个参数传入即可。【最好用变量的形式传入。直接传常量可能会导致类型转换异常】
      若需传入多个参数,则应该用HashMap<String,Object>传入参数。其中,String是mapper.xml中的参数名(#{xx}),Object是参数值。将多个参数放入map后,将map作为参数传入即可。
  2. commit():刷新批处理语句并提交数据库连接。在增删改之后必须调用。
  3. selectOne("sqlID",param):参数意义同上。返回值:mapper.xml中规定的返回值类型。
  4. selectList("sqlID",param):同上。返回值:List<E>,其中E为mapper.xml中规定的返回值类型。
  5. close():关闭会话,释放资源。

2.注意事项

  1. POJO类中的构造方法的参数类型,如果是基本数据类型,应该写成其包装类的形式(比如int写为Integer)。因为mapper.xml中的javaType会自动转为完全限定名(比如int转为java.lang.Integer)。如果在resultMap中定义了constructor元素,映射到POJO类时会是完全限定名的类型,如果构造方法中的参数类型不是包装类,就会报错(找不到参数类型为xxx的构造函数)。
  2. 务必在insert/delete/update之后执行commit!否则一切操作都不会在数据库中生效!

最后,对上述内容举例说明:上述配置文件的测试代码。

 /**
* @FileName:MybatisStuImpl.java
* @description:
* @author Cage Yang
* @version
* Modified Date:2017年8月23日
* Why & What is modified: <修改原因描述>
*/
package cn.cage.student; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull; import java.io.InputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List; 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 org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test; /**
* @ClassName MybatisStuImpl
* @description 测试通过Mybatis接口绑定自动生成的数据操作类的运行情况。
* @author Cage Yang
*/
public class MybatisStuImpl {
static InputStream in = null;
static SqlSession sqlSession = null; /**
* @description 创建出SqlSession实例
* @throws java.lang.Exception
*/
@BeforeClass
public static void setUpBeforeClass() throws Exception {
String resource = "MybatisConfig.xml";
in = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
sqlSession = sqlSessionFactory.openSession();
} /**
* @description 释放资源
* @throws java.lang.Exception
*/
@AfterClass
public static void tearDownAfterClass() throws Exception {
sqlSession.close();
in.close();
} @Test
public void testAddStu() {
Student stu = RandomStudent.getStudent();
stu.setMajor("java");
stu.setJnshuId(1501);
assertEquals("插入失败!", 1, sqlSession.insert("addStu", stu));
sqlSession.commit();
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("major", "java");
param.put("jnshuId", 1501);
Student stu2 = sqlSession.selectOne("queryStuByJnshu", param);
assertEquals("插入错误,或查询byJnshu出错", stu, stu2);
} @Test
public void testDelStuById() {
long id = 4;
Student student = sqlSession.selectOne("queryStuById", id);
System.out.println(student.getEntryTime());
assertEquals("删除失败!", 1, sqlSession.delete("delStuById", id));
sqlSession.commit();
assertNull("删除错误,或查询byId出错", sqlSession.selectOne("queryStuById", id));
} @Test
public void testUpdateStu() {
long id = 5;
Student stu = sqlSession.selectOne("queryStuById", id);
stu.setDesire("哈哈哈哈哈哈哈哈");
HashMap<String, Object> param = new HashMap<String, Object>();
param.put("stu", stu);
param.put("id", id);
assertEquals("更新失败!", 1, sqlSession.update("updateStu", param));
sqlSession.commit();
assertEquals("更新错误,或查询byId出错", "哈哈哈哈哈哈哈哈", ((Student) sqlSession.selectOne("queryStuById", id)).getDesire());
} @Test
public void testQueryStuByName() {
List<Student> list = sqlSession.selectList("queryStuByName", "王五");
for (Iterator<Student> iterator = list.iterator(); iterator.hasNext();) {
Student student = (Student) iterator.next();
if (student.getJnshuId() == 1111) {
assertEquals("查询byName出错", "2017-08-06", student.getEntryTime());
}
}
}
}

JUnit4测试代码

三、与Spring-JdbcTemplate的比较

1.Mybatis必须用IO流载入xml配置文件,JdbcTemplate可以直接载入。

2.Mybatis可以无需编写数据操作类、通过配置文件绑定接口,JdbcTemplate必须编写类实现数据操作接口。

3.Mybatis可使用自带数据源类,JdbcTemplate只能使用外部数据源类。

4.mapper中的元素:增删改查元素对应StudentDAOImpl中的各实现方法,resultMap对应JdbcTemplate中的QueryStuRowMapper。

Mybatis说明文档:http://www.mybatis.org/mybatis-3/zh/getting-started.html

l

MyBatis框架概述的更多相关文章

  1. 03 Mybatis框架---学习笔记1--框架的概念及优势

    1.框架的概念 框架其实就是某种应用的半成品,就是一组组件,供你选用完成你自己的系统.简单说就是使用别人搭好的舞台,你来做表演.而且,框架一般是成熟的,不断升级的软件.框架是我们软件开发中的一套解决方 ...

  2. Mybatis框架(未完待续)

    1.框架概述:                        它是我们软件开发中的一套解决方案,不同的框架解决的是不同的问题.好处:框架封装了很多的细节,使开发者可以使用极简的方式实现功能.大大提高开 ...

  3. SSM(Spring+SpringMVC+Mybatis)框架环境搭建(整合步骤)(一)

    1. 前言 最近在写毕设过程中,重新梳理了一遍SSM框架,特此记录一下. 附上源码:https://gitee.com/niceyoo/jeenotes-ssm 2. 概述 在写代码之前我们先了解一下 ...

  4. (转)MyBatis框架的学习(二)——MyBatis架构与入门

    http://blog.csdn.net/yerenyuan_pku/article/details/71699515 MyBatis框架的架构 MyBatis框架的架构如下图: 下面作简要概述: S ...

  5. Spring Boot:整合MyBatis框架

    综合概述 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单 ...

  6. Mybatis框架(9)---Mybatis自定义插件生成雪花ID做为表主键项目

    Mybatis自定义插件生成雪花ID做为主键项目 先附上项目项目GitHub地址 spring-boot-mybatis-interceptor 有关Mybatis雪花ID主键插件前面写了两篇博客作为 ...

  7. 1、MyBatis框架底层初涉

    1.拜年 哈哈,现在是过年了,祝大家新年好. 本来大过年的是不打算碰电脑的,(抢票除外,三疯同学现在还没抢到票,然后突然又延长假期了).现在疫情严重,被堵家里不能出去了.不能为国家做贡献,但是起码不能 ...

  8. MyBatis框架基础详细开发流程

    MyBatis 项目已托管到GitHub,大家可以去GitHub查看下载!并搜索关注微信公众号 码出Offer 领取各种学习资料! 一.框架概述 1.1 什么是框架? 软件的半成品,解决了软件开发过程 ...

  9. SpringBoot+MySQL,如何整合并使用MyBatis框架

    概述 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. MyBatis 可以使用简单的 ...

随机推荐

  1. git 不成功

    fatal: Interactive git shell is not enabled.hint: ~/git-shell-commands should exist and have read an ...

  2. Cypher查询语言--Neo4j-WHERE(三)

    目录 Where Boolean 操作类型 节点属性上的过滤 正则表达式 转义正则表达式 不分大小些正则表达式 关系类型上的过滤 属性存在性 如果缺失属性默认为true 如果缺失属性默认为false ...

  3. OS模块的常用内置方法

    chdir 修改当前工作目录到指定目录 Change the current working directory to the specified path. chmod 修改一个文件的访问权限 Ch ...

  4. ABP官方文档翻译 5.2 动态We API层

    动态Web APID层 创建动态Web API控制器 ForAll方法 重写ForAll ForMethods Http动词 WithVerb方法 HTTP特性 命名约定 API管理器 RemoteS ...

  5. 【OH】Oracle软件安装需要的软件包(官方文档)

    1  安装12c 1.1  Table 3 x86-64 Supported Linux 7 Operating System Requirements Item Requirements SSH R ...

  6. AC 自动机 模板

    简单版 #include <iostream> #include <cstdio> #include <algorithm> #include <cstrin ...

  7. 洛谷 [P1578] WC2002 奶牛浴场

    本题是一道用极大化思想求最大子矩阵的经典题目.这个题目很出名,可以在百度搜索王知昆国家队dalao的论文,其中说的非常详细. 先枚举极大子矩形的左边界,然后从左到右依次扫描每一个障碍点,并不断修改可行 ...

  8. adb模拟操作之event

    首语: 我们都知道,adb可以对模拟器和root过的真机进行很多操作,例如:模拟点击,输入,截图,手机和PC,数据互传等.这篇要说的就是adb操作模拟器或者真机的输入输出. 0x01 问题 使用adb ...

  9. IOS教程视频汇总

    使用StoryBoard做iOS UI界面跳转

  10. idea Code激活

    参考:http://blog.csdn.net/gnail_oug/article/details/70677272 1.将激活包复制到bin安装目录: 2.在安装的idea下面的bin目录下面有2个 ...