0
点赞
收藏
分享

微信扫一扫

MyBatis XML简单理解


目录

  • ​​固定格式​​
  • ​​前置操作​​
  • ​​顶级元素​​
  • ​​select​​
  • ​​insert,update,delete​​
  • ​​xml语法​​
  • ​​if 语句​​
  • ​​where 语句​​
  • ​​trim 语句​​
  • ​​set 语句​​
  • ​​foreach​​
  • ​​choose(when,otherwize) 语句​​
  • ​​模糊查找​​
  • ​​批量插入​​
  • ​​其他​​
  • ​​MySQL时区错误​​
  • ​​IDEA快速创建xml​​

本文集各家之长,自学整理,若有错误,欢迎留言指出!!!

固定格式

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.scau.demo.mapper.UserMapper">
## ...具体内容...
</mapper>

  其中,​​namespace​​用于绑定Mapper接口。不同mapper接口对应到不同的xml。

前置操作

1、在​​application.yml​​中添加:

mybatis:
# 设置别名,这样,在xml文件中就不用写全名
type-aliases-package: com.scau.demo.entity
# resources文件夹下创建mapper文件夹,内含xxxMapper.xml文件
mapper-locations: classpath:mapper/*.xml

MyBatis XML简单理解_sql

2、在启动类前添加:

// mapper接口所在包路径
@MapperScan(basePackages = "com.scau.demo.mapper")

MyBatis XML简单理解_mybatis_02

顶级元素

​<xx>​​内最外层可以包含的元素。

  • cache – 配置给定命名空间的缓存。
  • cache-ref – 从其他命名空间引用缓存配置。
  • resultMap – 最复杂,也是最有力量的元素,用来描述如何从数据库结果集中来加载你的对象。
  • parameterMap – 已经被废弃了!老式风格的参数映射。内联参数是首选,这个元素可能在将来被移除。这里不会记录。
  • sql – 可以重用的 SQL 块,也可以被其他语句引用。
  • insert – 映射插入语句
  • update – 映射更新语句
  • delete – 映射删除语句
  • select – 映射查询语句

select

MyBatis XML简单理解_java_03


补充说明:

  • ​id​​:对应mapper接口中的函数定义,如:
  • ​parameterType​​:入参类型,可以使用的有基本数据类型Java复杂数据类型
  • 基本数据类型:包含int,String,Date等。基本数据类型作为传参,只能传入一个。通过#{参数名} 即可获取传入的值
  • 复杂数据类型:包含JAVA实体类、Map。通过#{属性名}或#{map的KeyName}即可获取传入的值

// 基本类型
<select id="get" parameterType="String" resultType="User">
select * from `scau_log` where `_openid`=#{_openid};
</select>

// 复杂类型 - 实体类
<select id="selectTeacher" parameterType="com.myapp.domain.Teacher" resultType="com.myapp.domain.Teacher">
select * from Teacher where c_id=#{id}
</select>

  • ​resultType​​:结果类型,与mapper接口中的函数定义的返回值一致

// 返回一般数据类型的值
<select id="Sel" resultType="java.lang.String">
select username from user_test where id = #{id}
</select>

// 返回类型是javaBean
<select id="Sel" resultType="com.tx.springboottestdemo.entity.User">
select * from user_test where id = #{id}
</select>

// 返回是List类型
List<User> getUsers(); // mapper 接口
// SQL映射文件,这里需要注意的是返回是List类型 但是resultType依然是javaBean
<select id="getUsers" resultType="com.tx.entity.User">
select * from user
</select>

// 返回类型是Map结构
// 当我们在查询并返回一条数据的时候,可以把{字段名,字段值}封装成Map结构
Map<String, Object> findUserByName(Integer id); // mapper 接口
<select id="findUserByName" resultType="string">
select userName from user where id=#{id};
</select>

// 传入多个参数 - 1
// 可以看做是加了注解
public List<User> findUser(@Param("name1") String name1, @Param("name2") String name2);
// 对应的SQL文件:
<select id="findUser" resultType="com.tx.springboottestdemo.entity.User">
select * from user_test where userName = #{name1} and realName = #{name2}
</select>

// 传入多个参数 - 2
// 可以把参数封装到Map里面 有些时候我们的业务数据查询没有定义对应的POJO,就进行参数的封装操作。
public List<User> findUser1(Map<String, Object> map);
// 对应的SQL文件:
<select id="findUser1" parameterType="java.util.Map" resultType="com.tx.springboottestdemo.entity.User">
select * from user_test where userName = #{username} and realName = #{realname}
</select>

insert,update,delete

  数据变更语句 insert,update 和 delete 在它们的实现中非常相似。

MyBatis XML简单理解_mybatis_04


补充说明:

  • ​useGeneratedKeys、keyProperty​​:如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就 OK 了。例如使用下列语句,这样每次插入数据时,就可以省略掉 id 列了。(:当数据库中的字段不是自增的时,useGeneratedKeys 不起作用。)

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

  如果你的数据库还支持多行插入, 你也可以传入一个数组或集合,并返回自动生成的主键。

<insert id="batchInsert" parameterType="java.util.List" useGeneratedKeys="true" keyProperty="id">
INSERT INTO user (name, age) VALUES
<foreach collection="list" item="user" index="index" separator="," >
(#{user.name}, #{user.age})
</foreach>
</insert>

  • ​keyColumn​​:用于指定数据库table中的主键。通过生成的键值设置表中的列名,这个设置仅在某些数据库(像 PostgreSQL)是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
  • 插入的时候系统时间值可以直接用​​now()​

xml语法

总体说来mybatis 动态SQL 语句主要有以下几类:

  • if 语句 (简单的条件判断)
  • choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似.
  • trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
  • where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)
  • set (主要用于更新时)
  • foreach (在实现 mybatis in 语句查询时特别有用)

if 语句

  在mapper接口中定义一个函数名,其中​​@Param​​指定xml中对应的名称,后面会用到。

List<Map<String,Object>> getByItem(@Param("item") String item, @Param("val") String val);

  在controller类和service类中:

@RequestMapping(value = "/getByItem")
public Result getByItem(String item, String value){
return userService.getByItem(item, value);
}

public Result getByItem(String item, String value){
return Result.ok(userMapper.getByItem(item, value));
}

Result 类是封装的一个返回类,可以先不用管。
  XML中:

<select id="getByItem" resultType="User">
select * from `scau_log` where
<if test="item == '_id'">
_id=#{val}
</if>
</select>

  postman发送:

MyBatis XML简单理解_sql_05


  但如果​​item!=_id​​​,则语句就变成了​​select * from​​​scau_log​​where​​​而报错,可以使用​​<where >​​。

where 语句

  ​​where​​​元素只会在子元素返回任何内容的情况下才插入 “WHERE” 子句。而且,若子句的开头为 “AND” 或 “OR”,where 元素也会将它们去除。
  将上面的xml改为如下即可:

<select id="getByItem" resultType="User">
select * from `scau_log`
<where>
<if test="item == '_id'">
_id=#{val}
</if>
</where>
</select>

  如果 where 元素与你期望的不太一样,你也可以通过自定义 ​​trim​​ 元素来定制 where 元素的功能。

trim 语句

  和 where 元素等价的自定义 trim 元素为:

<trim prefix="WHERE" prefixOverrides="AND |OR ">
...
</trim>

  ​​prefixOverrides、suffixOverrides​​​ 属性会忽略通过管道符分隔的文本序列(注意此例中的空格是必要的)。上述例子会移除所有 ​​prefixOverrides(suffixOverrides)​​​ 属性中指定的内容,并且插入 ​​prefix(suffix)​​ 属性中指定的内容。

set 语句

 用于动态更新语句的类似解决方案叫做 set。set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。

<update id="updateAuthorIfNecessary">
update Author
<set>
<if test="username != null">username=#{username},</if>
<if test="password != null">password=#{password},</if>
<if test="email != null">email=#{email},</if>
<if test="bio != null">bio=#{bio}</if>
</set>
where id=#{id}
</update>

 这个例子中,set 元素会动态地在行首插入 SET 关键字,并会删掉额外的逗号(这些逗号是在使用条件语句给列赋值时引入的)。
 来看看与 set 元素等价的自定义 trim 元素,注意我们覆盖了后缀值设置,并且自定义了前缀值。:

<trim prefix="SET" suffixOverrides=",">
...
</trim>

foreach

 对集合进行遍历(尤其是在构建 IN 条件语句的时候)。

<select id="selectPostIn" resultType="domain.blog.Post">
SELECT *
FROM POST P
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>

 foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(​​item​​​)和索引(​​index​​​)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符
 你可以将任何可迭代对象(如 ​​​List​​​、​​Set​​​ 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,​​index​​​ 是当前迭代的序号,​​item​​​ 的值是本次迭代获取到的元素。当使用​​Map​​​对象(或者 Map.Entry 对象的集合)时,​​index​​​ 是键,​​item​​ 是值。

 foreach元素的属性主要有item,index,collection,open,separator,close。

  • item表示集合中每一个元素进行迭代时的别名。
  • index指定一个名字,用于表示在迭代过程中,每次迭代到的位置。
  • open表示该语句以什么开始。
  • separator表示在每次进行迭代之间以什么符号作为分隔符。
  • close表示以什么结束。

 在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况下,该属性的值是不一样的,主要有一下3种情况:

  • 如果传入的是单参数且参数类型是一个List的时候,collection属性值为list
  • 如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array
  • 如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,当然单参数也可以封装成map,实际上如果你在传入参数的时候,在MyBatis里面也是会把它封装成一个Map的,map的key就是参数名,所以这个时候collection属性值就是传入的List或array对象在自己封装的map里面的key。

// 单参数List的类型
public List<User> dynamicForeachTest(List<Integer> ids); // 对应的Mapper
<select id="dynamicForeachTest" resultType="com.mybatis.entity.User">
select * from t_user where id in
<foreach collection="list" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>

// 数组类型的参数
public List<User> dynamicForeach2Test(int[] ids); // 对应的Mapper
<select id="dynamicForeach2Test" resultType="com.mybatis.entity.User">
select * from t_user where id in
<foreach collection="array" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>

// Map类型的参数
public List<User> dynamicForeach3Test(Map<String, Object> params); // 对应的Mapper
<select id="dynamicForeach3Test" resultType="com.mybatis.entity.User">
select * from t_user where username like '%${username}%' and id in
<foreach collection="ids" index="index" item="item" open="(" separator="," close=")">
#{item}
</foreach>
</select>

choose(when,otherwize) 语句

<select id="dynamicChooseTest" parameterType="Blog" resultType="Blog">
select * from t_blog where 1 = 1
<choose>
<when test="title != null">
and title = #{title}
</when>
<when test="content != null">
and content = #{content}
</when>
<otherwise>
and owner = "owner1"
</otherwise>
</choose>
</select>

 ​​when​​​元素表示当​​when​​​中的条件满足的时候就输出其中的内容,当when中有条件满足的时候,就会跳出​​choose​​​,即所有的​​when​​​和​​otherwise​​条件中,只有一个会输出;当所有的条件都不满足的时候就输出​​otherwise​​​中的内容。
 所以上述语句的意思非常简单,当​​​title!=null​​​的时候就输出​​and titlte = #{title}​​​,不再往下判断条件,当​​title​​​为空且​​content!=null​​​的时候就输出​​and content = #{content}​​​,当所有条件都不满足的时候就输出​​otherwise​​中的内容。

模糊查找

<if test="infoTemplateAll.templateName != null">
AND template_name LIKE '%${infoTemplateAll.templateName}%'
</if>

批量插入

<insert id="insertSelectives" parameterType="java.util.List">
INSERT INTO oap_detail_income
(
income_seq_num,
interest_terms
)
VALUES
<foreach collection="list" item="file" index="index"
separator=",">
(
#{file.incomeSeqNum},
<choose>
<when test="file.interestTerms != null">
#{file.interestTerms},
</when>
<otherwise>
0,
</otherwise>
</choose>
)
</foreach>
</insert>

… …

其他

MySQL时区错误

打开my.ini,搜索[mysqld],在[mysql]节点下加上这一行

default-time-zone='+08:00'

重启mysql服务

IDEA快速创建xml

File -> Setting -> File and Code Templates - > ‘+’号新建 -> 填写Name和Extension -> 自行填写内容 -> OK

MyBatis XML简单理解_数据库_06

<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.xx.mapper.xxMapper">
<select id="GetUserByID" parameterType="int" resultType="com.test.springtest.dao.MUser">
select * from `student` where id = #{id}
</select>
<insert
id="saveUser" parameterType="com.test.springtest.User" useGeneratedKeys="true">
insert into student(NAME,AGE) values (#{name},#{age})
</insert>
</mapper>


举报

相关推荐

0 条评论