390 likes | 807 Views
ORM 框架 - MyBatis. ORM 框架的发展. 本次分享的主题列表. ORM 技术介绍 Mybatis 的初步介绍 Mybatis 的进阶指南 同类 框架比较. ORM 技术介绍. ORM 解决了什么问题 ? 对象关系与关系数据库的 ” 阻抗失配 ” Mapping 就是把对象与对象之间的关系与表与表之间的关系一一对 映 怎么解决对象关系的映射 , 理论是什么 ? 1 对象继承 2 对象 关联 ORM 技术的 实现 Mybatis hibernate. 对象继承映射. 整个层次结构映射到一张表
E N D
ORM框架-MyBatis ORM框架的发展
本次分享的主题列表 • ORM技术介绍 • Mybatis的初步介绍 • Mybatis的进阶指南 • 同类框架比较
ORM技术介绍 • ORM解决了什么问题? • 对象关系与关系数据库的”阻抗失配” • Mapping就是把对象与对象之间的关系与表与表之间的关系一一对映 • 怎么解决对象关系的映射,理论是什么? 1 对象继承 2 对象关联 • ORM技术的实现 • Mybatis • hibernate
对象继承映射 • 整个层次结构映射到一张表 • Betorderplan,betgrouplanbet_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
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 ?
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"> <selectKeykeyProperty="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片段 <sqlid=“userColumns”> id,username,password </sql> <select id=“selectUsers”parameterType=“int” resultType=“hashmap” select <include refid=“userColumns”fromUSERS 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-高级一点的用法 嵌套查询:通过执行另外一个 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”...... Association
ResultMap-高级一点的用法 Collection 这个主题同Association
ResultMap-高级一点的用法 • <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> • Discriminator • 鉴别器
Cache • 开启缓存(二级) • 在mapper映射文件中加<cache /> >映射语句文件中的所有 select 语句将会被缓存。 >映射语句文件中的所有 insert,update 和 delete 语句会刷新缓存。 >缓存会使用 Least Recently Used(LRU,最近最少使用的)算法来收回。 >根据时间表(比如 no Flush Interval,没有刷新间隔),缓存不会以任何时间顺序来刷新。 >缓存会存储列表集合或对象(无论查询方法返回什么)的 1024个引用。 >缓存会被视为是 read/write(可读/可写)的缓存,意味着对象检索不是共享的,而且可以安全地被调用者修改,而不干扰其他调用者或线程所做的潜在修改。
缓存的收回策略 LRU–最近最少使用的:移除最长时间不被使用的对象。 FIFO–先进先出:按对象进入缓存的顺序来移除它们。 SOFT–软引用:移除基于垃圾回收器状态和软引用规则的对象。 WEAK–弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
自定义缓存 class MyCache implements Cache { … } <cache type=”com.domain.something.MyCustomCache”/>
动态SQL MyBatis 采用功能强大的基于 OGNL 的表达式 if choose(when,otherwise) trim(where,set) foreach
动态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 SELECT * FROM POST P WHERE ID in <foreach item="item" index="index" collection="list" open="(" separator="," close=")"> #{item} </foreach> Item->传入的集合参数名;collection在参数是集合时是list,数组时是array 迭代一个集合,通常是构建在IN条件