小白学mybatis-笔记

Mybatis 是⼀个半 ORM (对象关系映射)框架,它内部封装了 JDBC ,开发时只需要关注
SQL 语句本⾝,不需要花费精⼒去处理加载驱动、创建连接、创建 statement 等繁杂的过
程。程序员直接编写原⽣态 sql ,可以严格控制 sql 执⾏性能,灵活度⾼。
MyBatis 可以使⽤ XML 或注解来配置和映射原⽣信息,将 POJO 映射成数据库中的记
录,避免了⼏乎所有的 JDBC 代码和⼿动设置参数以及获取结果集。
再说⼀下缺点
SQL 语句的编写⼯作量较⼤,尤其当字段多、关联表多时,对开发⼈员编写 SQL 语句的功
底有⼀定要求
SQL 语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
 
为什么说 Mybatis 是半⾃动 ORM 映射⼯具?它与全⾃动的区别在哪⾥?
Hibernate 属于全⾃动 ORM 映射⼯具,使⽤ Hibernate 查询关联对象或者关联集合对象时,
可以根据对象关系模型直接获取,所以它是全⾃动的。
Mybatis 在查询关联对象或关联集合对象时,需要⼿动编写 SQL 来完成,所以,被称之
为半⾃动 ORM 映射⼯具。

1 、数据连接创建、释放频繁造成系统资源浪费从⽽影响系统性能
解决:在 mybatis-config.xml 中配置数据链接池,使⽤连接池统⼀管理数据库连接。
2 sql 语句写在代码中造成代码不易维护
解决:将 sql 语句配置在 XXXXmapper.xml ⽂件中与 java 代码分离。
3 、向 sql 语句传参数⿇烦,因为 sql 语句的 where 条件不⼀定,可能多也可能少,占位符需
要和参数⼀⼀对应。
解决: Mybatis ⾃动将 java 对象映射⾄ sql 语句。
4 、对结果集解析⿇烦, sql 变化导致解析代码变化,且解析前需要遍历,如果能将数据库
记录封装成 pojo 对象解析⽐较⽅便。
解决: Mybatis ⾃动将 sql 执⾏结果映射⾄ java 对象。

1 、 创建 SqlSessionFactory
可以从配置或者直接编码来创建 SqlSessionFactory
String resource = "org/mybatis/example/mybatis-config.xml" ;
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
2 、 通过 SqlSessionFactory 创建 SqlSession
SqlSession (会话)可以理解为程序和数据库之间的桥梁
SqlSession session = sqlSessionFactory.openSession();
3 、 通过 sqlsession 执⾏数据库操作
可以通过 SqlSession 实例来直接执⾏已映射的 SQL 语句:
Blog blog =
( Blog ) session . selectOne ( "org.mybatis.example.BlogMapper.selectBlog" ,
101 );
更常⽤的⽅式是先获取 Mapper( 映射 ) ,然后再执⾏ SQL 语句:
BlogMapper mapper = session . getMapper ( BlogMapper . class );
Blog blog = mapper . selectBlog ( 101 );
4 、 调⽤ session.commit() 提交事务
如果是更新、删除语句,我们还需要提交⼀下事务。
5 、 调⽤ session.close() 关闭会话
最后⼀定要记得关闭会话。

当然,万物皆可集成 Spring MyBatis 通常也是和 Spring 集成使⽤, Spring 可以帮助我们创建线
程安全的、基于事务的 SqlSession 和映射器,并将它们直接注⼊到我们的 bean 中,我们不需
要关⼼它们的创建过程和⽣命周期,那就是另外的故事了。

 

第⼀种⽅法:使⽤ foreach 标签
foreach 的主要⽤在构建 in 条件中,它可以在 SQL 语句中进⾏迭代⼀个集合。 foreach 标签的属性
主要有 item index collection open separator close
item   表⽰集合中每⼀个元素进⾏迭代时的别名,随便起的变量名;
index   指定⼀个名字,⽤于表⽰在迭代过程中,每次迭代到的位置,不常⽤;
open   表⽰该语句以什么开始,常⽤ “(”
separator 表⽰在每次进⾏迭代之间以什么符号作为分隔符,常⽤ “,”
close   表⽰以什么结束,常⽤ “)”
在使⽤ foreach 的时候最关键的也是最容易出错的就是 collection 属性,该属性是必须指定的,
但是在不同情况下,该属性的值是不⼀样的,主要有以下 3 种情况:
1. 如果传⼊的是单参数且参数类型是⼀个 List 的时候, collection 属性值为 list
2. 如果传⼊的是单参数且参数类型是⼀个 array 数组的时候, collection 的属性值为 array
3. 如果传⼊的参数是多个的时候,我们就需要把它们封装成⼀个 Map 了,当然单参数也可以
封装成 map ,实际上如果你在传⼊参数的时候,在 MyBatis ⾥⾯也是会把它封装成⼀个 Map
的,
map key 就是参数名,所以这个时候 collection 属性值就是传⼊的 List array 对象在⾃⼰封
装的 map ⾥⾯的 key

获取配置
获取配置这⼀步经过了⼏步转化,最终由⽣成了⼀个配置类 Configuration 实例,这个配置
类实例⾮常重要,主要作⽤包括:
读取配置⽂件,包括基础配置⽂件和映射⽂件
初始化基础配置,⽐如 MyBatis 的别名,还有其它的⼀些重要的类对象,像插件、映射
器、 ObjectFactory 等等
提供⼀个单例,作为会话⼯⼚构建的重要参数
它的构建过程也会初始化⼀些环境变量,⽐如数据源

会话运⾏
会话运⾏是 MyBatis 最复杂的部分,它的运⾏离不开四⼤组件的配合:

 

1. 读取 MyBatis 配置⽂件 ——mybatis-config.xml 、加载映射⽂件 —— 映射⽂件即 SQL 映射
⽂件,⽂件中配置了操作数据库的 SQL 语句。最后⽣成⼀个配置对象。
2. 构造会话⼯⼚:通过 MyBatis 的环境等配置信息构建会话⼯⼚ SqlSessionFactory
3. 创建会话对象:由会话⼯⼚创建 SqlSession 对象,该对象中包含了执⾏ SQL 语句的所有
⽅法。
4. Executor 执⾏器: MyBatis 底层定义了⼀个 Executor 接⼜来操作数据库,它将根据
SqlSession 传递的参数动态地⽣成需要执⾏的 SQL 语句,同时负责查询缓存的维护。
5. StatementHandler :数据库会话器,串联起参数映射的处理和运⾏结果映射的处理。
6. 参数处理:对输⼊参数的类型进⾏处理,并预编译。
7. 结果处理:对返回结果的类型进⾏处理,根据对象映射规则,返回相应的对象。

 

我们⼀般把 Mybatis 的功能架构分为三层:
API 接⼜层:提供给外部使⽤的接⼜ API ,开发⼈员通过这些本地 API 来操纵数据库。接⼜
层⼀接收到调⽤请求就会调⽤数据处理层来完成具体的数据处理。
数据处理层:负责具体的 SQL 查找、 SQL 解析、 SQL 执⾏和执⾏结果映射处理等。它主要
的⽬的是根据调⽤的请求完成⼀次数据库操作。
基础⽀撑层:负责最基础的功能⽀撑,包括连接管理、事务管理、配置加载和缓存处理,
这些都是共⽤的东西,将他们抽取出来作为最基础的组件。为上层的数据处理层提供最基
础的⽀撑。

 

 

 

 

 

 

如何编写⼀个插件?
我们⾃⼰编写 MyBatis 插件,只需要实现拦截器接⼜ Interceptor (org.apache.ibatis. plugin
Interceptor ),在实现类中对拦截对象和⽅法进⾏处理。
实现 Mybatis Interceptor 接⼜并重写 intercept() ⽅法
这⾥我们只是在⽬标对象执⾏⽬标⽅法的前后进⾏了打印;

 

public class MyInterceptor implements Interceptor {
Properties props = null ;
@Override
public Object intercept ( Invocation invocation ) throws Throwable {
System . out . println ( "before……" );
// 如果当前代理的是⼀个⾮代理对象,那么就会调⽤真实拦截对象的⽅法
// 如果不是它就会调⽤下个插件代理对象的 invoke ⽅法
Object obj = invocation . proceed ();
System . out . println ( "after……" );
return obj ;
}
}

然后再给插件编写注解,确定要拦截的对象,要拦截的⽅法
@Intercepts ({ @Signature (
type = Executor . class , // 确定要拦截的对象
method = "update" , // 确定要拦截的⽅法
args = { MappedStatement . class , Object . class } // 拦截⽅法的参数
)})
public class MyInterceptor implements Interceptor {
Properties props = null ;
@Override
public Object intercept ( Invocation invocation ) throws Throwable {
System . out . println ( "before……" );
// 如果当前代理的是⼀个⾮代理对象,那么就会调⽤真实拦截对象的⽅法
// 如果不是它就会调⽤下个插件代理对象的 invoke ⽅法
Object obj = invocation . proceed ();
System . out . println ( "after……" );
return obj ;
}
}

20.MyBatis 是如何进⾏分页的?分页插件的原理是什么?
MyBatis 是如何分页的?
MyBatis 使⽤ RowBounds 对象进⾏分页,它是针对 ResultSet 结果集执⾏的内存分页,⽽⾮物理
分页。可以在 sql 内直接书写带有物理分页的参数来完成物理分页功能,也可以使⽤分页插件
来完成物理分页。
分页插件的原理是什么?
分页插件的基本原理是使⽤ Mybatis 提供的插件接⼜,实现⾃定义插件,拦截 Executor
query ⽅法
在执⾏查询的时候,拦截待执⾏的 sql ,然后重写 sql ,根据 dialect ⽅⾔,添加对应的物理分
页语句和物理分页参数。
举例: select * from student ,拦截 sql 后重写为: select t.* from (select * from student) t limit
0, 10
可以看⼀下⼀个⼤概的 MyBatis 通⽤分页拦截器:

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值