1_MyBatis

目录

MyBatis

​ MyBatis 是轻量级持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。

快速入门

安装
  1. 导入mybatis jar包

    https://github.com/mybatis/mybatis-3/releases

  2. maven项目添加依赖

    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>x.x.x</version>
    </dependency>
    

核心架构

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uhIMXxA2-1609347007799)(D:\0000note\4框架note\img\mybatis核心.png)]

SqlSessionFactory

​ 每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的,SqlSessionFactory 它是个单个数据库映射关系经过编译后的内存镜像

String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession

​ SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。

try (SqlSession session = sqlSessionFactory.openSession()) {
  BlogMapper mapper = session.getMapper(BlogMapper.class);
  Blog blog = mapper.selectBlog(101);
}

XML映射文件

用来定义SQL映射语句,包内的映射器接口实现全部注册为映射器(接口既绑定映射文件)

  1. 通过xml配置映射器

    https://mybatis.org/mybatis-3/zh/configuration.html#mappers

  2. 在映射文件里绑定接口

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 对应接口的类路径 -->
<mapper namespace="com.cy.pj.sys.dao.xxMapper"> 
</mapper>
顶级元素
  • cache – 该命名空间的缓存配置。
  • cache-ref – 引用其它命名空间的缓存配置。
  • resultMap – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。
  • sql – 可被其它语句引用的可重用语句块。
  • insert – 映射插入语句。
  • update – 映射更新语句。
  • delete – 映射删除语句。
  • select – 映射查询语句。
select

这个语句名为 selectPerson,接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值。

<select id="selectPerson" parameterType="int" resultType="hashmap">
  SELECT * FROM PERSON WHERE ID = #{id}
</select>
select元素属性
属性描述
id对应映射器中的方法
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
resultType期望从这条语句中返回结果的类全限定名或别名。 注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。 resultType 和 resultMap 之间只能同时使用一个。
resultMap对外部 resultMap 的命名引用。结果映射是 MyBatis 最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。 resultType 和 resultMap 之间只能同时使用一个。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
insert, update 和 delete

数据变更语句 insert,update 和 delete 的实现非常接近:

<insert id="insertAuthor">
  insert into Author (id,username,password,email,bio)
  values (#{id},#{username},#{password},#{email},#{bio})
</insert>

<update id="updateAuthor">
  update Author set
    username = #{username},
    password = #{password},
    email = #{email},
    bio = #{bio}
  where id = #{id}
</update>

<delete id="deleteAuthor">
  delete from Author where id = #{id}
</delete>

如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就会把自增的id回显给pojo

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>
SQL

​ 这个元素可以用来定义可重用的 SQL 代码片段,以便在其它语句中使用。 参数可以静态地(在加载的时候)确定下来,并且可以在不同的 include 元素中定义不同的参数值。

  1. 定义 (取参用 ‘$’)

    <sql id="sqltest"> ${alias}.id,${alias}.username,${alias}.password </sql>
    
  2. 使用 (include标签 的 refid属性关联< sql>)

    <select id="selectUsers" resultType="map">
      select
        <include refid="userColumns"><property name="alias" value="t1"/></include>,
        <include refid="userColumns"><property name="alias" value="t2"/></include>
      from some_table t1
        cross join some_table t2
    </select>
    
resultMap 结果映射

​ resultMap 元素是 MyBatis 中最重要最强大的元素。ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。

隐式resultMap
<select id="selectUsers" resultType="map">
  select *
  from some_table
</select>

​ 上述语句只是简单地将所有的列映射到 HashMap 的键上,这由 resultType 属性指定。虽然在大部分情况下都够用,但是 HashMap 并不是一个很好的领域模型。

​ 你的程序更可能会使用 JavaBean 或 POJO(Plain Old Java Objects,普通老式 Java 对象)作为领域模型。MyBatis 对两者都提供了支持。

显式resultMap

​ 定义< resultMap>然后在引用它的语句中设置 resultMap 属性就行了(注意去掉了 resultType 属性)。

<resultMap id="userResultMap" type="User">
  <id property="id" column="user_id" />
  <result property="username" column="user_name"/>
  <result property="password" column="hashed_password"/>
</resultMap>

<select id="selectUsers" resultMap="userResultMap">
  select user_id, user_name, hashed_password
  from some_table
  where id = #{id}
</select>
高级结果映射
<!-- 非常复杂的结果映射 -->
<!-- property bean的字段或属性
	 column 数据库中的列名
 	 javaType java类的全限定名
-->
<resultMap id="detailedBlogResultMap" type="Blog">
  <constructor>
    <idArg column="blog_id" javaType="int"/>
  </constructor>
    
  <result property="title" column="blog_title"/>
    
  <association property="author" javaType="Author">
    <id property="id" column="author_id"/>
    <result property="username" column="author_username"/>
    <result property="password" column="author_password"/>
    <result property="email" column="author_email"/>
    <result property="bio" column="author_bio"/>
    <result property="favouriteSection" column="author_favourite_section"/>
  </association>
    
  <collection property="posts" ofType="Post">
    <id property="id" column="post_id"/>      
    <result property="subject" column="post_subject"/>
    <association property="author" javaType="Author"/>
    
    <collection property="comments" ofType="Comment">
      <id property="id" column="comment_id"/>
    </collection>
      
    <collection property="tags" ofType="Tag" >
      <id property="id" column="tag_id"/>
    </collection>
      
    <discriminator javaType="int" column="draft">
      <case value="1" resultType="DraftPost"/>
    </discriminator>     
    </collection>
</resultMap>
  • constructor 用于在实例化类时,注入结果到构造方法中
    • idArg id参数
    • arg 将被注入到构造方法的一个普通结果
  • id id结果
  • result 注入到字段或 JavaBean 属性的普通结果
  • association 一个复杂类型的关联;许多结果将包装成这种类型
    • 嵌套结果映射 – 关联可以是 resultMap 元素,或是对其它结果映射的引用
  • collection 一个复杂类型的集合
    • 嵌套结果映射 – 集合可以是 resultMap 元素,或是对其它结果映射的引用
  • discriminator 使用结果值来决定使用哪个 resultMap
    • case 基于某些值的结果映射
      • 嵌套结果映射 case 也是一个结果映射,因此具有相同的结构和元素;或者引用其它的结果映射

动态SQL

  • if 条件元素
  • choose(when,otherwise) 选择元素(like switch in java)
  • trim(where,set)
  • foreach
if

if提供了可选的xx功能,传入

<select id="find" resultType="pojo">
  SELECT * FROM table
  WHERE state = ‘ACTIVE’
  <if test="title != null">
    AND title like concat('%',#{title},'%')  <!-- '%${title}%' 也可,但会引发sql注入问题-->
  </if>
</select>
choose ,when ,otherwise

如果传入title 则按title查找 ,传入author 就按author查找

<select id="find" resultType="pojo">
  SELECT * FROM table 
  WHERE
  <choose>
  	<when test="title != null">
     	column=#{title}
   	</when>
   	<when test="author != null and author.name != null">
      	 column=#{author.name}
    </when>
    <otherwise>
      	column = -1
    </otherwise>
  </choose>
</select>
where

where 元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或

“OR”,where 元素也会将它们去除。

<select id="find" resultType="pojo">
  SELECT * FROM table
  <where>
    <if test="state != null">
         state = #{state}
    </if>
    <if test="title != null">
        AND title like #{title}
    </if>
  </where>
</select>
<!-- 注意和if标签配合使用: 不加if 则 相当于 where state=null 进行查询 -->
set

set 元素可以用于动态包含需要更新的列,而忽略其它不更新的列。若结尾有 ‘,’ 会自动去除.

<update id="update">
	update teble 
    <set>
    	<if test="username!=null">username=#{username},</if>
        <if test="password!=null">password=#{password}</if>
    </set>
    where id = #{id}
</update>
trim
属性
属性描述
prefix若sql有效,拼接前缀
suffix若sql有效,拼接后缀
prefixOverrides去除sql语句前面的关键字或者字符,该关键字或者字符由prefixOverrides属性指定,假设该属性指定为"AND",当sql语句的开头为"AND",trim标签将会去除该"AND"
suffixOverrides去除sql语句后面的关键字或者字符,该关键字或者字符由suffixOverrides属性指定
<!-- preficOverrides 参数用 ' |' 分隔 -->
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  <!-- 	等价于where标签-->
</trim>
<trim prefix="SET" suffixOverrides=",">
  <!-- 等价于set 标签-->
</trim>
foreach

对集合进行遍历

<delete id="delete" resultType="pojo">
  delete 
  from teble
  <where>
  	<if test="ids!=null">
    	id in
        <!--          mapper接口参数;                下标        前缀      后缀         分隔符-->
        <foreach collection="ids" item="id" index="index" open="(" close=")" separator=",">
        	#{id}
        </foreach>
    </if>
  </where>
</delete>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值