热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

开发笔记:MyBatis框架概述

篇首语:本文由编程笔记#小编为大家整理,主要介绍了MyBatis框架概述相关的知识,希望对你有一定的参考价值。MyBatis是一个优秀的持久层框架,它对jd

篇首语:本文由编程笔记#小编为大家整理,主要介绍了MyBatis框架概述相关的知识,希望对你有一定的参考价值。


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说明文档。

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


1 xml version="1.0" encoding="UTF-8"?>
2 DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
3 <configuration>
4
5 <properties resource="db.properties">properties>
6
7 <environments default="development">
8 <environment id="development">
9
10 <transactionManager type="JDBC" />
11
12 <dataSource type="POOLED">
13 <property name="username" value="${username}"/>
14 <property name="password" value="${password}"/>
15 <property name="url" value="${url}"/>
16 <property name="driver" value="${driver}"/>
17 <property name="poolMaximumActiveConnections" value="${maxActive}"/>
18 dataSource>
19 environment>
20 environments>
21
22 <mappers>
23 <mapper resource="StudentMapper.xml"/>
24 mappers>
25 configuration>



  1. 头文件(1~2行):第1行是xml声明,声明该xml文件的字符集为UTF-8;第2行是DTD文件类型声明(外部DTD),用于约束该xml文件的结构。引用的DTD约束的格式为(本地文件),或(公共文件),这里是约束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中加载。

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


1 xml version="1.0" encoding="UTF-8" ?>
2 DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
3 <mapper namespace="cn.cage.student.StudentDAO">
4
5 <insert id="addStu" parameterType="cn.cage.student.Student">
6 INSERT INTO students
7 (name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom)
8 VALUES
9 (#{name},#{qq},#{major},#{entryTime},#{school},#{jnshuId},#{dailyUrl},#{desire},#{jnshuBro},#{knowFrom})
10 insert>
11
12 <delete id="delStuById" parameterType="long">
13 DELETE FROM students WHERE
14 id=#{id}
15 delete>
16 <delete id="delStu" parameterType="cn.cage.student.Student">delete>
17
18 <update id="updateStu">
19 UPDATE students SET
20 name=#{stu.name},qq=#{stu.qq},major=#{stu.major},entrytime=#{stu.entryTime},gra_school=#{stu.school},id_jnshu=#{stu.jnshuId}
21 ,daily_url=#{stu.dailyUrl},desire=#{stu.desire},bro_jnshu=#{stu.jnshuBro},knowfrom=#{stu.knowFrom}
22 WHERE id=#{id}
23 update>
24
25 <select id="queryStuById" resultMap="stuMap">
26 SELECT
27 id,create_at,update_at,name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom
28 FROM students WHERE id=#{id}
29 select>
30 <select id="queryStuByName" resultMap="stuMap">
31 SELECT
32 id,create_at,update_at,name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom
33 FROM students WHERE name=#{name}
34 select>
35 <select id="queryStuByJnshu" resultMap="stuMap">
36 SELECT
37 id,create_at,update_at,name,qq,major,entrytime,gra_school,id_jnshu,daily_url,desire,bro_jnshu,knowfrom
38 FROM students WHERE major=#{major} and id_jnshu=#{jnshuId}
39 select>
40 <select id="queryStu">select>
41
42 <resultMap type="cn.cage.student.Student" id="stuMap">
43 <constructor>
44 <arg column="name" javaType="String" jdbcType="VARCHAR" />
45 <arg column="major" javaType="String" jdbcType="VARCHAR" />
46 <arg column="id_jnshu" javaType="int" jdbcType="INTEGER" />
47 constructor>
48 <id property="id" column="id" />
49 <result property="createTime" column="create_at" />
50 <result property="updateTime" column="update_at" />
51 <result property="qq" column="qq" />
52
53 <result property="entryTime" column="entrytime" />
54 <result property="school" column="gra_school" />
55 <result property="dailyUrl" column="daily_url" />
56 <result property="desire" column="desire" />
57 <result property="jnshuBro" column="bro_jnshu" />
58 <result property="knowFrom" column="knowfrom" />
59 resultMap>
60
61 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是mapper.xml中的参数名(#{xx}),Object是参数值。将多个参数放入map后,将map作为参数传入即可。


  2. commit():刷新批处理语句并提交数据库连接。在增删改之后必须调用。

  3. selectOne("sqlID",param):参数意义同上。返回值:mapper.xml中规定的返回值类型。

  4. selectList("sqlID",param):同上。返回值:List,其中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!否则一切操作都不会在数据库中生效!

 

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


技术分享技术分享

1 /**
2 * @FileName:MybatisStuImpl.java
3 * @description:
4 * @author Cage Yang
5 * @version
6 * Modified Date:2017年8月23日
7 * Why & What is modified: <修改原因描述>
8 */
9 package cn.cage.student;
10
11 import static org.junit.Assert.assertEquals;
12 import static org.junit.Assert.assertNull;
13
14 import java.io.InputStream;
15 import java.util.HashMap;
16 import java.util.Iterator;
17 import java.util.List;
18
19 import org.apache.ibatis.io.Resources;
20 import org.apache.ibatis.session.SqlSession;
21 import org.apache.ibatis.session.SqlSessionFactory;
22 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
23 import org.junit.AfterClass;
24 import org.junit.BeforeClass;
25 import org.junit.Test;
26
27 /**
28 * @ClassName MybatisStuImpl
29 * @description 测试通过Mybatis接口绑定自动生成的数据操作类的运行情况。
30 * @author Cage Yang
31 */
32 public class MybatisStuImpl {
33 static InputStream in = null;
34 static SqlSession sqlSession = null;
35
36 /**
37 * @description 创建出SqlSession实例
38 * @throws java.lang.Exception
39 */
40 @BeforeClass
41 public static void setUpBeforeClass() throws Exception {
42 String resource = "MybatisConfig.xml";
43 in = Resources.getResourceAsStream(resource);
44 SqlSessionFactory sqlSessiOnFactory= new SqlSessionFactoryBuilder().build(in);
45 sqlSession = sqlSessionFactory.openSession();
46 }
47
48 /**
49 * @description 释放资源
50 * @throws java.lang.Exception
51 */
52 @AfterClass
53 public static void tearDownAfterClass() throws Exception {
54 sqlSession.close();
55 in.close();
56 }
57
58 @Test
59 public void testAddStu() {
60 Student stu = RandomStudent.getStudent();
61 stu.setMajor("java");
62 stu.setJnshuId(1501);
63 assertEquals("插入失败!", 1, sqlSession.insert("addStu", stu));
64 sqlSession.commit();
65 HashMap param = new HashMap();
66 param.put("major", "java");
67 param.put("jnshuId", 1501);
68 Student stu2 = sqlSession.selectOne("queryStuByJnshu", param);
69 assertEquals("插入错误,或查询byJnshu出错", stu, stu2);
70 }
71
72 @Test
73 public void testDelStuById() {
74 long id = 4;
75 Student student = sqlSession.selectOne("queryStuById", id);
76 System.out.println(student.getEntryTime());
77 assertEquals("删除失败!", 1, sqlSession.delete("delStuById", id));
78 sqlSession.commit();
79 assertNull("删除错误,或查询byId出错", sqlSession.selectOne("queryStuById", id));
80 }
81
82 @Test
83 public void testUpdateStu() {
84 long id = 5;
85 Student stu = sqlSession.selectOne("queryStuById", id);
86 stu.setDesire("哈哈哈哈哈哈哈哈");
87 HashMap param = new HashMap();
88 param.put("stu", stu);
89 param.put("id", id);
90 assertEquals("更新失败!", 1, sqlSession.update("updateStu", param));
91 sqlSession.commit();
92 assertEquals("更新错误,或查询byId出错", "哈哈哈哈哈哈哈哈", ((Student) sqlSession.selectOne("queryStuById", id)).getDesire());
93 }
94
95 @Test
96 public void testQueryStuByName() {
97 List list = sqlSession.selectList("queryStuByName", "王五");
98 for (Iterator iterator = list.iterator(); iterator.hasNext();) {
99 Student student = (Student) iterator.next();
100 if (student.getJnshuId() == 1111) {
101 assertEquals("查询byName出错", "2017-08-06", student.getEntryTime());
102 }
103 }
104 }
105 }


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












推荐阅读
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 在说Hibernate映射前,我们先来了解下对象关系映射ORM。ORM的实现思想就是将关系数据库中表的数据映射成对象,以对象的形式展现。这样开发人员就可以把对数据库的操作转化为对 ... [详细]
  • 本文介绍了Hyperledger Fabric外部链码构建与运行的相关知识,包括在Hyperledger Fabric 2.0版本之前链码构建和运行的困难性,外部构建模式的实现原理以及外部构建和运行API的使用方法。通过本文的介绍,读者可以了解到如何利用外部构建和运行的方式来实现链码的构建和运行,并且不再受限于特定的语言和部署环境。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • flowable工作流 流程变量_信也科技工作流平台的技术实践
    1背景随着公司业务发展及内部业务流程诉求的增长,目前信息化系统不能够很好满足期望,主要体现如下:目前OA流程引擎无法满足企业特定业务流程需求,且移动端体 ... [详细]
  • r2dbc配置多数据源
    R2dbc配置多数据源问题根据官网配置r2dbc连接mysql多数据源所遇到的问题pom配置可以参考官网,不过我这样配置会报错我并没有这样配置将以下内容添加到pom.xml文件d ... [详细]
  • web.py开发web 第八章 Formalchemy 服务端验证方法
    本文介绍了在web.py开发中使用Formalchemy进行服务端表单数据验证的方法。以User表单为例,详细说明了对各字段的验证要求,包括必填、长度限制、唯一性等。同时介绍了如何自定义验证方法来实现验证唯一性和两个密码是否相等的功能。该文提供了相关代码示例。 ... [详细]
  • Oracle优化新常态的五大禁止及其性能隐患
    本文介绍了Oracle优化新常态中的五大禁止措施,包括禁止外键、禁止视图、禁止触发器、禁止存储过程和禁止JOB,并分析了这些禁止措施可能带来的性能隐患。文章还讨论了这些禁止措施在C/S架构和B/S架构中的不同应用情况,并提出了解决方案。 ... [详细]
  • Spring常用注解(绝对经典),全靠这份Java知识点PDF大全
    本文介绍了Spring常用注解和注入bean的注解,包括@Bean、@Autowired、@Inject等,同时提供了一个Java知识点PDF大全的资源链接。其中详细介绍了ColorFactoryBean的使用,以及@Autowired和@Inject的区别和用法。此外,还提到了@Required属性的配置和使用。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • HDFS2.x新特性
    一、集群间数据拷贝scp实现两个远程主机之间的文件复制scp-rhello.txtroothadoop103:useratguiguhello.txt推pushscp-rr ... [详细]
  • MyBatis多表查询与动态SQL使用
    本文介绍了MyBatis多表查询与动态SQL的使用方法,包括一对一查询和一对多查询。同时还介绍了动态SQL的使用,包括if标签、trim标签、where标签、set标签和foreach标签的用法。文章还提供了相关的配置信息和示例代码。 ... [详细]
  • 如何实现JDK版本的切换功能,解决开发环境冲突问题
    本文介绍了在开发过程中遇到JDK版本冲突的情况,以及如何通过修改环境变量实现JDK版本的切换功能,解决开发环境冲突的问题。通过合理的切换环境,可以更好地进行项目开发。同时,提醒读者注意不仅限于1.7和1.8版本的转换,还要适应不同项目和个人开发习惯的需求。 ... [详细]
author-avatar
手机用户2502902093
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有