MyBatis开发中常用总结

文章目录

常用MyBatis参数映射

单个参数

XML中可以通过 #{xxx}, #{param1} 来获取Mapper接口中的单个参数没有任何限制,即使前后名字不一致的同时也没有@Param注解别名也能传入给XML

但为了开发规范尽量使用和入参时一样,使用@Param注解约定好名称

java 复制代码
// Mapper
User selectUserById(Long id);

// XML
<select id="selectUserById" parameterType="long" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{123}
</select>

多个参数

使用索引【不推荐】

java 复制代码
// Mapper
User selectUserByIdAndName(Long id, String username);

// XML
<select id="selectUserByIdAndName" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{param1} AND username = #{param2}
</select>

@Param注解

java 复制代码
// Mapper
User selectUserByIdAndName(@Param(value = "id") Long id, @Param(value = "username") String username);

// XML
<select id="selectUserByIdAndName" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{id} AND username = #{username}
</select>

Map传参

Mybatis底层也是通过 Map 传参,因此传入也可以一个 Map 作为参数。Map 中的 key 就对应 XML 中 #{key}

单Map参数

java 复制代码
// Mapper
User selectUserByIdAndNameMap(Map<String, Object> map);

// XML
<select id="selectUserByIdAndNameMap" parameterType="map" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{id} AND username = #{username}
</select>

简单类型+map

java 复制代码
// Mapper
User selectUserByIdAndNameMap(@Param(value = "id") Long id,  Map<String, Object> map);

// XML
<select id="selectUserByIdAndNameMap" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{id} AND username = #{map.username}
</select>

简单类型+map

java 复制代码
// Mapper
User selectUserByIdAndNameMap(@Param(value = "id") Long id,  @Param(value = "map") Map<String, Object> map);

// XML
<select id="selectUserByIdAndNameMap" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{id} AND username = #{map.username}
</select>

测试

java 复制代码
Map<String, Object> map=new HashMap<>();
map.put("id", 1);
map.put("username", "Jack");
// 单 map 参数
User user = userMapper.selectUserByIdAndNameMap(map);
// 简单参数+map
User user = userMapper.selectUserByIdAndNameMap(2L, map);

POJO【推荐】

多个参数可以使用实体类封装,key就是属性名,实体类需要有 getXXX()方法

不使用@Param注解

java 复制代码
// Mapper
User selectUserByEntity(User user);

// XML
<select id="selectUserByEntity" parameterType="app.domain.po.User" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{id} AND username = #{username}
</select>

使用@Para注解

java 复制代码
// Mapper
User selectUserByEntity(@Param(value = "user") User user);

// XML
<select id="selectUserByEntity" parameterType="app.domain.po.User" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id = #{user.id} AND username = #{user.username}
</select>

测试

java 复制代码
User user=new User();
user.setId(1L);
user.setUsername("Jack");
User entity = userMapper.selectUserByEntity(user);

List

java 复制代码
// Mapper
List<User> selectList(@Param(value = "ids") List<Long> ids);

// XML
<select id="selectList" parameterType="list" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id IN
    <foreach collection="ids" item="item" separator=", " open="(" close=")">
        #{item}
    </foreach>
</select>

测试

java 复制代码
List<Long> ids = List.of(1L, 2L, 3L);
List<User> userList = userMapper.selectList(ids);

数组

java 复制代码
// Mapper
List<User> selectArray(@Param(value = "ids") Long[] ids);

// XML
<select id="selectArray" parameterType="arraylist" resultMap="BaseResultMap">
    SELECT * FROM user WHERE id IN
    <foreach collection="ids" item="item" separator=", " open="(" close=")">
        #{item}
    </foreach>
</select>

测试

java 复制代码
Long[] idsArray = ids.toArray(new Long[0]);
userList = userMapper.selectArray(idsArray);

动态标签

<if>标签

  • if标签中的test是传入对象的属性

mapper

java 复制代码
int addUser(@Param(value = "userInfo") UserInfo userInfo);

xml

xml 复制代码
<insert id="addUser" useGeneratedKeys="true" parameterType="app.model.UserInfo" keyColumn="id" keyProperty="id">
    INSERT INTO userinfo(
    username
    ,password
    <if test="userInfo.photo != null">
        ,photo
    </if>
    )
    VALUES(
    #{userInfo.name}
    ,#{userInfo.password}
    <if test="userInfo.photo != null">
        ,#{userInfo.photo}
    </if>
    )
</insert>

<trim>标签

  • prefix:表示整个语句块,以prefix的值作为前
  • suffix:表示整个语句块,以suffix的值作为后缀
  • prefixOverrides:表示整个语句块要去除掉的前
  • suffixOverrides:表示整个语句块要去除掉的后缀

mapper

java 复制代码
int addUser(@Param(value = "userInfo") UserInfo userInfo);

xml

xml 复制代码
<insert id="addUser" useGeneratedKeys="true" parameterType="app.model.UserInfo" keyColumn="id" keyProperty="id">
    INSERT INTO userinfo
       <trim prefix="(" suffix=")" suffixOverrides=",">
            username,
            password,
            <if test="userInfo.photo != null">
                photo,
            </if>
        </trim>
    VALUES
    <trim prefix="(" suffix=")" suffixOverrides=",">
        #{userInfo.name},
        #{userInfo.password},
        <if test="userInfo.photo != null">
            #{userInfo.photo}
        </if>
    </trim>
</insert>

<where>标签

  • where标签会自动清除掉第一个if标签中第一个多余的 and字符串,因此也可以用 <trim prefix="where" preffixOverrides="and"></trim> 替换掉where标签。但一般不这么用
java 复制代码
List<UserInfo> selectUserByCondition(@Param(value = "userInfo") UserInfo userInfo);

xml

xml 复制代码
<select id="selectUserByCondition" parameterType="app.model.UserInfo" resultMap="BaseMap">
    SELECT *
    FROM userinfo
    <where>
        <if test="userInfo.name != null">
            and username = #{userInfo.name}
        </if>
        <if test="userInfo.photo != null">
            and photo = #{userInfo.photo}
        </if>
        <if test="userInfo.createTime != null">
            and DATE_FORMAT(createtime, '%Y-%m-%d %H:%i:%s') >= DATE_FORMAT(#{userInfo.createTime}, '%Y-%m-%d %H:%i:%s')
        </if>
        <if test="userInfo.updateTime != null">
            and DATE_FORMAT(updatetime, '%Y-%m-%d %H:%i:%s') >= DATE_FORMAT(#{userInfo.updateTime}, '%Y-%m-%d %H:%i:%s')
        </if>
        <if test="userInfo.state != null">
            and state = #{userInfo.state}
        </if>
    </where>
</select>

<set>标签

  • set标签会自动去除掉最后一个SQL的逗号:","。同理,也可以是用 <trime prefix="set" suffixOverridex=",></trim> 替换掉set标签。但一般不这么做

mapper

java 复制代码
int updateUserByCondition(@Param("userInfo") UserInfo userInfo);

xml

xml 复制代码
<update id="updateUserByCondition">
    UPDATE userinfo
    <set>
        <if test="userInfo.name != null">
            username = #{userInfo.name},
        </if>
        <if test="userInfo.photo != null">
            photo = #{userInfo.photo},
        </if>
    </set>
    <where>
        <if test="userInfo.id != null">
            and id >= #{userInfo.id}
        </if>
        <if test="userInfo.createTime != null">
            and DATE_FORMAT(createtime, '%Y-%m-%d %H:%i:%s') >= DATE_FORMAT(#{userInfo.createTime}, '%Y-%m-%d %H:%i:%s')
        </if>
    </where>
</update>

<foreach>标签

  • collection:绑定方法参数中的集合的名称,如 List,Set,Map或数组对象「一般配合@Param注解搭配名称使用」
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • item:遍历时的每一个对象
  • separator:每次遍历之间间隔的字符串

mapper

java 复制代码
int deleteUserByIds(@Param("idList") List<Integer> idList);

xml

xml 复制代码
<delete id="deleteUserByIds">
    DELETE
    FROM userinfo
    WHERE id IN
    <foreach collection="idList" open="(" close=")" item="id" separator=",">
        #{id}
    </foreach>
</delete>

MyBatis查询

一对一

数据库

sql 复制代码
CREATE TABLE `orders` (
  `id` int NOT NULL AUTO_INCREMENT,
  `amount` decimal(11,2) DEFAULT NULL,
  `uid` int NOT NULL,
  PRIMARY KEY (`id`,`uid`) USING BTREE
)

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
  PRIMARY KEY (`id`)
)

一个用户有多个订单【这里只查询一个订单,一对多中会查询多个订单】,一个订单只从属于一个用户

sql 复制代码
SELECT o.id  o_id,
       o.amount,
       o.uid o_uid,
       u.id  u_id,
       u.username
FROM orders o
         LEFT JOIN `user` u ON o.uid = u.id;

用户实体类

java 复制代码
import lombok.Data;

@Data
public class User {
    private Long id;
    private String username;
}

订单实体类

java 复制代码
import lombok.Data;

@Data
public class Order {
    private Long id;
    private Double amount;
    private Long uid;

    // 一对一: 当前订单从属于哪个用户
    private User user;
}

XML方案一:通过构造新的实体类,resultMap 完成数据封装返回

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="app.mapper.OrderMapper">
    <resultMap id="OrderResultMap" type="app.domain.po.Order">
        <!--
		id: 主键
		property: 实体类属性
		column: 查询出来的数据库字段
		-->
        <id property="id" column="o_id"/>
        <result property="amount" column="amount"/>
        <result property="uid" column="o_uid"/>
        
        <!-- 一对一 -->
        <result property="user.id" column="u_id"/>
        <result property="user.username" column="username"/>
    </resultMap>

    <select id="selectAllOrder" resultMap="OrderResultMap">
        SELECT o.id  o_id,
               o.amount,
               o.uid o_uid,
               u.id  u_id,
               u.username
        FROM orders o
                 LEFT JOIN `user` u ON o.uid = u.id;
    </select>
</mapper>

XML方案二:使用 resultMap 中的 association 完成封装

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="app.mapper.OrderMapper">
    <resultMap id="OrderResultMap" type="app.domain.po.Order">
        <id property="id" column="o_id"/>
        <result property="amount" column="amount"/>
        <result property="uid" column="o_uid"/>
        
        <!-- 一对一 -->
        <association property="user">
            <id property="id" column="u_id"/>
            <result property="username" column="username"/>
        </association>
    </resultMap>

    <select id="selectAllOrder" resultMap="OrderResultMap">
        SELECT o.id  o_id,
               o.amount,
               o.uid o_uid,
               u.id  u_id,
               u.username
        FROM orders o
                 LEFT JOIN `user` u ON o.uid = u.id;
    </select>
</mapper>

Mapper接口

java 复制代码
List<Order> selectAll();

一对多

数据库

sql 复制代码
CREATE TABLE `orders` (
  `id` int NOT NULL AUTO_INCREMENT,
  `amount` decimal(11,2) DEFAULT NULL,
  `uid` int NOT NULL,
  PRIMARY KEY (`id`,`uid`) USING BTREE
)

CREATE TABLE `user` (
  `id` int NOT NULL AUTO_INCREMENT,
  `username` varchar(256) COLLATE utf8mb4_general_ci DEFAULT NULL,
  PRIMARY KEY (`id`)
)

一个用户有多个订单,一个订单只从属于一个用户

sql 复制代码
SELECT u.id  u_id,
       u.username,
       o.id  o_id,
       o.amount,
       o.uid o_uid
FROM `user` u
         LEFT JOIN orders o ON u.id = o.uid;

用户实体类

java 复制代码
import lombok.Data;

import java.util.List;

@Data
public class User {
    private Long id;
    private String username;

    // 一对多: 当前用户有哪些订单
    private List<Order> orderList;
}

订单实体类

java 复制代码
import lombok.Data;

@Data
public class Order {
    private Long id;
    private Double amount;
    private Long uid;

    // 一对一: 当前订单从属于哪个用户
    private User user;
}

XML

xml 复制代码
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="app.mapper.UserMapper">
    <resultMap id="UserResultMap" type="app.domain.po.User">
        <id property="id" column="u_id"/>
        <result property="username" column="username"/>

        <!-- 
				一对多
				ofType: 指定集合中的数据类型
				-->
        <collection property="orderList" ofType="app.domain.po.Order">
            <id property="id" column="o_id"/>
            <result property="amount" column="amount"/>
            <result property="uid" column="o_uid"/>
        </collection>
    </resultMap>

    <select id="selectAll" resultMap="UserResultMap">
        SELECT u.id  u_id,
               u.username,
               o.id  o_id,
               o.amount,
               o.uid o_uid
        FROM `user` u
                 LEFT JOIN orders o ON u.id = o.uid
    </select>
</mapper>

Mapper

java 复制代码
List<User> selectAll();
相关推荐
油丶酸萝卜别吃5 小时前
MyBatis中XML文件的模板
xml·数据库·mybatis
菠萝咕噜肉i6 小时前
MyBatis是什么?为什么有全自动ORM框架还是MyBatis比较受欢迎?
java·mybatis·框架·半自动
向阳12187 小时前
mybatis 缓存
java·缓存·mybatis
一只淡水鱼668 小时前
【mybatis】详解 # 和 $ 的区别,两者分别适用于哪种场景,使用 $ 不当会造成什么影响
sql·spring·mybatis·sql注入
秋恬意8 小时前
IBatis和MyBatis在细节上的不同有哪些
java·mybatis
赖龙9 小时前
springboot restful mybatis连接mysql返回日期格式不对
spring boot·mybatis·restful
皓木.10 小时前
苍穹外卖——准备工作
java·数据库·mybatis
憶巷12 小时前
MyBatis中动态SQL执行原理
java·sql·mybatis
一只淡水鱼6613 小时前
【mybatis】基本操作:详解Spring通过注解和XML的方式来操作mybatis
java·数据库·spring·mybatis
秋恬意1 天前
Mybatis能执行一对一、一对多的关联查询吗?都有哪些实现方式,以及它们之间的区别
java·数据库·mybatis