MyBatis框架第一天
【MyBatis:优秀的持久层框架_第一天】
主要内容
- 框架
- ORM
- MyBatis和Hibernate比较
- 搭建MyBatis环境
- 配置文件
- 映射文件
- 核心API
- 使用log4j记录日志
学习目标
|
知识点 |
要求 |
|
框架 |
理解 |
|
ORM |
理解 |
|
MyBatis和Hibernate比较 |
了解 |
|
搭建MyBatis环境 |
掌握 |
|
配置文件 |
掌握 |
|
映射文件 |
掌握 |
|
核心API |
掌握 |
|
使用log4j记录日志 |
掌握 |
1 MyBatis入门
1.1 认识框架
框架(Framework):是一个框子——指其约束性,也是一个架子——指其支撑性。是一个基本概念上的结构,用于去解决或者处理复杂的问题。框架这个广泛的定义使用的十分流行,尤其在软件概念。
框架( Framework )是构成一类特定软件可复用设计的一组相互协作的类。
简单来说,框架其实就是别人写好的一些通用性的、功能强大、可靠的代码,我们直接使用即可,不需要再去重复的写一些基础性、繁琐的操作代码!
使用框架的好处:
- 减少开发时间、降低开发难度,并且还保证设计质量
- 可以降低程序员之间沟通以及日后维护的成本
常用的基于JavaEE的三大开源框架,已经从SSH过渡到了SSM:SpringMVC、Spring、MyBatis。
总之,框架是一个半成品,已经对基础的代码进行了封装并提供相应的API,开发者在使用框架是直接调用封装好的API可以省去很多代码编写,从而提高工作效率和开发速度。
1.2 认识MyBatis框架
MyBatis 本是Apache的一个开源项目iBatis, 2010年这个项目由Apache Software Foundation 迁移到了Google Code,且改名为MyBatis 。2013年11月迁移到GitHub。iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。
- MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。
- MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。
- MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
- MyBatis是一个半自动ORM框架,其本质是对JDBC的封装。使用MyBatis重点需要程序员编写SQL命令,不需要写一行JDBC代码。
1.3 认识ORM
使用JDBC的时候,我们需要手动的完成面向对象的Java语言、面向关系的数据库之间数据的转换,代码繁琐无技术含量,影响了开发效率。
如图所示,查询是需要手动的将结果集的列数据转换为Java对象的属性;而添加操作时需要手动将Java对象的属性转换为数据库表的列字段。
ORM,Object-Relationl Mapping,对象关系映射,它的作用是在关系型数据库和对象之间作一个映射,这样我们在具体的操作数据库的时候,只要像平时操作对象一样操作它就可以了,ORM框架会根据映射完成对数据库的操作。
1.4 持久化、持久层
什么是“持久化”
持久(Persistence),即把数据(如内存中的对象)保存到可永久保存的存储设备中(如磁盘)。持久化的主要应用是将内存中的数据存储在关系型的数据库中,当然也可以存储在磁盘文件中、XML数据文件中等等。
什么是 “持久层”
持久层(Persistence Layer),即专注于实现数据持久化应用领域的某个特定系统的一个逻辑层面,将数据使用者和数据实体相关联。之前使用JDBC访问数据库的DAO层,后面采用MyBatis访问数据库的mapper层,就是持久层。
层其实就是java中的package(dao、mapper)
1.5 和Hibernate的比较
Hibernate是一个全自动的ORM框架。因为Hibernate创建了Java对象和数据库表之间的完整映射,可以完全以面向对象的思想来操作数据库,程序员不需要手写SQL语句,而MyBatis中还需要手写SQL语句,所以是半自动化的,工作量要大于Hibernate。
为什么半自动化的Mybatis比自动化的Hibernate受欢迎?
MyBatis需要手写SQL语句,所以工作量要大于Hibernate。但是也正是由于自定义SQL语句,所以其灵活性、可优化性就超过了Hibernate。
Hibernate封装了SQL语句,由开发者对对象操作,Hibernate来生成SQL语句。虽然也可以通过映射配置来控制生成的SQL语句,但是对于要生成复杂的SQL语句,很难实现,或者实现后导致性能的丢失。
而MyBatis将手写SQL语句的工作丢给开发者,可以更加精确的定义SQL,更加灵活,也便于优化性能。完成同样功能的两条SQL语句的性能可能相差十几倍到几十倍,在高并发、快响应要求下的互联网系统中,对性能的影响更明显。
MyBatis对存储过程可提供很好的支持。另外MyBatis的开发工作量大不意味着学习成本大。对于新手,学习Hibernate时间成本比Mybatis大很多,Mybatis很快就上手了。
总之,因为MyBatis具有封装少、映射多样化、支持存储过程、可以进行SQL语句优化等特点,符合互联网高并发、大数据、高性能、高响应的要求,使它取代Hibernate成为了Java互联网中首选的持久框架。而对于对性能要求不高的比如内部管理系统、ERP等可以使用Hibernate。
1.6 小结
- 框架就是对一些通用的功能进行了封装,我们学习框架就是学习框架的API方法的使用
- Mybatis是一款优秀的持久层框架,ORM框架,支持定制化的SQL、存储过程及高级映射
- ORM就是对象关系映射,也就是Java中的一个对象与关系型数据库中的一条记录对应起来
- 持久化就是将数据永久的保存下来,持久层就是操作数据库的层(dao、mapper)
- Mybatis框架(半自动)要优于Hibernate框架(全自动),它比Hibernate更加灵活,主要是它的SQL由我们自己编写的
1.7 使用框架的步骤
一般使用框架就三个步骤:
- 导入框架的jar包
- 编写框架的配置文件
- 编写代码
2 MyBatis快速上手
2.1 环境搭建
2.1.1 创建数据库表
2.1.2 编写log4j配置文件
在src目录下编写log4j的配置文件,名字必须是log4j.properties。
在其中可以将全局的日志级别调高,避免大量debug信息的干扰。同时将对映射文件的操作调低,可以用来显示SQL语句的调试信息。开发阶段,建议启动控制台的日志。
日志级别常用的有:debug、info、warn、error,日志框架会将大于等于当前日志级别的日志打出来!
log4j.rootLogger=error,stdout,logfile |
2.1.3 创建项目导入相关jar包
2.1.4 编写mybatis配置文件
在src目录下编写mybatis的配置文件。名字可以随便起,最好是mybatis-config.xml。
<?xml version="1.0" encoding="UTF-8" ?> <settings>
|
注意:数据库四个连接参数的name属性的值来自org.apache.ibatis.datasource.unpooled包下类UnpooledDataSource。
以后在实际开发中,我们也不会让mybatis帮我们管理数据源,管理事务。
数据源要涉及到连接池,以后我们用的是阿里的连接池管理数据源。Druid。(当然了,还有别的c3p0、追光者!)
事务以后让Spring框架来管理。
2.2 查询案例1
2.2.1 需求
查询所有的用户信息。
2.2.2 编写pojo类
2.2.3 编写mapper映射文件
创建一个mapper包,在这个包中编写mapper映射文件。2.2.3 编写mapper映射文件
MyBatis的主要工作就是进行映射,甚至可以占到全部工作量的80%以上。
MyBatis的映射可以通过XML和注解来实现。面对复杂的SQL语句,注解也会力不从心。所以MyBaits中更多使用XML配置来实现。
此处创建映射文件UserMapper.xml,和实体类User对应。
定义好映射文件后,需要在mybatis配置文件指明映射文件的位置。
<?xml version="1.0" encoding="UTF-8" ?> |
注意事项:
- id要求唯一
- paramterType参数类型,可以省略。如果提供该参数,必须书写正确类型。MyBatis可以通过类型处理器(TypeHandler)推断出具体传入语句的参数。parameterType取值只能是一个类型,相当于方法参数只能是一个参数(类型不限),局限性比较大。后续开发中都省略此参数。
- resultType 返回值类型
a) 返回值是集合,resultType取值为集合的元素泛型类型的完整路径名
b) 返回值是对象,resultType取值为对应类的完整路径名
- 关于方法参数传递
a) 参数是基本数据类型,使用#{param1}来接收数据(其实可以是任意名称)
b) 参数是引用数据类型,使用#{属性名}接收数据,底层调用的是其getter方法。如果没有getter方法,就会直接找同名属性。
- 初学者最直观感受是mapper.xml是编写SQL命令的文件,实际上这个文件相当分层开发中dao.impl下的数据访问层实现类(也可以说MyBatis一个好处就是不用写DAO实现类了)。也就是说MyBatis会把mapper.xml文件解析成一个类。
测试类中利用SqlSession直接来发送SQL命令给MySQL服务器。常用方法有selectList()、selectOne()等。MyBatis API的具体作用在后面进行详细说明。
2.2.4 编写测试类
public class MybatisTest {
|
MyBatis是如何把数据库查询结果中字段的值赋给Java中实体类的对应属性呢?这用到了自动映射技术。
Auto Mapping(结果自动映射)是MyBatis提供的按照名称自动把结果集中数据映射到对象属性的一种技术。查询到结果集后按照名称去类中找属性的set方法进行赋值。在新版本中如果属性没有提供set方法,则直接找同名属性进行赋值.
那如果数据库字段和实体类属性不一致呢?肯定是赋不上值的!如果出现这种情况,我们可以在查询的SQL语句中给不一样的字段起别名,让别名和属性名一致即可!
2.3 查询案例2
2.3.1 需求
根据id查询用户信息。
2.3.2 编写mapper映射文件
<!-- |
2.3.3 编写测试类方法
@Test |
2.4 查询案例3
2.4.1 需求
根据性别和年龄查询用户信息。
2.4.2 编写mapper映射文件
<!--根据性别和年龄查询用户--> |
2.4.3 编写测试类方法
@Test |
2.5 删除案例
2.5.1 需求
删除id=3的用户数据
2.5.2 编写mapper映射文件
<!--根据id删除信息--> |
注意事项:
1) DML操作的底层调用是executeUpdate(),返回值都是int类型,不需要提供,也没有resultType属性来指定。
2) 其实insert、update、delete任何一个元素都可以完成所有DML操作的映射
在测试类中完成对User表的DML操作,涉及事务的手动和自动提交。
2.5.3 编写测试类方法
@Test |
注意事项:
1) 执行DML操作,默认事务手动提交。此时可以两种方案解决
a. 使用自动提交
b. 手动执行commit ()或者rollback()结束事务
推荐手动提交事务。因为复杂业务中一个事务会包括多个DML操作,自动提交只能做到一个事务只有一个DML操作。
2) 其实一个SqlSession的update、delete、insert中任意一个方法均可完成所有DML操作。底层都是调用的update方法,就好比JDBC中的executeUpdate()可以完成DML操作一样。
2.6 添加案例
2.6.1 需求
添加一条用户信息
2.6.2 编写mapper映射文件
<insert id="addUser"> |
2.6.3 编写测试类方法
@Test |
2.7 修改案例
2.7.1 需求
修改id=1的数据。
2.7.2 编写mapper映射文件
<update id="updateUser"> |
2.7.3 编写测试类方法
@Test |
3 MyBatis功能详解
3.1 关于核心API
l SqlSessionFactoryBuilder
根据配置或者代码生成SqlSessionFactory,采用的是分步构建的构建者模式。
l SqlSessionFactory
生产SqlSession,使用的是工厂模式
l SqlSession
可获取Mapper的接口,相当于Connection,也可以发送SQL语句并返回结果。
和Connection一样也是线程不安全的,不能被共享使用!
l Mapper
映射器。由一个Java接口和XML文件(或者注解构成),需要给出对应的SQL和映射规则,负责发送SQL去执行并返回结果。
生命周期
l SqlSessionFactoryBuilder:
该类用来创建SqlSessionFactory对象,当SqlSessionFactory对象被创建后,该对象也就没有存在的必要了。
l SqlSessionFactory:
该对象应该在你的应用执行期间一直存在,由于要从该对象中获取SqlSession对象,这样的操作会相当频繁,同时创建SqlSessionFactory对象是一件非常消耗资源的事,因此,该对象应该与当前应用具有相同生命周期。
工厂在整个应用程序中有一份就行了!!!
l SqlSession:
每个线程都应该有自己的SqlSession实例,SqlSession实例不能被共享,是线程不安全的,因此最佳的范围是请求或方法范围。
l Mapper
关闭SqlSessin的时候也就关闭了由其所产生的Mapper。
3.2 关于配置文件
l transactionManager
在 MyBatis 中有两种事务管理器类型(也就是 type=“[JDBC|MANAGED]”):
- JDBC – 这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。
- MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如 Spring 或 JEE 应用服务器的上下文) 。
- 在MyBatis核心包中可以看到两种事务管理器类型的相关类。
l dataSource
有三种内建的数据源类型(也就是 type=“xxx”):
- UNPOOLED – 这个数据源的实现是每次被请求时简单打开和关闭连接。它有一点慢, 这是对简单应用程序的一个很好的选择, 因为它不需要及时的可用连接。UNPOOLED 类型的数据源仅仅需要配置以下 5 种属性:
driver – 这是 JDBC 驱动的 Java 类的完全限定名。
url – 这是数据库的 JDBC URL 地址。
username – 登录数据库的用户名。
password – 登录数据库的密码。
defaultTransactionIsolationLevel – 默认的连接事务隔离级别。
- POOLED – 这是 JDBC 连接对象的数据源连接池的实现,用来避免创建新的连接实例时必要的初始连接和认证时间。一种当前 Web 应用程序用来快速响应请求很流行的方法。 除了上述提到 UNPOOLED 下的属性外,还有更多属性用来配置 POOLED 的数据源:
poolMaximumActiveConnections – 在任意时间可以存在的活动(也就是正在使用)连接数量,默认值:10
poolMaximumIdleConnections – 任意时间可能存在的空闲连接数。
poolMaximumCheckoutTime – 在被强制返回之前,池中连接被检出(checked out)时间,默认值:20000 毫秒(即 20 秒)
poolTimeToWait – 这是一个底层设置,如果获取连接花费了相当长的时间,连接池会打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直安静的失败),默认值:20000 毫秒(即 20 秒)。
poolMaximumLocalBadConnectionTolerance – 这是一个关于坏连接容忍度的底层设置,作用于每一个尝试从缓存池获取连接的线程。如果这个线程获取到的是一个坏的连接,那么这个数据源允许这个线程尝试重新获取一个新连接,但这个重新尝试次数不应超过poolMaximumIdleConnections 与 poolMaximumLocalBadConnectionTolerance 之和。 默认值:3 (新增于 3.4.5)
poolPingQuery – 发送到数据库的侦测查询,用来检验连接是否正常工作并准备接受请求。默认是“NO PING QUERY SET”,这会导致多数数据库驱动失败时带有一个恰当的错误消息。
poolPingEnabled – 是否启用侦测查询。若开启,需要设置 poolPingQuery 属性为一个可执行的 SQL 语句(最好是一个速度非常快的 SQL 语句),默认值:false。
poolPingConnectionsNotUsedFor – 配置 poolPingQuery 的频率。可以被设置为和数据库连接超时时间一样,来避免不必要的侦测,默认值:0(即所有连接每一时刻都被侦测 — 当然仅当 poolPingEnabled 为 true 时适用)。
- JNDI – 这个数据源实现是为了使用如 Spring 或应用服务器这类容器, 容器可集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。这个数据源配置只需要两个属性。
initial_context – 这个属性用来在 InitialContext 中寻找上下文(即,initialContext.lookup(initial_context))。这是个可选属性,如果忽略,那么将会直接从 InitialContext 中寻找 data_source 属性。
data_source – 这是引用数据源实例位置的上下文的路径。提供了 initial_context 配置时会在其返回的上下文中进行查找,没有提供时则直接在 InitialContext 中查找。
在MyBatis核心包中可以看到三种内置数据源类型的相关类。
说明:在实际开发中,我们不会使用mybatis框架自带的数据库连接池来管理连接,而是使用阿里的Druid或者c3p0或者其他专业的连接池!
l mappers
也就是在mybatis的配置文件中注册SQL映射文件,即告诉了 MyBatis 去哪里找映射文件。
<!--注册mapper映射文件--> |
推荐使用第四种方式,但是前提是一定要显式的提供相应的接口定义,且要求接口名和mapper.xml文件名必须完全相同。目前没有定义接口,无法使用该方式。
3.3 关于日志管理
Mybatis 的内置日志工厂(LogFactory)提供日志功能,内置日志工厂将日志交给以下其中一种工具作代理:
- SLF4J
- Apache Commons Logging
- Log4j 2
- Log4j
- JDK logging
- NO_LOGGING
MyBatis 内置日志工厂基于运行时自省机制选择合适的日志工具。它会使用第一个查找得到的工具(按上文列举的顺序查找)。如果一个都未找到,日志功能就会被禁用。也就是说在项目中把日志工具环境配置出来后,不用再MyBatis进行配置就可以让日志生效。
一般我们使用log4j来做日志管理的工具。如果项目中有多个日志管理工具的话,也可以指定让mybatis使用哪种作为日志工具。
<settings> |
4 MyBatis配置完善
4.1 使用别名alias
类型别名是为 Java 类型命名一个短的名字。它只和 XML 配置有关, 只用来减少类完全限定名的多余部分。注意:别名都是大小写不敏感的。
在配置文件中为类的完整路径定义别名,可以采用两种方式
方式1:使用typeAlias指定单个类的别名
方式2:使用package指定某个包下所有类的默认别名
<typeAliases> |
使用别名后,映射文件:
<select id="getUsers" resultType="user"> |
对于普通的 Java 类型,有许多内建的类型别名。
|
别名 |
映射的类型 |
|
别名 |
映射的类型 |
|
别名 |
映射的类型 |
|
_byte |
byte |
|
string |
String |
|
date |
Date |
|
_long |
long |
|
byte |
Byte |
|
decimal |
BigDecimal |
|
_short |
short |
|
long |
Long |
|
bigdecimal |
BigDecimal |
|
_int |
int |
|
short |
Short |
|
object |
Object |
|
_integer |
int |
|
int |
Integer |
|
map |
Map |
|
_double |
double |
|
integer |
Integer |
|
hashmap |
HashMap |
|
_float |
float |
|
double |
Double |
|
list |
List |
|
_boolean |
boolean |
|
float |
Float |
|
arraylist |
ArrayList |
|
|
|
|
boolean |
Boolean |
|
collection |
Collection |
|
|
|
|
|
|
|
iterator |
Iterator |
其实这些系统内置的别名设置都是在org.apache.ibatis.type.TypeAliasRegistry类中指定并注册的。
另外在org.apache.ibatis.session.Configuration的无参数构造方法中有更多的别名设置,是否在其中也发现了我们所熟悉的别名呀,比如JDBC、POOLED、LOG4J。
4.2 引入属性文件
将数据库的四个连接参数放入属性文件,更便于修改维护。此时需要在配置文件中指定属性文件的位置,并给四个连接属性赋值。
jdbc.properties文件:
driver=com.mysql.cj.jdbc.Driver |
mybatis配置文件:
<!--引入外部的配置文件--> <environments default="development"> |
4.3 提供工具类复用代码
定义MyBatisUtil工具类,封装获取SqlSession和关闭SqlSession的操作。
public class MyBatisUtil {
|
@Test |
4.4 idea使用技巧:引入本地DTD文件(eclipse)
在没有联网的情况下,让dtd约束继续起作用,并且出现标签提示,可以通过引入本地dtd文件来实现。
1. 下载dtd:在浏览器中输入dtd的网络地址即可实现下载。比如:http://mybatis.org/dtd/mybatis-3-config.dtd
2. 将下载的dtd拷贝到本地的一个目录下
3. Idea操作路径:File---Settings---Languages & Frameworks
其中URI 复制dtd的网络地址即可。File选择dtd文件在本地的地址。OK!
注:在MyBatis的核心jar包中就提供了mybatis-3-config.dtd
4.5 idea使用技巧:创建文件模板
idea提供了大量的内置文件模板template,可以自定义模板,避免重复,提高效率。
创建入口1:右键----new----Edit file Templates
创建入口2:File--settings---editor---File and Code Templates
使用入口:右键----new---- 选择模板名称
总结
MyBatis第一天内容总结:
1. 框架是什么? 框架就是别人开发好的一些代码(jar包),它就是将一些我们常用的、通用的
功能封装好了!我们直接将这些框架的jar包导入到项目中,就可以使用了!
学习框架,其实就是学习人家的API方法。
使用的框架的步骤: 导包、写配置文件、写自己的代码。
2. MyBatis框架?
就是一个优秀的持久层框架、开源的、ORM框架、半自动的。
支持定制化的SQL、存储过程、高级映射。
3. 持久层:我们开发项目是分层,分层也就是分为各个包去开发,每个包里面放不同功能的代码。
对于与数据库打交道的代码,我们放在持久层,之前我们用的dao包,
现在还有以后用的都是mapper包。
4. ORM:对象关系映射的意思,就是说java对象和数据库表记录要一一对应,正是因为myabtis有
ORM的特性,所有从数据库查询到的数据就直接帮我们封装为了一个java对象。
5. Hibernate:是一个优秀的全自动的ORM的持久层框架,用它不需要我们写SQL,这样就造成了
我们无法优化SQL。而实际工作中,我们是需要对SQL进行优化。
6. 入门案例:
1. 导入mybatis相关的jar包
2. 编写mybatis的配置文件(mybatis-config.xml),文件内容从官网的入门中复制
3. 编写映射文件(UserMapper.xml), 文件内容从官网的入门中复制
4. 测试方法。
读取mybatis配置文件
通过SqlSessionFactory构建器构建SqlSessionFactory
通过SqlSessionFactory创建一个SqlSession
7. 编写映射文件的时候,命名空间不要随便写,一般写的是 映射文件名这就行了,不要加后缀!
id唯一, resultType指定返回的结果类型,如果是List的话,要写泛型的类型全路径
编写完映射文件后,一定要在mybatis的配置文件中注册一下! 注意路径 不要写成 com.bjsxt
8. #{} 就是用来获取传递给SQL的参数的
如果参数是一个的话,#{}里面可以随便写
如果参数是一个对象的话,#{}里面写的是对象的属性名
#{}方式就相当于之前jdbc的预编译占位符的方式
9. 别名:我们可以给返回值类型起一个短点的别名, 在mybatis配置文件中通过
typeAliases标签来起。 可以使用 <package name=""/> 包的方式批量给某个包下的所有类
起别名,默认别名就是类名, 当然了别名是不区分大小写的
10. 我们可以将数据库的配置信息写在专门的属性文件中,然后在mybatis的配置文件中
通过properties标签引入这个文件,然后通过 ${键} 的方式获取值!
11. 日志的话,使用log4j。具体配置信息可以从官网复制。 如果不指定日志,mybatis会自动在
项目中找看我们有哪个日志的配置。
12. SqlSessionFactory是由SqlSessionFactoryBuilder构建出来的,一旦构建出来之后,
SqlSessionFactoryBuilder就销毁了。
SqlSessionFactory在整个应用程序中,只有一份。而且会一直存在!
SqlSession是线程不安全的,每次请求或每个方法都要独立的使用一个,不能共享,
由SqlSessionFactory来创建的。

浙公网安备 33010602011771号