[mybatis]深入浅出Mybatis的SQL映射之增删查改

Posted 爱折腾的稻草

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[mybatis]深入浅出Mybatis的SQL映射之增删查改相关的知识,希望对你有一定的参考价值。

No.1 Mapper.xml

在Mybatis中真正强大地方在于它的映射语句(Mapper XML),有了它您的代码会非常简洁(差不多省掉了95%的代码)。Mybatis就是针对SQL构建的,并且比普通的方法做的更好。
SQL映射文件的顶级元素:

cache:给定命名空间的缓存配置;
cache-ref:对其他命名空间缓存配置的引用;
resultMap:用来描述如何从数据库结果集中来加载对象(最复杂最强大的元素);
sql:可被其他语句引用的可重用语句;
insert:映射插入语句;
update:映射更新语句;
delete:映射删除语句;
select:映射查询语句;

No.2 select语句

查询语句是我们最常用的语句之一。先来看一个简单示例:

<select id="selectById" parameterType="long" resultType="io.xiaojl.entity.UserEntity">
    select * from sys_user where id=#{id}
</select>

这个语句被称作selectById,接收一个long类型的数据,并返回一个UserEntity对象。

参数符号:#{id},告诉Mybatis使用预处理语句参数(通过JDBC,这样的一个参数在 SQL 中会由一个“?”来标识,并被传递到一个新的预处理语句中)

<select
  id="selectPerson"
  parameterType="int"
  parameterMap="deprecated"
  resultType="hashmap"
  resultMap="personResultMap"
  flushCache="false"
  useCache="true"
  timeout="10000"
  fetchSize="256"
  statementType="PREPARED"
  resultSetType="FORWARD_ONLY">

  • id:在命名空间中唯一的标识符,可以被用来引用这条语句。

  • parameterType:将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。

  • parameterMap:这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。

  • resultType:从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合情形,那应该是集合可以包含的类型,而不能是集合本身。使用 resultType 或 resultMap,但不能同时使用。

  • resultMap:外部 resultMap 的命名引用。结果集的映射是 MyBatis 最强大的特性,对其有一个很好的理解的话,许多复杂映射的情形都能迎刃而解。使用 resultMap 或 resultType,但不能同时使用。

  • flushCache:将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:false。

  • useCache:将其设置为 true,将会导致本条语句的结果被二级缓存,默认值:对 select 元素为 true。

  • timeout:这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。

  • fetchSize:这是尝试影响驱动程序每次批量返回的结果行数和这个设置值相等。默认值为 unset(依赖驱动)。

  • statementType:STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。

  • resultSetType:FORWARD_ONLY,SCROLL_SENSITIVE 或 SCROLL_INSENSITIVE 中的一个,默认值为 unset (依赖驱动)。

  • databaseId:如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

  • resultOrdered:这个设置仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。

  • resultSets:这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一个名称,名称是逗号分隔的。

No.3 insert, update 和 delete

因为这三个比较类似,所以就一起讲了,

<insert
  id="insertAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  keyProperty=""
  keyColumn=""
  useGeneratedKeys=""
  timeout="20">


<update
  id="updateAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">


<delete
  id="deleteAuthor"
  parameterType="domain.blog.Author"
  flushCache="true"
  statementType="PREPARED"
  timeout="20">

  • id:命名空间中的唯一标识符,可被用来代表这条语句。

  • parameterType:将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为 MyBatis 可以通过 TypeHandler 推断出具体传入语句的参数,默认值为 unset。

  • parameterMap:这是引用外部 parameterMap 的已经被废弃的方法。使用内联参数映射和 parameterType 属性。

  • flushCache:将其设置为 true,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值:true(对应插入、更新和删除语句)。

  • timeout:这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为 unset(依赖驱动)。

  • statementType:STATEMENT,PREPARED 或 CALLABLE 的一个。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。

  • useGeneratedKeys:(仅对 insert 和 update 有用)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 mysql 和 SQL Server 这样的关系数据库管理系统的自动递增字段),默认值:false。

  • keyProperty:(仅对 insert 和 update 有用)唯一标记一个属性,MyBatis 会通过 getGeneratedKeys 的返回值或者通过 insert 语句的 selectKey 子元素设置它的键值,默认:unset。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

  • keyColumn:(仅对 insert 和 update 有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。

  • databaseId:如果配置了 databaseIdProvider,MyBatis 会加载所有的不带 databaseId 或匹配当前 databaseId 的语句;如果带或者不带的语句都有,则不带的会被忽略。

插入语句的配置规则更加丰富,在插入语句里面有一些额外的属性和子元素用来处理主键的生成,而且有多种生成方式。

3.1、主键生成策略
  • 1、数据库支持自动生成(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置到目标属性上就OK了。比如:

<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id">
  • 2、数据库不支持自动生成或可能不支持自动生成主键的 JDBC 驱动,MyBatis 有另外一种方法来生成主键。  
    这个不推荐,我也不写示例了,这种情况一般会使用第三方或者在java程序中生成一个唯一的uuid来作为主键。

No.4 sql

sql元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:

<sql id="userColumns"> ${alias}.id,${alias}.username,${alias}.password </sql>

这个 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>

No.5 参数(Parameters)

5.1、单个参数

可以接受基本类型,对象类型,集合类型的值。这种情况MyBatis可直接使用这个参数,不需要经过任何处理。

<select id="selectById" parameterType="long" resultType="io.xiaojl.entity.UserEntity">
    select * from sys_user where id=#{id}
</select>
5.2、POJO

当这些参数属于我们业务POJO时,我们直接传递POJO

<!-- 参数parameterType可以省略,不管如何,变量名都是javabean中属性名 -->
<insert id="save" parameterType="io.xiaojl.entity.UserEntity">
    insert into sys_user(id,loginName,loginPwd,createTime)
    values(#{loginName},#{loginPwd},#{createTime})
</insert>
5.3、Map

我们也可以封装多个参数为map,直接传递。

<!-- 参数是map,变量名随意,调用时,map的key要和变量名要一致 ,参数也可以省略 -->
<insert id="save" parameterType="java.util.Map">
    insert into sys_user(id,loginName,loginPwd,createTime)
    values(#{loginName},#{loginPwd},#{createTime})
</insert>
5.4、多个参数

任意多个参数,都会被MyBatis重新包装成一个Map传入。Map的key是param1,param2,或者0,1,值就是参数的值

<!-- 带有多个参数,参数名 #{param1},#{param2},或者#{0},#{1},不能使用参数名-->
<insert id="save" parameterType="java.util.Map">
    insert into sys_user(id,loginName,loginPwd,createTime)
    values(#{loginName},#{loginPwd},#{createTime})
</insert>
5.5、命名参数

为参数使用@Param起一个名字,MyBatis就会将这些参数封装进map中,key就是我们自己指定的名字。

<!-- 带有多个参数,使用@Param注解,参数名直接使用定义名, #{name},#{pass}或,#{param1},#{param2},不能用#{0},#{1}-->
<insert id="save" parameterType="java.util.Map">
    insert into sys_user(id,loginName,loginPwd,createTime)
    values(#{loginName},#{loginPwd},#{createTime})
</insert>

·end·
- 如果喜欢,快分享给你的朋友们吧 -
我们一起愉快的玩耍吧

以上是关于[mybatis]深入浅出Mybatis的SQL映射之增删查改的主要内容,如果未能解决你的问题,请参考以下文章

《深入浅出MyBatis技术原理与实战》读书笔记 - 动态SQL

深入浅出MyBatis:MyBatis解析和运行原理

MyBatis映射器

深入浅出MyBatis:反射和动态代理

MyBatis sql映射器 Mapper

SQL映射器Mapper接口(MyBatis)