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();
相关推荐
高山上有一只小老虎3 小时前
mybatisplus分页查询版本 3.5.8 以下和版本 3.5.9及以上的区别
java·spring boot·mybatis
人道领域3 小时前
javaWeb从入门到进阶(MyBatis拓展)
java·tomcat·mybatis
J2虾虾12 小时前
SpringBoot和mybatis Plus不兼容报错的问题
java·spring boot·mybatis
pp起床1 天前
【苍穹外卖】Day03 菜品管理
java·数据库·mybatis
九皇叔叔1 天前
【01】SpringBoot3 MybatisPlus 工程创建
java·mybatis·springboot3·mybatis plus
BD_Marathon1 天前
MyBatis逆向工程之清晰简洁版
mybatis
九皇叔叔1 天前
【02】SpringBoot3 MybatisPlus 加入日志功能
java·mysql·mybatis·日志·mybatisplus
齐 飞1 天前
MybatisPlus真正的批量新增
spring boot·mybatis
小北方城市网1 天前
Spring Cloud Gateway 生产问题排查与性能调优全攻略
redis·分布式·缓存·性能优化·mybatis
while(1){yan}2 天前
Spring事务
java·数据库·spring boot·后端·java-ee·mybatis