ORM框架-MyBatis

Download Report

Transcript ORM框架-MyBatis

ORM框架-MyBatis
ORM框架的发展
本次分享的主题列表
 ORM技术介绍
 Mybatis的初步介绍
 Mybatis的进阶指南
 同类框架比较
ORM技术介绍

ORM解决了什么问题?
 对象关系与关系数据库的”阻抗失配”
 Mapping就是把对象与对象之间的关系与表与表之间的
关系一一对映

怎么解决对象关系的映射,理论是什么?
1 对象继承
2 对象关联

ORM技术的实现


Mybatis
hibernate
对象继承映射
 整个层次结构映射到一张表
 Betorderplan,betgrouplan bet_plan
 每个具体类映射到一张表
 每个类单独映射到一张表
对象关系映射
 关系的类型
 如何实现关系
 如何实现关系数据中的关系
 关系映射
 One to one
 One to many
 Many to many
ORM框架的实现
 MyBatis(Ibatis),半自动ORM实现
 不会在运行时自动生成sql代码执行
 将参数和返回结果映射到POJO





Hibernate
OpenJPA
EJB3
Apache OJB
…
Mybatis初步介绍
 基本组件
 基本配置
 SQL映射
 Select,update,insert,delete
 resultMap
 sql
基本组件
 SQLSessionFactoryBuilder
 SQLSessionFactory
 SQLSession
 Mapper
Mybatis-config.xml
SQL映射

resultMap -描述怎么从数据库结果集中加载对象






parameterMap –参数,已废弃,用内联参数代替
Sql –可重用的SQL块,可被其它的SQL用
Select
Insert
Update
delete
Select
 <select id=“selectLeague”

parameterType=“int”

resultType=“hashmap”
 Select * from LEAGUE where ID=#{id}
 </select>
 resultType VS resultMap ?
ResultMap-基本用法
Update
<update id="updateAuthor" parameterType="domain.blog.Author">
update Author set
username = #{username},
password = #{password},
email = #{email},
bio = #{bio}
where
id = #{id}
</update>
Insert-1
<insert id="insertAuthor" parameterType="domain.blog.Author">
insert into Author (id,username,password,email,bio)
values (#{id},#{username},#{password},#{email},#{bio})
</insert>
如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那
么,你可以设置 useGeneratedKeys=”true”,而且设置 keyProperty 到你已经做
好的目标属性上.
<insert id="insertAuthor" parameterType="domain.blog.Author"
useGeneratedKeys=”true” keyProperty=”id”>
insert into Author (username,password,email,bio)
values (#{username},#{password},#{email},#{bio})
</insert>
Insert-2
<insert id="insertAuthor" parameterType="domain.blog.Author">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
</selectKey>
insert into Author
(id, username, password, email,bio, favourite_section)
values
(#{id}, #{username}, #{password}, #{email}, #{bio},
#{favouriteSection,jdbcType=VARCHAR} )
</insert>
selectKey 元素将会首先运行,Author 的 id 会被设置,然后插入语句
会被调用
delete
<delete id="deleteAuthor” parameterType="int">
delete from Author where id = #{id}
</delete>
设置可重用的SQL片段
<sql id=“userColumns”> id,username,password </sql>
<select id=“selectUsers”parameterType=“int” resultType=“hashmap”
select <include refid=“userColumns”from USERS where id=#{id}
</select>
Mybatis进阶指南
 ResultMap高级用法
 Cache
 动态SQL
ResultMap-高级一点的用法
博客,有很多的博文,每篇博文有零条或多条的评论和标签,如下:
Class Blog {
private Author author;
private List<Post> posts;
//get/set…
}
Class Post {
private String subject;
private Author author;
private List<Comment> comments;
private List<Tag> tags;
//get/set
}
…>到下一页
ResultMap-高级一点的用法
见桌面 resultMap高级映射.txt
ResultMap-高级一点的用法
 Constructor
 调用构造函数
 Id
 用于标识对象,提高在缓存,多表映射时的性能




Result
Association
Collection
discriminator
ResultMap-高级一点的用法
 Association
嵌套查询:通过执行另外一个 SQL 映射语句来返回预期的复杂类型
<association property="author" column="blog_author_id "
javaType="Author" select= "selectAuthor " />
<select id=“selectAuthor”....
嵌套结果:使用嵌套结果映射来处理重复的联合结果的子集
<association property=“author”column=“blog_author_id”
resultMap=“authorResult”
<resultMap id=“authorResult”......
ResultMap-高级一点的用法
 Collection
 这个主题同Association
ResultMap-高级一点的用法
 Discriminator
 鉴别器
<resultMap id="vehicleResult" type="Vehicle">
<id property=”id” column="id" />
<result property="vin" column="vin"/>
<result property="year" column="year"/>
<result property="make" column="make"/>
<result property="model" column="model"/>
<result property="color" column="color"/>
<discriminator javaType="int" column="vehicle_type">
<case value="1" resultMap="carResult"/>
<case value="2" resultMap="truckResult"/>
<case value="3" resultMap="vanResult"/>
<case value="4" resultMap="suvResult"/>
</discriminator>
</resultMap>
Cache
 开启缓存(二级)
 在mapper映射文件中加<cache />
>映射语句文件中的所有 select 语句将会被缓存。
>映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。
>缓存会使用 Least Recently Used(LRU,最近最少使用的)算法
来收回。
>根据时间表(比如 no Flush Interval,没有刷新间隔),缓存不
会以任何时间顺序来刷新。
>缓存会存储列表集合或对象(无论查询方法返回什么)的 1024个
引用。
>缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检
索不是共享的,而且可以安全地被调用者修改,而不干扰其他调
用者或线程所做的潜在修改。
缓存的收回策略
 LRU–最近最少使用的:移除最长时间不被使用的对
象。
 FIFO–先进先出:按对象进入缓存的顺序来移除它们。
 SOFT–软引用:移除基于垃圾回收器状态和软引用规
则的对象。
 WEAK–弱引用:更积极地移除基于垃圾收集器状态
和弱引用规则的对象
自定义缓存
 <cache type=”com.domain.something.MyCustomCache”/>
class MyCache implements Cache {
…
}
动态SQL




if
choose(when,otherwise)
trim(where,set)
foreach
MyBat is 采用功能强大的基于 OGNL 的表达式
动态SQL-if
<select id=”findActiveBlogWithTitleLike”parameterType=”Blog”
resultType=”Blog”>
SELECT * FROM BLOG
WHERE
state = “ACTIVE”
<if test=”title != null”>
AND title like #{title}
</if>
</select>
动态SQL-choose,when,otherwise
<choose>
<when test=”title != null”>
AND title like #{title}
</when>
<when test=”author != null and author.name != null”>
AND title like #{author.name}
</when>
<otherwise>
AND featured = 1
</otherwise>
</choose>
动态SQL-where,trim,set
SELECT * FROM BLOG
<where>
<if test=”state != null”> state = #{state} </if>
<if test=”title != null”>
AND title like #{title}
</if>
</where>
UPDATE STUDENT_TBL
<set>
<if test="studentName != null and studentName != '' ">
STUDENT_TBL.STUDENT_NAME = #{studentName},
</if>
<if test="studentSex != null and studentSex != '' ">
STUDENT_TBL.STUDENT_SEX = #{studentSex},
</if>
</set>
where id=#{id}
</update>
Trim替代where和set
<trim prefix="WHERE" prefixOverrides="AND|OR">
<trim prefix=“SET" prefixOverrides=“,">
动态SQL-foreach
 迭代一个集合,通常是构建在IN条件
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list" open="(" separator=","
close=")">
#{item}
</foreach>
Item->传入的集合参数名; collection在参数是集合时是list,数组时是array