mybatis的mapper对应的xml写法
文章目录
- 前置
- mapper 对应 xml 基础配置
- mapper 对应 xml 复杂配置
- Mapper 中的相关注解
- 其他
前置
你使用
- java
- mybatis/mybatis plus
如果你使用 mybatis plus,也是会向下兼容 mybatis 的
mapper 对应 xml 基础配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.UserMapper"><!-- SQL 映射语句 --></mapper>
简单查询:
<!-- 简单查询 -->
<select id="getUserById" resultType="com.example.model.User">SELECT * FROM user WHERE id = #{id}
</select>
- id:与 Mapper 接口中的方法名一致
- resultType:返回值类型(Java 类的全限定名或别名)
- #{id}:预编译参数,防止 SQL 注入
- 如果返回 List,直接使用 resultType 即可,无需额外配置
简单插入:
<insert id="insertUser" parameterType="com.example.model.User">INSERT INTO user (name, age) VALUES (#{name}, #{age})
</insert>
- parameterType:输入参数类型(可选,MyBatis 可自动推断)
简单更新:
<update id="updateUser" parameterType="com.example.model.User">UPDATE user SET name = #{name}, age = #{age} WHERE id = #{id}
</update>
简单删除:
<delete id="deleteUserById" parameterType="int">DELETE FROM user WHERE id = #{id}
</delete>
mapper 对应 xml 复杂配置
resultMap 配置
当数据库字段名与 Java 对象属性名不一致时,需使用 映射。一般都需要配置
<resultMap id="userResultMap" type="com.example.model.User"><id property="id" column="user_id"/> <!-- 主键映射 --><result property="name" column="user_name"/> <!-- 字段映射 --><result property="age" column="user_age"/>
</resultMap><select id="getUserById" resultMap="userResultMap">SELECT user_id, user_name, user_age FROM user WHERE user_id = #{id}
</select>
if 条件
<select id="searchUsers" resultType="com.example.model.User">SELECT * FROM user<where><if test="name != null anconcatd name != ''">AND name LIKE CONCAT('%', #{name}, '%')</if><if test="age != null">AND age = #{age}</if></where>
</select>
在MyBatis中,如果不写这样的条件判断,如果是对表的写操作,如 update,其中的 set 中当name参数为null时,生成的SQL语句会直接包含name = null,从而将数据库中的对应字段更新为NULL。这是MyBatis的默认行为,需要开发者显式控制是否要过滤null值
多条件选择 choose
类似于 Java 中的 switch-case 或 if-else 逻辑
<choose>
的 <when>
是按顺序判断的,一旦某个条件满足,后续条件不再判断
<select id="findUser" resultType="com.example.model.User">SELECT * FROM user<where><choose><when test="type == 'name'">AND name = #{value}</when><when test="type == 'email'">AND email = #{value}</when><otherwise>AND status = 'active'</otherwise></choose></where>
</select>
<otherwise>
是可选的,但如果省略且所有 <when>
条件都不满足,会导致 SQL 语句不完整或无效
遍历集合 foreach
<select id="getUsersByIds" resultType="com.example.model.User">SELECT * FROM userWHERE id IN<foreach item="id" collection="ids" open="(" separator="," close=")">#{id}</foreach>
</select>
分页查询
<select id="getUsersByPage" resultType="com.example.model.User">SELECT * FROM userLIMIT #{offset}, #{limit}
</select>
你也可以使用 pagehelper 工具,更常用,那就不需要 limit offset
如果你使用 mybatis plus,也有自己的方式,可以使用 IPage 来分页
Mapper 中的相关注解
@Param注解
@Select("SELECT * FROM user WHERE name = #{user_name} AND age = #{user_age}")
User getUserByNameAndAge(@Param("user_name") String userName, @Param("user_age") int userAge);
如果没写 @Param,MyBatis 默认将未使用 @Param 注解的参数封装为 Map,键名为 param1、param2、…、paramN(按参数顺序递增),也就是说 sql 中应该写 #{param1}
和 #{param2}
其他
如果你不想使用 resultMap 来映射 mysql column 和 entity 的 field,还有其他办法吗?
方法一,使用 mybatis plus 的 @TableField 注解来指定 column 和 field 的映射
方法二:xml 中使用别名
<select id="getUserById" resultType="com.example.model.User">SELECT user_id AS id, user_name AS name, user_age AS age FROM user
</select>
choose when 和 if 区别
if 是独立的判断,而 choose when 更像 ifelse 逻辑,一旦判断一个满足,后续的 when 就不执行了!