前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >MyBatis XML简单理解

MyBatis XML简单理解

作者头像
小锋学长生活大爆炸
发布2020-09-16 14:43:13
9440
发布2020-09-16 14:43:13
举报

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


固定格式

代码语言:javascript
复制
<!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中添加:

代码语言:javascript
复制
mybatis:
  # 设置别名,这样,在xml文件中就不用写全名 
  type-aliases-package: com.scau.demo.entity
  # resources文件夹下创建mapper文件夹,内含xxxMapper.xml文件
  mapper-locations: classpath:mapper/*.xml
在这里插入图片描述
在这里插入图片描述

2、在启动类前添加:

代码语言:javascript
复制
// mapper接口所在包路径
@MapperScan(basePackages = "com.scau.demo.mapper") 
在这里插入图片描述
在这里插入图片描述

顶级元素

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

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

select

在这里插入图片描述
在这里插入图片描述

补充说明:

  • id:对应mapper接口中的函数定义,如:
在这里插入图片描述
在这里插入图片描述
  • parameterType:入参类型,可以使用的有基本数据类型Java复杂数据类型
    • 基本数据类型:包含int,String,Date等。基本数据类型作为传参,只能传入一个。通过#{参数名} 即可获取传入的值
    • 复杂数据类型:包含JAVA实体类、Map。通过#{属性名}或#{map的KeyName}即可获取传入的值
代码语言:javascript
复制
// 基本类型
<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接口中的函数定义的返回值一致
代码语言:javascript
复制
// 返回一般数据类型的值
<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 在它们的实现中非常相似。

在这里插入图片描述
在这里插入图片描述

补充说明:

  • useGeneratedKeys、keyProperty:如果你的数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),那么你可以设置 useGeneratedKeys=”true”,然后再把 keyProperty 设置为目标属性就 OK 了。例如使用下列语句,这样每次插入数据时,就可以省略掉 id 列了。(:当数据库中的字段不是自增的时,useGeneratedKeys 不起作用。)
代码语言:javascript
复制
<insert id="insertAuthor" useGeneratedKeys="true" keyProperty="id">
    insert into Author (username,password,email,bio) values (#{username},#{password},#{email},#{bio})
</insert>

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

代码语言:javascript
复制
<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中对应的名称,后面会用到。

代码语言:javascript
复制
List<Map<String,Object>> getByItem(@Param("item") String item, @Param("val") String val);

  在controller类和service类中:

代码语言:javascript
复制
@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中:

代码语言:javascript
复制
<select id="getByItem" resultType="User">
    select * from `scau_log` where
    <if test="item == '_id'">
        _id=#{val}
    </if>
</select>

  postman发送:

在这里插入图片描述
在这里插入图片描述

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

where 语句

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

代码语言:javascript
复制
<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 元素为:

代码语言:javascript
复制
<trim prefix="WHERE" prefixOverrides="AND |OR ">
  ...
</trim>

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

set 语句

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

代码语言:javascript
复制
<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 元素,注意我们覆盖了后缀值设置,并且自定义了前缀值。:

代码语言:javascript
复制
<trim prefix="SET" suffixOverrides=",">
  ...
</trim>

foreach

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

代码语言:javascript
复制
<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)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符  你可以将任何可迭代对象(如 ListSet 等)、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。
代码语言:javascript
复制
// 单参数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) 语句

代码语言:javascript
复制
<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,即所有的whenotherwise条件中,只有一个会输出;当所有的条件都不满足的时候就输出otherwise中的内容。  所以上述语句的意思非常简单,当title!=null的时候就输出and titlte = #{title},不再往下判断条件,当title为空且content!=null的时候就输出and content = #{content},当所有条件都不满足的时候就输出otherwise中的内容。

模糊查找

代码语言:javascript
复制
<if test="infoTemplateAll.templateName != null">
    AND template_name LIKE '%${infoTemplateAll.templateName}%'
</if>

批量插入

代码语言:javascript
复制
<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]节点下加上这一行

代码语言:javascript
复制
default-time-zone='+08:00'

重启mysql服务

IDEA快速创建xml

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

在这里插入图片描述
在这里插入图片描述
代码语言:javascript
复制
<!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>
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-09-11 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 本文集各家之长,自学整理,若有错误,欢迎留言指出!!!
  • 固定格式
  • 前置操作
  • 顶级元素
    • select
      • insert,update,delete
      • xml语法
        • if 语句
          • where 语句
            • trim 语句
              • set 语句
                • foreach
                  • choose(when,otherwize) 语句
                    • 模糊查找
                      • 批量插入
                      • 其他
                        • MySQL时区错误
                          • IDEA快速创建xml
                          相关产品与服务
                          数据库
                          云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                          领券
                          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档