(最高版本)mybaties知识总结

213 阅读7分钟

延迟加载:在多表关联的 一对一可以积极加载,一对多可以使用延迟加载,优化功能

延迟加载的核心方法是 createresultObject

jdbc开发的问题:

1、数据库配置加载硬编码,切换到其他加载类不方便(使用配置文件)

2、频繁连接,释放数据库(连接池,c3p0,druid..)

3、sql,设置参数,获取结果集硬编码问题(使用配置文件)

4、手动封装结果集比较繁琐(使用反射)

image.png

设计持久层框架:

使用端(项目):引入自定义持久层jar包 提供 数据库配置信息;sql配置信息;参数类型,返回类型

数据库配置 sqlmapconfig.xml sql配置信息 mapper.xml

自定义持久层框架:本质是对jdbc的代码封装

(1)加载配置文件:根据配置文件的路径,加载文件成字节输入流,存储到内存中,创建resource类 方法:inputstream getresourceas stream(String path) 关键类org.apache.ibatis.io.Resources:用于配置文件的流加载

(2)创建两个javabean:(容器对象):存放配置文件解析的内容 configration:核心配置类:存放sqlmapconfig.xml 解析的内容 mapperedStatment:映射配置类:存放mapper解析的文件

关键类:org.apache.ibatis.session.Configuration 存储配置信息

org.apache.ibatis.mapping.MappedStatement 存储执行sql的数据

(3)解析配置文件:dom4j 创建类sqlsessionfactorybiulder 方法 biuld(inputstream in)

第一:使用dom4j解析配置文件,将解析出来的内容封装到Configuration和MappedStatement中,其中Configuration对MappedStatement进行引用,以hashmap的形式存储

第二:创建sqlsessionfactory对象的实现类DefaultSqlSession;生产sqlsession:会话对象(工厂模式)

(4)创建sqlsessionfactory接口及实现类defualsqlsessionfactory 实现类org.apache.ibatis.session.defaults.DefaultSqlSessionFactory

opensession类生产sqlsession, 实现类org.apache.ibatis.session.defaults.DefaultSqlSession

DefaultSqlSession负责与jdbc的执行

org.apache.ibatis.executor.BaseExecutor 对数据的执行

org.apache.ibatis.executor.statement.PreparedStatementHandler 根据传过来的对象,对Statement设置参数

org.apache.ibatis.executor.resultset.ResultSetHandler 对返回的结果集进行封装

mybitis缓存 mybatis存在一级缓存和二级缓存,一级缓存是限制在单个sqlsession中;二级缓存时对一个mapper的缓存,允许对各sqlsession访问,在分布式的环境下,需要整合redis实现分布式的二级缓存

一级缓存的数据时存放在对象中,二级缓存的是数据,不是对象

mybatis的结构:

mybatis加载mapper文件的方式有几种?

mysql的工作流程:

mybatis标签使用: 属性介绍: 定义sql语句的标签 select标签 id :唯一的标识符. parameterType:传给此语句的参数的全路径名或别名 例:com.test.poso.User或user resultType :语句返回值类型或别名。注意,如果是集合,那么这里填写的是集合的泛型,而不是集合本身(resultType 与resultMap 不能并用) select * from student where id=#{id}

1.2 insert标签 属性介绍:

id :唯一的标识符 parameterType:传给此语句的参数的全路径名或别名 例:com.test.poso.User 复制代码

insert into student NAME, #{name},

1.3 delete标签 属性同 insert

delete from student where id=#{id}

2、java对象属性映射 如果数据库的字段名和java对象的映射不匹配,使用标签可以实现映射(映射文件的顺序在查询的上面或者下面是没有影响的,因为文件扫描的时候,会全文去找)

标签说明: 主标签: id:该resultMap的标志 type:返回值的类名,此例中返回Studnet类

select id,name,hobby,major,birthday,age from student where id=#{id}

动态sql的拼接: 3. 动态sql拼接 3.1 if 标签 if标签通常用于WHERE语句、UPDATE语句、INSERT语句中,通过判断参数值来决定是否使用某个查询条件、判断是否更新某一个字段、判断是否插入某个字段的值。

and NAME = #{name}

foreach标签主要用于构建in条件,可在sql中对集合进行迭代。也常用到批量删除、添加等操作中。 select name,hobby    from student where id in #{item}

属性介绍:

collection:collection属性的值有三个分别是list、array、map三种,分别对应的参数类型为:List、数组、map集合。 item :表示在迭代过程中每一个元素的别名 index :表示在迭代过程中每次迭代到的位置(下标) open :前缀 close :后缀 separator :分隔符,表示迭代时每个元素之间以什么分隔

3.3 choose标签   有时候我们并不想应用所有的条件,而只是想从多个选项中选择一个。MyBatis提供了choose 元素,按顺序判断when中的条件出否成立,如果有一个成立,则choose结束。当choose中所有when的条件都不满则时,则执行 otherwise中的sql。类似于Java 的switch 语句,choose为switch,when为case,otherwise则为default。

if是与(and)的关系,而choose是或(or)的关系。

choose标签的功能: SELECT * from STUDENT WHERE 1=1 AND name LIKE CONCAT(CONCAT('%', #{student}),'%') AND hobby = #{hobby} AND AGE = 15
《where标签》 当name值为null时,查询语句会出现 “WHERE AND” 的情况,解决该情况除了将"WHERE"改为“WHERE 1=1”之外,还可以利用where标签。这个“where”标签会知道如果它包含的标签中有返回值的话,它就插入一个‘where’。此外,(如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。) SELECT * from STUDENT NAME LIKE CONCAT(CONCAT('%', #{name}),'%') AND hobby = #{hobby}
《set》标签的作用: 没有使用if标签时,如果有一个参数为null,都会导致错误。当在update语句中使用if标签时,如果最后的if没有执行,则或导致逗号多余错误。使用set标签可以将动态的配置set关键字,和剔除追加到条件末尾的任何不相关的逗号。

UPDATE STUDENT SET NAME = #{name}, MAJOR = #{major}, HOBBY = #{hobby} WHERE ID = #{id};

实战: 使用set+if标签修改后,如果某项为null则不进行更新,而是保持数据库原值。
UPDATE STUDENT


NAME = #{name},


MAJOR = #{major},

HOBBY = #{hobby}


WHERE ID = #{id};

; trim属性主要有以下四个

prefix:前缀覆盖并增加其内容 suffix:后缀覆盖并增加其内容 prefixOverrides:前缀判断的条件 suffixOverrides:后缀判断的条件 www.cnblogs.com/zjfjava/p/8…

关联查询中的一对一,一对多的问题 5.1 collection标签 5.2 association标签 www.cnblogs.com/zjfjava/p/8…

命名空间

当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。为求结构清晰也可将sql语句分解 定义常量及引用 6.1 sql标签 当多种类型的查询语句的查询字段或者查询条件相同时,可以将其定义为常量,方便调用。为求结构清晰也可将sql语句分解。

复制代码

<sql id="Base_Column_List">
    ID,MAJOR,BIRTHDAY,AGE,NAME,HOBBY
</sql>
<sql id="Example_Where_Clause">
    where 1=1
    <trim suffixOverrides=","> 
        <if test="id != null and id !=''">
            and id = #{id}
        </if>
        <if test="major != null and major != ''">
            and MAJOR = #{major}
        </if>
        <if test="birthday != null ">
            and BIRTHDAY = #{birthday}
        </if>
        <if test="age != null ">
            and AGE = #{age}
        </if>
        <if test="name != null and name != ''">
            and NAME = #{name}
        </if>
        <if test="hobby != null and hobby != ''">
            and HOBBY = #{hobby}
        </if>            
        <if test="sorting != null">
            order by #{sorting}
        </if>
        <if test="sort!= null  and sort != '' ">
            order by ${sort}   ${order}
        </if>

    </trim>
</sql>

6.2 include标签 用于引用定义的常量

<select id="selectAll" resultMap="BaseResultMap">
    SELECT
    <include refid="Base_Column_List" />
    FROM
    student
    <include refid="Example_Where_Clause" />
</select>
<select id="select" resultMap="BaseResultMap">


    select * from (
        select tt.*,rownum as rowno from 
            (
                SELECT
                <include refid="Base_Column_List" /> 
                FROM
                student
                <include refid="Example_Where_Clause" />
                 ) tt 
                 <where>
                        <if test="pageNum != null and rows != null">
                        and  rownum  <![CDATA[<=]]>#{page}*#{rows}
                     </if>
                </where>
         ) table_alias
        where table_alias.rowno>#{pageNum}
          
          
</select>
<delete id="deleteByEntity" parameterType="java.util.Map">
DELETE  FROM   student
<include refid="Example_Where_Clause" />
</delete>

(1)Mybatis是一个半ORM(对象关系映射)框架,它内部封装了JDBC,开发时只需要关注SQL语句本身,不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。程序员直接编写原生态sql,可以严格控制sql执行性能,灵活度高。

Hibernate属于全自动ORM映射工具,使用Hibernate查询关联对象或者关联集合对象时,可以根据对象关系模型直接获取,所以它是全自动的。而Mybatis在查询关联对象或关联集合对象时,需要手动编写sql来完成,所以,称之为半自动ORM映射工具

因此 mybatis 中优先使用 #{};当需要动态传入 表名或列名时,再考虑使用 ${} 。

#{}是预编译处理,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

mybaties懒加载的实现 使用场景:在对应的四种表关系中,一对多、多对多通常情况下采用延迟加载,多对一、一对一通常情况下采用立即加载。 用户的查询,关联账户查询 账户的查询

mybaties配置中设置全局懒加载 懒加载的测试 调用的该对象的关联属性值,才加载数据

缓存机制在集群的环境下,会出现脏读,不建议使用