文档库 最新最全的文档下载
当前位置:文档库 › MyBatis课程讲义2.0

MyBatis课程讲义2.0

MyBatis课程讲义2.0
MyBatis课程讲义2.0

《MyBatis课程讲义》V2.0

作者:王伟2016年6月

邮件:ahler@https://www.wendangku.net/doc/727086311.html,

QQ群:391244052

本文档版权归作者所有,并保留一切权利。未经书面许可,任何公司和个人不得将此文档中的任何部用于商业用途,否则,必将追究其法律责任。

2.0版说明:

●保持1.0版以任务驱动的特点

●MyBatis版本从3.2升级到3.3

●修订了第一章中相关案例的数据库定义

●修订案例,减少案例对其他框架技术的依赖,便于学习

●章节或者小节前标示有“*”,说明该内容是可选的

●新增第4章,描述了MyBatis缓存相关内容

2.1版更新计划

●所有案例采用eclipse+maven开发,不再使用MyEclipse

●MyBatis版本更新到3.4系列

●充实第4章SQL优化案例

第1章MyBatis基础

1.1 MyBatis的诞生背景及其特点

MyBatis的前身是Apache的iBatis开源项目,2010年更名为MyBatis,并从ASF(Apache Software Fundation)迁移到了Google Code。2013年,源代码又托管到了GitHub。在MyBatis诞生之前,Hibernate已经取得了业界的认可,几乎是Java 领域数据库持久化的事实标准。但随着互联网应用的发展,特别是在Web2.0之后,在应用中用户的高度参与性导致互联网应用的数据量急剧增加,典型的应用就是电子商务站点,社交网络等。Hibernate的高度面向对象的封装特性使得其面对大数据开始力不从心。

SQL诞生至今已经超过40年了,在这期间,企业在关系数据库上的投资已经无法估算,有无数的信息系统建立在关系型数据库系统之上,而且这些系统(包括关系型数据库)在未来很长一段时间内将依然存在而且承担关键作用。

在上述关键因素的背景下MyBatis应运而生。MyBatis框架认为,关系型数据库和SQL技术是非常有价值的,有许多的开发团队在SQL上有优秀的技术沉淀,不应该丢弃SQL,尽管SQL存在一些缺点。

MyBatis让开发者可以继续使用SQL,但没有JDBC编程的复杂性,还提供了诸多基础服务以保障效率。总而言之,MyBatis具有以下一些特点,

◆简单易用

◆性能高效

◆保留SQL

◆开源框架

1.2 MyBatis的使用场景

◆当开发团队对数据库设计没有控制权时,例如遗留数据库

◆当应用系统数据分散到多个数据库时

◆当数据库设计没有按照规范化设计时

◆当数据访问效率要求较高时

1.3 MyBatis和Hibernate的区别

◆Hibernate是完全的ORM框架,是实体与关系表的映射,而MyBatis是SQL执

行结果和实体的映射

◆Hibernate解决了面向对象与关系数据库的阻抗问题,例如关系数据库没有继

承,关系数据库只有单向关联等。MyBatis不打算去解决这些问题,保持封装的简洁,以便提高应用执行效率。

1.4 搭建MyBatis开发环境

在本节中,通过实现一个业务功能来演示MyBatis开发环境的搭建。假设某互联网应用需要统计会员总数的功能,采用MyBatis实现。

【准备工作】

事先准备MyEclipse 10.7、Oracle 11gR2数据库、MyBatis-3.3库、Oracle JDBC 驱动库。

MyBatis的前身是iBatis,iBatis发展到3系列时更名为MyBatis。iBatis2系列的最后一个维护版本(iBatis-2.3.5)可以从网址https://https://www.wendangku.net/doc/727086311.html,/mybatis/ibatis-2/处下载。感兴趣的同学可以自行学习,因为还有一些iBatis2的遗留项目需要维护。

MyBatis3可以从https://https://www.wendangku.net/doc/727086311.html,/mybatis/mybatis-3网址下载,本课程使用MyBatis-3.3.1版本。

创建Web Project,如图1.4.1所示。图中显示了需要用到的其他库文件。

图1.4.1 具有MyBatis库的项目结构

【案例实现】

步骤1,以SCOTT模式登录Oracle数据库,新建会员表(T_BIZ_MEMBERS)并添加测试数据,SQL脚本如代码1.4.1所示。

CREATE TABLE T_BIZ_MEMBERS (

UCODE VARCHAR2(32) DEFAULT SYS_GUID() NOT NULL , -- 会员编号

NICK_NAME VARCHAR2(40) NOT NULL , -- 昵称

REAL_NAME VARCHAR2(100) NULL , -- 真实姓名

EMAIL VARCHAR2(200) NULL , -- 电子邮件

CDATE DATE NULL , -- 创建日期

LDATE DATE NULL , -- 最近修改日期

PRIMARY KEY (UCODE) -- 主键

);

INSERT INTO T_BIZ_MEMBERS (UCODE,NICK_NAME,REAL_NAME)

VALUES(SYS_GUID(),'TOM','无敌风火轮');

INSERT INTO T_BIZ_MEMBERS (UCODE,NICK_NAME,REAL_NAME)

VALUES(SYS_GUID(),'JERRY','芭蕉扇公主');

INSERT INTO T_BIZ_MEMBERS (UCODE,NICK_NAME,REAL_NAME)

VALUES(SYS_GUID(),'JACK','通天金箍棒');

COMMIT;

代码1.4.1 会员表SQL脚本

步骤2,在项目源代码目录src中新建mybatis-config.xml配置文件,内容如代码1.4.2所示。需要根据自己Oracle实例名称修改URL部分。

PUBLIC "-//https://www.wendangku.net/doc/727086311.html,//DTD Config 3.0//EN"

"https://www.wendangku.net/doc/727086311.html,/dtd/mybatis-3-config.dtd">

value="jdbc:oracle:thin:@localhost:1521:orcl" />

代码1.4.2 mybatis-config.xml配置文件内容

步骤3,新建包com.ysdit.mybatis3.dao,并在其中新建IMemberMapper接口,如代码1.4.3所示。

package com.ysdit.mybatis3.dao;

public interface IMemberMapper {

public int countAll();

}

代码1.4.3 IMemberMapper接口代码

步骤4,在com.ysdit.mybatis3.dao包中新建映射文件IMemberMapper.xml,内容如代码1.4.4所示。

PUBLIC "-//https://www.wendangku.net/doc/727086311.html,//DTD Mapper 3.0//EN"

"https://www.wendangku.net/doc/727086311.html,/dtd/mybatis-3-mapper.dtd">

代码1.4.4 IMemberMapper.xml接口映射文件

步骤5,新建测试类MemberMapperTest,如代码1.4.5所示。

/*省略package和import代码*/

public class MemberMapperTest{

public static void main(String[] args) {

String configFile = "mybatis-config.xml";

InputStream in = null;

SqlSessionFactory sessionFactory = null;

SqlSession session = null;

try {

SqlSessionFactoryBuilder builder

= new SqlSessionFactoryBuilder();

in = Resources.getResourceAsStream(configFile);

sessionFactory = builder.build(in);

session = sessionFactory.openSession();

IMemberDao memberDao = session.getMapper(IMemberDao.class);

int totalMembers = memberDao.countAll();

System.out.println ("会员总数:" + totalMembers);

} catch (Exception e) {

e.printStackTrace();

}finally{

session.close();

}

}

}

代码1.4.5 MemberMapperTest测试代码

步骤6,执行MemberMapperTest测试类,如果得到输出结果“会员总数:3”,说明整个MyBatis开发环境搭建成功了。

简单来说,MyBatis执行原理图1.4.2所示。SqlSessionFactoryBuilder会读取配置文件,SqlSession会根据映射文件信息来操作数据库。

图1.4.2 MyBatis执行原理图

1.5 配置事务管理器和数据源

在实际的项目开发中,数据操作是离不开事务的,否则数据的完整性和一致性都无法得到保证。因此,任何一款数据访问产品都需要提供事务管理的功能。MyBatis的事务管理策略分为JDBC和MANAGED两种。

数据库连接是属于稀缺资源,在计算机软件设计领域中,稀缺资源很多时候都会使用池化技术来进行有效管理,从而提高资源的使用效率。数据源即是数据库连接池,用来提高数据库连接的使用效率。在Java开发领域中,有许多成熟的数据源开源产品,例如ASF的DBCP、阿里巴巴的Druid等。作为数据访问产品,MyBatis提供了灵活的数据源类型。

MyBatis框架通过mybatis-config.xml框架配置文件,能够对数据源和事务管理进行配置。

【准备工作】

MyBatis关于事务管理和数据源的配置如代码1.5.1加粗部分所示。

value="jdbc:oracle:thin:@localhost:1521:orcl" />

代码1.5.1配置数据源

【工作原理】

transactionManager的类型有JDBC、MANAGED两种。

对于应用系统中只有一个数据源(数据库)来说,事务管理器可以采用JDBC 类型,事务管理交由数据库自身来处理。如果应用系统涉及多个数据源,例如在互联网系统中,往往存在数据库集群的情况,那么事务管理器类型应该取MANAGED

类型,此时事务交由中间件服务器来调度处理。

◆dataSource的类型有UNPOOLED、POOLED、JNDI三种。

数据源的核心是数据库连接池,数据库连接对象池化的目的是提高系统效率。

连接池能够对属于稀缺资源的数据库连接进行统一管理,包括对连接对象的初始化、新增、释放等操作。

UNPOOLED类型说明数据库连接对象不采用池化技术,每次数据库会话操作都需要新建和关闭数据库连接,实际应用中不采用这种方式。UNPOOLED是工厂类org.apache.ibatis.datasource.unpooled.UnpooledDataSourceFactory的别名。

POOLED类型则是采用数据库连接池,MyBatis框架自身提供了一个数据源实现。如果需要替换成其他数据源产品,可以通过改变元素type属性的值,取值一个实现了DataSourceFactory接口的工厂类即可。POOLED是工程类org.apache.ibatis.datasource.pooled.PooledDataSourceFactory 的别名。

JNDI类型指的是,数据库连接池不由MyBatis来控制管理,交给中间件服务器(例如Tomcat)来管理。MyBatis通过JNDI名字从中间件服务器中获得数据库连接对象。JNDI是工厂类org.apache.ibatis.datasource.jndi.JndiDataSourceFactory的别名。

【扩展描述】

当dataSource的类型是POOLED时,还额外有以下常用属性。

poolMaximumActiveConnections,连接池最大活动连接数,默认值10

poolMaximumIdleConnections,连接池最大闲置连接数

poolMaximumCheckoutTime,连接“离开”连接池的最大时间,默认20秒

1.6 映射文件的结构

在mybatis-config.xml配置文件中,主要是对整个MyBatis框架的环境设置,比如上一节讲的事务管理器和数据源,另外后面要学到的延迟加载、类型别名等等。对SQL语句执行结果和实体数据的映射关系是单独的映射文件来配置的。映射文件宏观结构如代码1.6.1所示。

代码1.6.1 接口映射文件结构

【工作原理】

映射文件中,根元素是元素,它有一个namespace属性,用来管理SQL映射语句的名称,在同一个名字空间中,映射语句是不能重名的。namespace 属性的取值需要是接口的全限定名。

MyBatis框架的核心功能就在于SQL语句的映射。一个典型的SQL映射语句如下图1.6.1所示。

图1.6.1 SQL语句结构图

SQL映射语句的输入一般存在WHERE子句的条件中,用#{}符号表示,实际上就是一个占位符。语句输出一般是SELECT子句。映射语句并不是必须有输入和输出部分。如果SELECT语句不带WHERE子句的话,就是没有输入。如果语句是更新类型的,一般都没有输出部分。

为了区分SQL语句的语义,MyBatis提供了