<code>《“爱读书”--给你讲技术》,我来看书,你来进步,让我们开始吧!/<code>
本书简介
书名为《Spring+MyBatis企业应用实战》,是本人在学习JavaEE框架时候的一本基础书籍,本书对于SpringMVC和MyBatis框架及相关基础知识讲述的比较清晰,适合需要详细学习Java框架的读者。
本文内容为本书第八章--第十一章,记录和总结了所有MyBatis的知识
MyBatis开发步骤
1.导入MyBatis依赖的Jar包
2.创建持久化类
3.配置持久化类映射,即配置Mapper
4.配置MyBatis配置文件,即mybatis-config.xml
5.在程序中调用对应方法实现持久化操作
核心对象SqlSessionFactory和SqlSession
1.SqlSessionFactory
SqlSessionFactory是MyBatis的关键对象,它是单个数据库映射关系经过编译后的内存镜像。SqlSessionFactory的实例可以通过SqlSessionFactoryBuilder对象来获得,SqlSessionFactory是线程安全的, SqlSessionFactory一旦被创建,在应用执行期间都存在,不需要重复创。
SqlSessionFactory是创建SqlSession的工厂,创建方法如下:
<code>SqlSession openSession():创建SqlSession对象/<code>
2.SqlSession
SqlSession是执行持久化操作的对象,类似于JDBC中的Connection。它是应用程序与持久存储层之间执行交互操作的一个单线程对象。
SqlSession对象包含以数据库为背景的所有执行SQL操作的方法,它的底层封装了JDBC连接,可以用SqlSession实例来直接执行已映射的 SQL语句。
每个线程都应该有它自己的SqlSession实例,是线程不安全的。使用完SqlSession之后必须要关闭它。
SqlSession常用方法如下:
<code>int insert(String statement):插入方法,参数是Mapper中元素的id,返回执行的行数 int insert(String statement, Object parameter):插入方法,parameter是插入所需的参数 int update(String statement):更新方法,参数是Mapper中元素的id,返回执行的行数 int update(String statement, Object parameter):更新方法,parameter是更新所需的参数 int delete(String statement):删除方法,参数是Mapper中元素的id,返回执行的行数 int delete(String statement, object parameter):删除方法,parameter是删除所需的参数 T selectOne(String statement):查询方法,参数是Mapper中/<code>
MyBatis配置文件
1.MyBatis SqlSessionFactory初始化过程
(1)调用SqlSessionFactoryBuilder对象的build(inputStream)方法
(2)SqlSessionFactoryBuilder会根据输入流inputStream等信息创建XMLConfigBuilder对象
(3)SqlSessionFactoryBuilder调用XMLConfigBuilder对象的parse()方法
(4)XMLConfigBuilder对象解析XML配置文件返回Configuration对象
(5)SqlSessionFactoryBuilder根据Configuration对象创建一个DefaultSessionFactory对象
(6)SqlSessionFactoryBuilder返回DefaultSessionFactory对象给客户端使用
2.MyBatis配置文件属性
- 顶层configuration 配置
- properties 属性
- settings 设置
- typeAliases 类型命名
- typeHandlers 类型处理器
- objectFactory 对象工厂
- plugins 插件
- environments 环境
- environment 环境变量
- transactionManager 事务管理器
- dataSource 数据源
- databaseIdProvider 数据库厂商标识
- mappers 映射器
(1)properties
在classpath中增加db.properties属性文件
配置如下:
<code>/<code>
调用属性文件的值:
<code> /<code>
(2)setting
设置MyBatis运行时参数
配置如下:
<code> /<code>
参数包含如下:
(3)typeAliases
类型别名是为Java类型设置的一个短的名字。它只和XML配置有关,仅用来减少类完全限定名的冗余。
<code> /<code>
MyBatis内建了java类型的别名如下:
(4)typeHandlers
类型处理器将获取的值以合适的方式转换成Java类型
(5)objectFactory
MyBatis每次创建新实例时,都会使用一个对象工厂。如何想覆盖对象工厂的默认行为,可以通过创建自己的对象工厂来实现,继承并重写DefaultObjectFactory。配置如下:
<code> /<code>
(6)environments
environments配置就是数据源的配置。每个SqlSessionFactory实例只能选择一个环境,即每个数据库对应一个SqlSessionFactory实例。
配置方式如下:
(1)要配置默认的环境id
(2)每个environment要定义环境id
(3)需要配置事务管理器,包括JDBC和MANAGED
(4)需要配置数据源,包括POOLED、UNPOOLED、JNDI
(7)mapper
mapper映射器告诉MapBatis去哪里找映射文件。可以使用相对于类路径的引用、全限定资源定位符或类名包名等。配置如下:
<code> /<code>
MyBatis日志信息配置
配置日志实现方式
<code> /<code>
配置mapper接口所对应的日志级别
(1)采用properties文件配置
<code>//设置某个方法的日志级别 log4j.logger.org.fkit.mapper.UserMapper.selectUser=DEBUG //设置包的日志级别 log4j.logger.org.fkit.mapper=DEBUG/<code>
(2)采用xml文件配置
<code>//设置某个方法的日志级别 //设置包的日志级别 /<code>
深入Mapper映射文件
SQL映射文件常用元素:
- select:映射查询语句
- insert:映射插入语句
- update:映射更新语句
- delete:映射删除语句
- sql:可被其他语句引用的可重用语句块
- cache:给定命名空间的缓存配置
- cache-ref:其他命名空间缓存配置引用
- resultMap:用来描述如何从数据库结果集加载对象
1.select
select元素用来映射查询语句
参数符号#{id},是指创建一个预处理语句参数,就是JDBC SQL语句中的?
select元素属性如下:
- id:在命名空间中唯一的标识符,可以被用来引用这条语句
- parameterType:将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为MyBatis可以通过TypeHandler推断出具体传入语句的参数,默认值为unset
- resultType:返回值的类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。返回时可以使用resultType或resultMap
- resultMap:外部resultMap的命名引用
- flushCache:如果设置为 true,则任何时候只要语句被调用,都会导致本地缓存和二级缓存都被清空,默认值为false
- useCache:如果设置为 true,将会导致本条语句的结果被二级缓存,在select元素当中默认值为 true
- timeout:这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset
- fetchSize:其尝试使每次批量返回的结果行数和这个设置值相等。默认值为 unset
- statementType:值为STATEMENT、PREPARED或CALLABLE。这会让MyBatis分别使用 JDBC 中的Statement、PreparedStatement或CallableStatement,默认值为PREPARED
- resultSetType:结果集的类型,值为FORWARD_ONLY、SCROLL_SENSITIVE或SCROLL_INSENSITIVE,默认值为unset
- databaseId:如果配置了databaseIdProvider,MyBatis会加载所有的不带databaseId或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略
- resultOrdered:这个设置仅针对嵌套结果select语句适用:如果为true,就是假设包含了嵌套结果集或分组,这样的话当返回一个主结果行的时候,就不会发生对前面结果集引用的情况。这就使得在获取嵌套的结果集时不至于导致内存不够用。默认值为false
- resultSets:这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并给每个结果集起一个名称,名称是逗号分隔的
2.insert、update和delete
常用属性举例如下:
insert、update 和 delete元素的属性大多和select的一致,它们特有的属性如下:
- useGeneratedKeys:(仅对 insert 和 update 有用)这会令MyBatis使用JDBC的getGeneratedKeys方法来获取由数据库内部生成的主键,默认值为false
- keyProperty:(仅对 insert 和 update 有用)唯一标记一个属性,MyBatis会通过getGeneratedKeys的返回值或者通过insert语句的selectKey子元素设置它的键值,默认为unset
- keyColumn:(仅对insert和update有用)通过生成的键值设置表中的列名,这个设置仅对某些数据库(像PostgreSQL)是必须的,当主键列不是表中的第一列时需要设置
insert插入主键的方式
(1)如果数据库支持主键生成方式(如:MySQL和SQL Server)
(2)如果数据库采用其他方式生成主键(如:Oracle)
3.sql
sql元素被用来定义可重用的SQL代码段,可以包含在其他语句中,
定义SQL
使用SQL
4.参数(Parameters)
简单数据类型
复杂对象
5.ResultMaps
resultMap元素作用是讲结果集中取出的数据转换成开发者所需的对象
(1)单表映射
举例如下:
resultType表示将返回的结果集转换成一个Map集合
当然也可以将结果集转换成持久化对象
默认情况下,MtBatis会将查询到的数据列和需要返回的对象的属性逐一进行匹配赋值,但如果查询到的数据列和需要返回的对象属性不一致,就无法自动赋值了。这时需要使用resultMap处理。
如下图:
上图使用resultMap将持久化对象属性和表的字段进行匹配
resultMap常用属性如下:
- id:唯一标识符
- type:实际返回的类型
- 子元素指定数据库表的主键,column为列名,property为对象属性
- 子元素指定数据库表的普通列
(2)多表关联映射(1对1)
多表查询的情况,当查询某个对象同时关联查询了另一个对象时使用
<code> /<code>
说明如下:
- 查询所有的学生数据,此时返回的不是简单的Student对象,因为Student对象中还包含了Clazz对象,所以使用resultMap去映射返回类型
- resultMap中查询的班级id列clazz_id则使用了关联映射,元素属性如下:
<code>column:数据库表列名 property:返回的对象类型 javaType:property属性对应的java类型 select:执行一条查询语句,将查询到的数据封装到property所代表的对象中/<code>
(3)多表关联映射(1对多)
多表查询的情况,当查询某个对象同时关联查询了List对象时使用
<code> /<code>
说明如下:
- 查询所有的班级数据,此时返回的不是简单的Clazz对象,因为Clazz对象中还包含了学生的集合对象,所以使用resultMap去映射返回类型
- 查询班级所有学生时使用了集合映射,属性如下:
<code>property:返回的集合类型的属性名 javaType:property属性对应的java类型 ofType:集合中的类型 column:使用当前表的哪个列名作为查询集合的条件 select:执行一条查询语句,将查询到的数据封装到property所代表的对象中 fetchType:设置集合属性加载的方式,包括eager和lazy,eager立即加载,lazy延迟加载/<code>
一般来说1对多关联大多被设置成lazy,全局设置方式如下:
<code>//mybatis-config.xml文件 /<code>
(4)多表关联映射(多对多)
多对多关联,单独看每个对象的映射,其实就是1对1和1对多的组合。所以只需组合使用和元素即可。
MyBatis调用存储过程
1.操作数据的存储过程
插入数据
存储过程如下:
配置如下:
(1)调用存储过程时,需要把statementType属性的值设置为CALLABLE
(2)call是用来调用存储过程的关键字,需要注意的是,OUT模式的参数必须指定jdbcType,这是因为在IN模式下,MyBatis提供了默认的jdbcType,而在OUT模式下没有提供
修改数据
存储过程如下:
配置如下:
删除数据
存储过程如下:
配置如下:
2.查询数据的存储过程
存储过程如下:
配置如下:
调用名为select_user的存储过程查询所有User数据并返回List,查询到的每一条数据会被封装到User对象中
3.根据条件查询的存储过程
存储过程如下:
配置如下:
MyBatis事务管理
1.Transaction接口
MyBatis事务核心是
org.apache.ibatis.transaction.Transaction接口。Transaction接口有两个实现类:
- JdbcTransaction
- ManagedTransaction
同时MyBatis还设计了
org.apache.ibatis.transaction.TransactionFactory接口,实现类:
- JdbcTransactionFactory
- ManagedTransactionFactory
以上类可用来获取事务的实例对象
MyBatis管理事务的两种方式:
(1)使用JDBC的事务管理机制。利用java.sql.Connection对象完成对事务的提交(commit)、回滚(rollback)和关闭(close)等操作
(2)使用MANAGED的事务管理机制。这种机制MyBatis自身不会去实现事务管理,而是让容器如WebLogic、JBoss等来实现对事务的管理
2.事务的配置创建和使用
(1)事务的配置
元素的type决定我们用什么类型的事务管理机制
(2)事务工厂的创建
MyBatis的事务创建是由TransactionFactory事务工厂来完成的。如果type="JDBC",则MyBatis会创建一个JdbcTransactionFactory的实例;如果type="MANAGED",则MyBatis 会创建一个MangedTransactionFactory的实例
(3)事务工厂TransactionFactory
JdbcTransactionFactory会创建JDBC类型的Transaction,即JdbcTransaction。类似地,ManagedTransactionFactory也会创建ManagedTransaction
(4)JdbcTransaction
JdbcTransaction可直接使用JDBC的提交和回滚事务管理机制。它依赖于从dataSource中取得的连接 connection来管理transaction的作用域。如果将autocommit设置为on,开启状态的话,则它会忽略commit和rollback。
MyBatis缓存机制
1.一级缓存(SqlSession级别)
在操作数据库时需要构造SqlSession对象,在SqlSession对象中有一个HashMap用于存储缓存数据。不同的SqlSession之间的缓存数据区域是互相不影响的。
如果SqlSession执行了DML操作(insert、update、delete),并提交到数据库,MyBatis则会
清空SqlSession中的一级缓存
Mybatis默认开启一级缓存,不需要进行任何配置
MyBatis的缓存机制是基于id进行缓存的,MyBatis使用HashMap缓存数据时,是使用对象的id作为key,对象作为value
2.二级缓存(mapper级别)
使用二级缓存时,多个SqlSession使用同一个mapper的SQL语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMap进行数据存储的。相比一级缓存 SqlSession,二级缓存的范围更大,多个SqlSession可以共享二级缓存中的数据,二级缓存是跨SqlSession的。
MyBatis默认没有开启二级缓存,需要在setting全局参数中配置开启二级缓存。
<code> /<code>
MyBatis的二级缓存是和命名空间绑定的,即二级缓存需要配置在Mapper.xml映射文件或者Mapper接口中。使用元素
在映射文件中,命名空间就是XML根节点mapper的namespace属性。在Mapper接口中,命名空间就是接口的全限定名称
配置如下:
- 映射语句文件中的所有SELECT语句将会被缓存
- 映射语句文件中的所有INSERT、UPDATE、DELETE语句会刷新缓存
- 缓存会使用LRU(最近最少使用)策略来回收
- 缓存会被视为read/write(可读/可写)的,这意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改
cache元素属性如下:
- flushInterval:刷新间隔。可以被设置为任意的正整数,单位毫秒。默认没有刷新间隔,缓存仅调用语句时刷新
- size:缓存数目。可以被设置为任意正整数。默认值是1024
- readOnly:只读。该属性可以被设置为true或false。只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改。可读写的缓存会返回缓存对象的拷贝。这种方式会慢一些,但是安全,因此默认是false。
- eviction:回收策略,默认为LRU。有如下几种:
<code>LRU:最近最少使用的策略,移除最长时间不被使用的对象 FIFO: 先进先出策略,按对象进入缓存的顺序来移除它们 SOFT: 软引用策略,移除基于垃圾回收器状态和软引用规则的对象 WEAK。 弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象 /<code>
MyBatis的注解配置
1.常用注解
- Select:映射查询的SQL语句
- SelectProvider:select语句的动态SQL映射。允许指定一个类名和 一个方法在执行时返回运行的查询语句
- Insert:映射插入的SQL语句
- InsertProvider:insert语句的动态SQL映射
- Update:映射更新的SQL语句
- UpdateProvider:update语句的动态SQL映射
- Delete:映射删除的SQL语句
- DeleteProvider:delete语句的动态SQL映射
- Result:在列和属性之间的单独结果映射。属性包括:id、 column、property、javaType、jdbcType、type Handler、one、many。id 属性是一个布尔值,表示是否被用于主键映射。one 属性是单独的映射,和XML配置中的 相似,而many属性是对集合而言的,和XML配置的相似
- Results:多个结果映射(Result)列表
- Option: 提供配置选项的附加值,它们通常在映射语句上作为附加功能配置
- One:复杂类型的单独属性值映射。必须指定select属性,表示已映射的SQL语句的完全限定名
- Many:复杂类型的集合属性映射。必须指定select属性,表示已映射的SQL语句的完全限定名
- Param:当映射器方法需要多个参数时,这个注解可以被应用于映射器方法参数来给每个参数取一个名字。否则,多参数将会以它们的顺序位置和SQL语句中的表达式进行映射,这是默认的。使用 @Param("id")时,SQL中参数应该被命名为#{id}
2.select、insert、update、delete注解
3.One注解
关联映射的对象
被关联的对象
4.Many注解
关联映射对象
被关联的对象
5.存储过程调用
6.二级缓存
關鍵字: SqlSession 属性 对象