一文搞定MyBatis各种标签

select标签

在 SQL 映射文件中 < select> 元素用于映射 SQL 的 select 语句,其示例代码如下:

<!--根据uid查询一个用户信息 -->
<select id="selectUserById" parameterType="Integer" resultType="com.mybatis.po.MyUser">
    select * from user where uid = #{uid}
</select>

在上述示例代码中,id 的值是唯一标识符,它接收一个 Integer 类型的参数,返回一个 MyUser 类型的对象,结果集自动映射到 MyUser 属性。

< select> 元素除了有上述示例代码中的几个属性以外,还有一些常用的属性,如表 1 所示。

属性名称描 述
id它和 Mapper 的命名空间组合起来使用,是唯一标识符,供 MyBatis 调用
parameterType表示传入 SQL 语句的参数类型的全限定名或别名。它是一个可选属性,MyBatis 能推断出具体传入语句的参数
resultTypeSQL 语句执行后返回的类型(全限定名或者别名)。如果是集合类型,返回的是集合元素的类型,返回时可以使用 resultType 或 resultMap 之一
resultMap它是映射集的引用,与 < resultMap> 元素一起使用,返回时可以使用 resultType 或 resultMap 之一
flushCache用于设置在调用 SQL 语句后是否要求 MyBatis 清空之前查询的本地缓存和二级缓存,默认值为 false,如果设置为 true,则任何时候只要 SQL 语句被调用都将清空本地缓存和二级缓存
useCache启动二级缓存的开关,默认值为 true,表示将査询结果存入二级缓存中
timeout用于设置超时参数,单位是秒(s),超时将抛出异常
fetchSize获取记录的总条数设定
statementType告诉 MyBatis 使用哪个 JDBC 的 Statement 工作,取值为 STATEMENT(Statement)、 PREPARED(PreparedStatement)、CALLABLE(CallableStatement)
resultSetType这是针对 JDBC 的 ResultSet 接口而言,其值可设置为 FORWARD_ONLY(只允许向前访问)、SCROLL_SENSITIVE(双向滚动,但不及时更新)、SCROLLJNSENSITIVE(双向滚动,及时更新)

使用 Map 接口传递多个参数

在实际开发中,查询 SQL 语句经常需要多个参数,例如多条件查询。当传递多个参数时,< select> 元素的 parameterType 属性值的类型是什么呢?在 MyBatis 中允许 Map 接口通过键值对传递多个参数。

假设数据操作接口中有个实现查询陈姓男性用户信息功能的方法:

public List< MyUser> selectAllUser(Map<String,Object> param);

此时,传递给映射器的是一个 Map 对象,使用它在 SQL 文件中设置对应的参数,对应 SQL 文件的代码如下:

<!-- 查询陈姓男性用户信息 -->
<select id="selectAllUser" resultType="com.mybatis.po.MyUser">
    select * from user
    where uname like concat('%',#{u_name},'%')
    and usex = #{u_sex}
</select>

在上述 SQL 文件中,参数名 u_name 和 u_sex 是 Map 的 key。

为了测试该示例,首先创建一个 Web 应用 mybatisDemo02,将 mybatisDemo01 应用的所有 JAR 包复制到 /WEB-INF/lib 下,同时将 mybatisDemo01 应用的 src 目录下的所有包和文件复制到 mybatisDemo02 应用的 src 目录下。

然后将 com.mybatis 包中的 SQL 映射文件 UserMapper.xml 中的“查询所有用户信息”的代码片段修改为上述“查询陈姓男性用户信息”的代码片段,最后将 com.controller 包中 UserController 的代码简单修改即可运行测试类了。

com.controller 包中 UserController 的代码片段如下:

@Controller("UserController")
public class UserController {
    private UserDao userDao;
    public void test(){
        ...
        //查询多个用户
        Map<String,Object> map = new HashMap<>();
        map.put("u_name","陈");
        map.put("u_sex","男");
        List<MyUser> list = userDao.seleceAllUser(map);
        for(MyUser myUser : list) {
            System.out.println(myUser);
        }
        ...
    }
}

Map 是一个键值对应的集合,使用者要通过阅读它的键才能了解其作用。另外,使用 Map 不能限定其传递的数据类型,所以业务性不强,可读性较差。如果 SQL 语句很复杂,参数很多,使用 Map 将很不方便。幸运的是,MyBatis 还提供了使用 Java Bean 传递多个参数的形式。

使用 Java Bean 传递多个参数

首先在 myBatisSemo02 应用的 src 目录下创建一个名为 com.pojo 的包,在包中创建一个 POJO 类 SeletUserParam,代码如下:

package com.pojo;
public class SeletUserParam {
    private String u_name;
    private String u_sex;
    // 此处省略setter和getter方法
}

接着将 Dao 接口中的 selectAllUser 方法修改为如下:

public List< MyUser> selectAllUser(SelectUserParam param);

然后将 com.mybatis 包中的 SQL 映射文件 UserMapper.xml 中的“查询陈姓男性用户信息”的代码修改为如下:

<select id="selectAllUser" resultType="com.po.MyUser" parameterType="com.pojo.SeletUserParam">
  select * from user
  where uname like concat('%',#{u_name},'%')
  and usex=#{u_sex}
</select>

最后将 com.controller 包中 UserController 的“查询多个用户”的代码片段做如下修改:

SeletUserParam su = new SelectUserParam();
su.setU_name("陈");
su.setU_sex("男");
List<MyUser> list = userDao.selectAllUser(su);
for (MyUser myUser : list) {
    System.out.println(myUser);
}

在实际应用中是选择 Map 还是选择 Java Bean 传递多个参数应根据实际情况而定,一般建议选择 Java Bean。

insert、update、delete和sql标签

< insert>元素

< insert> 元素用于映射插入语句,MyBatis 执行完一条插入语句后将返回一个整数表示其影响的行数。它的属性与 < select> 元素的属性大部分相同,在本节讲解它的几个特有属性。

  • keyProperty:该属性的作用是将插入或更新操作时的返回值赋给 PO 类的某个属性,通常会设置为主键对应的属性。如果是联合主键,可以将多个值用逗号隔开。
  • keyColumn:该属性用于设置第几列是主键,当主键列不是表中的第 1 列时需要设置。如果是联合主键,可以将多个值用逗号隔开。
  • useGeneratedKeys:该属性将使 MyBatis 使用 JDBC 的 getGeneratedKeys()方法获取由数据库内部产生的主键,例如 MySQL、SQL Server 等自动递增的字段,其默认值为 false。
1)主键(自动递增)回填

MySQL、SQL Server 等数据库的表格可以采用自动递增的字段作为主键,有时可能需要使用这个刚刚产生的主键,用于关联其他业务。

首先为 com.mybatis 包中的 SQL 映射文件 UserMapper.xml 中 id 为 addUser 的 < insert> 元素添加 keyProperty 和 useGeneratedKeys 属性,具体代码如下:

<!--添加一个用户,成功后将主键值返回填给uid(po的属性)-->
<insert id="addUser" parameterType="com.po.MyUser" keyProperty="uid" useGeneratedKeys="true">
  insert into user (uname,usex) values(#{uname},#{usex})
</insert>

然后在 com.controller 包的 UserController 类中进行调用,具体代码如下:

// 添加一个用户
MyUser addmu = new MyUser();
addmu.setUname("陈恒");
addmu.setUsex("男");
int add = userDao.addUser(addmu);
System.out.println("添加了" + add + "条记录");
System.out.println("添加记录的主键是" + addmu.getUid());
2)自定义主键

如果在实际工程中使用的数据库不支持主键自动递增(例如 Oracle),或者取消了主键自动递增的规则,可以使用 MyBatis 的 < selectKey> 元素来自定义生成主键。具体配置示例代码如下:

<!-- 添加一个用户,#{uname}为 com.mybatis.po.MyUser 的属性值 -->
<insert id="insertUser" parameterType="com.po.MyUser">
    <!-- 先使用selectKey元素定义主键,然后再定义SQL语句 -->
    <selectKey keyProperty="uid" resultType="Integer" order="BEFORE">
    select if(max(uid) is null,1,max(uid)+1) as newUid from user)
    </selectKey>
    insert into user (uid,uname,usex) values(#{uid},#{uname},#{usex})
</insert>

在执行上述示例代码时,< selectKey> 元素首先被执行,该元素通过自定义的语句设置数据表的主键,然后执行插入语句。

< selectKey> 元素的 keyProperty 属性指定了新生主键值返回给 PO 类(com.po.MyUser)的哪个属性。

  • order 属性可以设置为 BEFORE 或 AFTER。
  • BEFORE 表示先执行 < selectKey> 元素然后执行插入语句。
  • AFTER 表示先执行插入语句再执行 < selectKey> 元素。

< update>与< delete>元素

< update> 和 < delete> 元素比较简单,它们的属性和 < insert> 元素、< select> 元素的属性差不多,执行后也返回一个整数,表示影响了数据库的记录行数。配置示例代码如下:

<!-- 修改一个用户 -->
<update id="updateUser" parameterType="com.po.MyUser">
    update user set uname = #{uname},usex = #{usex} where uid = #{uid}
</update>
<!-- 删除一个用户 -->
<delete id="deleteUser" parameterType="Integer">
    delete from user where uid = #{uid}
</delete>

< sql> 元素

< sql> 元素的作用在于可以定义 SQL 语句的一部分(代码片段),以方便后面的 SQL 语句引用它,例如反复使用的列名。

在 MyBatis 中只需使用 < sql> 元素编写一次便能在其他元素中引用它。配置示例代码如下:

<sql id="comColumns">id,uname,usex</sql>
<select id="selectUser" resultType="com.po.MyUser">
    select <include refid="comColumns"> from user
</select>

在上述代码中使用 < include> 元素的 refid 属性引用了自定义的代码片段。

if标签

开发人员通常根据需求手动拼接 SQL 语句,这是一个极其麻烦的工作,而 MyBatis 提供了对 SQL 语句动态组装的功能,恰能解决这一问题。

MyBatis 的动态 SQL 元素与 JSTL 或 XML 文本处理器相似,常用 < if>、< choose>、< when>、< otherwise>、< trim>、< where>、< set>、< foreach> 和 < bind> 等元素。

动态 SQL 通常要做的事情是有条件地包含 where 子句的一部分,所以在 MyBatis 中 < if> 元素是最常用的元素,它类似于 Java 中的 if 语句。在 myBatisDemo03 应用中测试 < if> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用 if 元素根据条件动态查询用户信息-->
<select id="selectUserByIf" resultType="com.po.MyUser" parameterType="com.po.MyUser">
    select * from user where 1=1
    <if test="uname!=null and uname!=''">
        and uname like concat('%',#{uname},'%')
    </if >
    <if test="usex !=null and usex !=''">
        and usex=#{usex}
    </if >
</select>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public List<MyUser> selectUserByIf(MyUser user);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

// 使用 if 元素查询用户信息
MyUser ifmu=new MyUser();
ifmu.setUname ("张");
ifmu.setUsex ("女");
List<MyUser> listByif=userDao.selectUserByIf(ifmu);
System.out.println ("if元素================");
for (MyUser myUser:listByif) {
    System.out.println(myUser);
}

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

choose、when、otherwise标签

有些时候不想用到所有的条件语句,而只想从中择取一二,针对这种情况,MyBatis 提供了 < choose> 元素,它有点像 Java 中的 switch 语句。在 myBatisDemo03 应用中测试 < choose> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用choose、when、otherwise元素根据条件动态查询用户信息-->
<select id="selectUserByChoose" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
    select * from user where 1=1
    <choose>
        <when test="uname!=null and uname!=''">
            and uname like concat('%',#{uname},'%')
        </when>
        <when test="usex!=null and usex!=''">
            and usex=#{usex}
        </when>
        <otherwise>
            and uid > 10
        </otherwise>
    </choose>
</select>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public List<MyUser> selectUserByChoose(MyUser user);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

// 使用 choose 元素查询用户信息
MyUser choosemu=new MyUser();
choosemu.setUname("");
choosemu.setUsex("");
List<MyUser> listByChoose = UserDao.selectUserEyChoose(choosemu);
System.out.println ("choose 元素================");
for (MyUser myUser:listByChoose) {
    System.out.println(myUser);
}

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

trim、where、set标签

< trim>元素

< trim> 元素的主要功能是可以在自己包含的内容前加上某些前缀,也可以在其后加上某些后缀,与之对应的属性是 prefix 和 suffix。

可以把包含内容的首部某些内容覆盖,即忽略,也可以把尾部的某些内容覆盖,对应的属性是 prefixOverrides 和 suffixOverrides。正因为 < trim> 元素有这样的功能,所以也可以非常简单地利用 < trim> 来代替 < where> 元素的功能。

在 myBatisDemo03 应用中测试 < trim> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用trim元素根据条件动态查询用户信息-->
<select id="selectUserByTrim" resultType="com.po.MyUser"parameterType="com.po.MyUser">
    select * from user
    <trim prefix="where" prefixOverrides = "and | or">
        <if test="uname!=null and uname!=''">
            and uname like concat('%',#{uname},'%')
        </if>
        <if test="usex!=null and usex!=''">
            and usex=#{usex}
        </if>
    </trim>
</select>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public List<MyUser> selectUserByTrim(MyUser user);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

// 使用trim元素查询用户信息
MyUser trimmu=new MyUser();
trimmu.setUname ("张");
trimmu.setUsex("男");
List<MyUser> listByTrim=userDao.selectUserByTrim(trimmu);
System.out.println ("trim 元素=========================");
for (MyUser myUser:listByTrim) {
    System.out.println(myUser);
}

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

< where> 元素

< where> 元素的作用是会在写入 < where> 元素的地方输出一个 where 语句,另外一个好处是不需要考虑 < where> 元素里面的条件输出是什么样子的,MyBatis 将智能处理。如果所有的条件都不满足,那么 MyBatis 就会查出所有的记录,如果输出后是以 and 开头的,MyBatis 会把第一个 and 忽略。

当然如果是以 or 开头的,MyBatis 也会把它忽略;此外,在 < where> 元素中不需要考虑空格的问题,MyBatis 将智能加上。

在 myBatisDemo03 应用中测试 < where> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用where元素根据条件动态查询用户信息-->
<select id="selectUserByWhere" resultType="com.po.MyUser" parameterType="com.po.MyUser">
    select * from user
    <where>
        <if test="uname != null and uname ! = ''">
            and uname like concat('%',#{uname},'%')
        </if>
        <if test="usex != null and usex != '' ">
            and usex=#{usex}
        </if >
    </where>
</select>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public List<MyUser> selectUserByWhere(MyUser user);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

// 使用where元素查询用户信息
MyUser wheremu=new MyUser();
wheremu.setUname ("张");
wheremu.setUsex("男");
List<MyUser> listByWhere=userDao.selectUserByWhere(wheremu);
System.out.println ("where 元素=========================");
for (MyUser myUser:listByWhere) {
    System.out.println(myUser);
}

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

< set>元素

在动态 update 语句中可以使用 < set> 元素动态更新列。在 myBatisDemo03 应用中测试 < set> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用set元素动态修改一个用户-->
<update id="updateUserBySet" parameterType="com.po.MyUser">     
    update user
    <set>
        <if test="uname!=null">uname=#{uname}</if>
        <if test="usex!=null">usex=#{usex}</if>
    </set>
    where uid=#{uid}
</update>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public int updateUserBySet(MyUser user);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

// 使用set元素查询用户信息
MyUser setmu=new MyUser();
setmu.setUid (1);
setmu.setUname("张九");
int setup=userDao.updateUserBySet(setmu);
System.out.println ("set 元素修改了"+setup+"条记录");
System.out.println ("=========================")

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

foreach标签

< foreach> 元素主要用在构建 in 条件中,它可以在 SQL 语句中迭代一个集合。

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

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

在使用 < foreach> 元素时,最关键、最容易出错的是 collection 属性,该属性是必选的,但在不同情况下该属性的值是不一样的,主要有以下 3 种情况:

  • 如果传入的是单参数且参数类型是一个 List,collection 属性值为 list。
  • 如果传入的是单参数且参数类型是一个 array 数组,collection 的属性值为 array。
  • 如果传入的参数是多个,需要把它们封装成一个 Map,当然单参数也可以封装成 Map。Map 的 key 是参数名,collection 属性值是传入的 List 或 array 对象在自己封装的 Map 中的 key。

在 myBatisDemo03 应用中测试 < foreach> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用foreach元素查询用户信息-->
<select id="selectUserByForeach" resultType="com.po.MyUser" parameterType=
"List">
    select * from user where uid in
    <foreach item="item" index="index" collection="list"
    open="(" separator="," close=")">
        # {item}
    </foreach>
</select>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public List<MyUser> selectUserByForeach(List<Integer> listId);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

//使用foreach元素查询用户信息
List<Integer> listId=new ArrayList<Integer>();
listId.add(34);
listId.add(37);
List<MyUser> listByForeach = userDao.selectUserByForeach(listId);
System.out.println ("foreach元素================");
for(MyUser myUser : listByForeach) {
    System.out.println(myUser);
}

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

bind标签

在进行模糊查询时,如果使用“${}”拼接字符串,则无法防止 SQL 注入问题。如果使用字符串拼接函数或连接符号,但不同数据库的拼接函数或连接符号不同。

例如 MySQL 的 concat 函数、Oracle 的连接符号“||”,这样 SQL 映射文件就需要根据不同的数据库提供不同的实现,显然比较麻烦,且不利于代码的移植。幸运的是,MyBatis 提供了 < bind> 元素来解决这一问题。

在 myBatisDemo03 应用中测试 < bind> 元素,具体过程如下:

1)添加 SQL 映射语句

在 com.mybatis 包的 UserMapper.xml 文件中添加如下 SQL 映射语句:

<!--使用bind元素进行模糊查询-->
<select id="selectUserByBind" resultType="com.po.MyUser" parameterType= "com.po.MyUser">
    <!-- bind 中的 uname 是 com.po.MyUser 的属性名-->
    <bind name="paran_uname" value="'%' + uname + '%'"/>
        select * from user where uname like #{paran_uname}
</select>

2)添加数据操作接口方法

在 com.dao 包的 UserDao 接口中添加如下数据操作接口方法:

public List<MyUser> selectUserByBind(MyUser user);

3)调用数据操作接口方法

在 com.controller 包的 UserController 类中添加如下程序调用数据操作接口方法。

// 使用bind元素查询用户信息
MyUser bindmu=new MyUser();
bindmu.setUname ("张");
List<MyUser> listByBind=userDao.selectUserByBind(bindmu);
System.out.println ("bind 元素=========================");
for (MyUser myUser:listByBind) {
    System.out.println(myUser);
}

4)测试动态 SQL 语句

运行 com.controller 包中的 TestController 主类,测试动态 SQL 语句。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Apple_Web

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值