MyBatis动态SQL处理增删改查

MyBatis动态SQL处理增删改查


文章目录

  • MyBatis动态SQL处理增删改查
  • 前言
  • 一、动态sql的标签介绍
    • [1 < if>](#1 < if>)
    • [2 < where>](#2 < where>)
    • [3 < set>](#3 < set>)
    • [3 < trim>](#3 < trim>)
    • [4 < choose>,< when>,< otherwise>](#4 < choose>,< when>,< otherwise>)
    • [5 < foreach>](#5 < foreach>)
    • [6 自定义方法< sql>](#6 自定义方法< sql>)
  • 二、增删改查
    • [1 增](#1 增)
    • [2 删](#2 删)
    • [3 改](#3 改)
    • [4 查](#4 查)
  • 三、映射
    • [1 一对一(One-to-One)](#1 一对一(One-to-One))
    • [2 一对多(One-to-Many)/ 多对一(Many-to-One)](#2 一对多(One-to-Many)/ 多对一(Many-to-One))
    • [3 多对多](#3 多对多)

前言

动态查询一般都是以 Map 为基础制作

<resultMap type="userInfo" id="userInfo">
	<id column="userId" property="userId" />
	<result column="userName" property="userName" />
	<result column="salary" property="salary" />
</resultMap>

一、动态sql的标签介绍

参考:MyBatis动态SQL处理增删改查

1 < if>

通过 test属性中的表达式判断标签中的内容是否会拼接到sql中。

//查询用户信息1
List<UserInfo> selectUserInfo1(UserInfo userInfo);

注意这里sql语句最后有个空格!

<select id="selectUserInfo1" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<where>
		<if test="userId != null">
			AND userId = #{userId}
		</if>
		<if test="userName != null">
			AND userName = #{userName}
		</if>
		<if test="salary != null">
			AND salary = #{salary}
		</if>
	</where>
</select>

2 < where>

特点:

①若where标签中有条件成立,会自动生成where关键字

②会自动将where标签中内容前多余的and去掉,不过其中内容后多余的and无法去掉

③若where标签中没有任何一个条件成立,则where没有任何功能

3 < set>

修改信息"updete 表 set 修改字段"的set。

3 < trim>

属性 说明
prefix,suffix 在标签的前面或后面添加指定内容
prefixOverrides,suffixOverrides 在标签的前面或后面去掉指定内容
//查询用户信息2
List<UserInfo> selectUserInfo2(UserInfo userInfo);

这里区别于 <where>,AND放到后面

<!-- 查询用户信息2 -->
<select id="selectUserInfo2" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<trim prefix="WHERE" suffixOverrides="AND">
		<if test="userId != null">
			userId = #{userId} AND 
		</if>
		<if test="userName != null">
			userName = #{userName} AND 
		</if>
		<if test="salary != null">
			salary = #{salary} AND
		</if>
	</trim>
</select>

4 < choose>,< when>,< otherwise>

-相当于Java中的if、else if、else

when至少设置一个,otherwise至多设置一个

5 < foreach>

是动态SQL中的循环标签。 标签中属性作用:

属性 说明
collection 设置要循环的数组或集合(数组:array)
item 用一个字符串表示数组或集合中的每一个数据
separator 设置每次循环的数据之间的分隔符
open 循环的所有内容以什么开始
close 循环的所有内容以什么结束
//查询用户信息3
List<UserInfo> selectUserInfo3(Integer[] i);

<!-- 查询用户信息3 -->
<select id="selectUserInfo3" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<where>
		userId in
		<foreach collection="array" item="userId" open="(" close=")" separator=",">
			#{userId}
		</foreach>
	</where>
</select>

6 自定义方法< sql>

可以记录一段 sql,在需要用的地方使用 < include> 标签引用。

< sql id="方法id">sql< /sql>
< include refid="方法id" />

<!-- 自定义方法1 -->
<sql id="method_1">
	<if test="userId != null">
		AND userId = #{userId}
	</if>
	<if test="userName != null">
		AND userName = #{userName}
	</if>
	<if test="salary != null">
		AND salary = #{salary}
	</if>
</sql>

<!-- 查询用户信息1 -->
<select id="selectUserInfo1" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<where>
		<include refid="method_1" />
	</where>
</select>

二、增删改查

【MyBatis之SQL篇】 基本增删改查 + 动态sql + 批量增删改

1 增

//插入用户信息1
Integer insertUserInfo1(UserInfo userInfo);

//插入用户信息2
Integer insertUserInfo2(List<UserInfo> userInfos);

<!-- 插入用户信息1 -->
<insert id="insertUserInfo1">
	INSERT INTO Students(userName,salary) VALUES
	<trim prefix="(" suffix=")" suffixOverrides=",">
		<if test="userName != null">
			#{userName},
		</if>
		<if test="salary != null">
			#{salary},
		</if>
	</trim>
</insert>

<!-- 插入用户信息2 -->
<insert id="insertUserInfo2" parameterType="list">
	INSERT INTO Students(userName,salary)
	VALUES 
	<foreach collection="list" item="item" separator=",">
	    (#{item.userName},#{item.salary})
	</foreach>
</insert>

2 删

//删除用户信息
Integer deleteUserInfoById(Integer[] i);

<!-- 删除用户信息 -->
<select id="deleteUserInfoById">
	DELETE FROM Students
	<where>
		userId in
		<foreach collection="array" item="userId" open="(" close=")" separator=",">
			#{userId}
		</foreach>
	</where>
</select>

3 改

//修改用户信息1
Integer updateUserInfo1(UserInfo userInfo);

//修改用户信息2
Integer updateUserInfo2(UserInfo userInfo);

<!-- 自定义方法2 -->
<sql id="method_2">
	<if test="userName != null">
           userName = #{userName},
       </if>
       <if test="salary != null">
           salary = #{salary},
       </if>
</sql>

<!-- 修改用户信息1 -->
<update id="updateUserInfo1">
    UPDATE Students 
    <set>
        <include refid="method_2" />
    </set>
    <where>
        <if test="userId != null">
            userId = #{userId}
        </if>
    </where>
</update>

<!-- 修改用户信息2 -->
<update id="updateUserInfo2">
    UPDATE Students 
   	<trim prefix="set" suffixOverrides=",">
   		<include refid="method_2" />
   	</trim>
   	<where>
        <if test="userId != null">
            userId = #{userId}
        </if>
    </where>
</update>

4 查

//查询用户信息1
List<UserInfo> selectUserInfo(UserInfo userInfo);

//查询用户信息2
List<UserInfo> selectUserInfo2(UserInfo userInfo);

//查询用户信息3
List<UserInfo> selectUserInfo(Integer[] i);

<!-- 自定义方法1 -->
<sql id="method_1">
	<if test="userId != null">
		AND userId = #{userId}
	</if>
	<if test="userName != null">
		AND userName = #{userName}
	</if>
	<if test="salary != null">
		AND salary = #{salary}
	</if>
</sql>

<!-- 查询用户信息1 -->
<select id="selectUserInfo1" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<where>
		<include refid="method_1" />
	</where>
</select>

<!-- 查询用户信息2 -->
<select id="selectUserInfo2" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<trim prefix="WHERE" suffixOverrides="AND">
		<if test="userId != null">
			userId = #{userId} AND 
		</if>
		<if test="userName != null">
			userName = #{userName} AND 
		</if>
		<if test="salary != null">
			salary = #{salary} AND
		</if>
	</trim>
</select>

<!-- 查询用户信息3 -->
<select id="selectUserInfo3" resultMap="userInfo" >
	SELECT userId,userName,salary FROM Students 
	<where>
		userId in
		<foreach collection="array" item="userId" open="(" close=")" separator=",">
			#{userId}
		</foreach>
	</where>
</select>

三、映射

参考:MyBatis映射关系
对一:<association>
对多:<collection>

例子仅帮助理解

1 一对一(One-to-One)

一对一关系是指一个实体对象与另一个实体对象之间存在一对一的映射关系。在数据库中,通过共享主键或外键来实现。

在MyBatis中,你可以通过在< resultMap>中使用< association>元素来映射一对一关系。< association>元素允许你指定一个Java类型,并将查询结果映射到这个类型的属性上。

例子:身份证和学生一对一

Card .java

public class Card {
	
	//身份证编号
	private Integer id;
	
	//身份证号码
	private String num;
	
	//学生实体类对象
	private Student student;
	
	//....get,set
}

Student .java

public class Student {

	//学生编号
	private Integer id;
	
	//学生姓名
	private String name;
	
	//身份证实体类对象
	private Card card;
	
	//....get,set
}

StudentCardMapper .java

public interface StudentCardMapper {
	//根据id查询学生信息
	List<Student> selectStudentInfoById(Integer i); 
}

StudentCardMapper .xml

<mapper namespace="com.seiryo.dao.StudentCardMapper">
  
	<resultMap id="studentMap" type="student">
		<id property="id" column="id" />
		<result property="name" column="name" />
		<!-- 一对一映射 -->
		<association property="card" javaType="card">
			<id property="id" column="card_id" />
			<result property="num" column="card_num" />
		</association>
	</resultMap>
  
	<!-- 根据id查询学生信息 -->
	<select id="selectStudentInfoById" parameterType="int" resultMap="studentMap">
		SELECT s.id,s.name,c.id,c.num 
		FROM Students2 s 
		INNER JOIN Cards c 
		ON s.cid = c.id AND s.id = #{id}
	</select>
</mapper>

2 一对多(One-to-Many)/ 多对一(Many-to-One)

一对多关系是指一个实体对象可以关联多个其他实体对象。在数据库中,在一个表中存储另一个表的主键作为外键来实现。

在MyBatis中,你可以通过在< resultMap>中使用< collection>元素来映射一对多关系。< collection>元素允许你指定一个集合类型(如List),并将查询结果映射到这个集合中的对象上。

多对一关系是指多个实体对象可以关联到同一个实体对象。在数据库中,同样通过外键来实现。

在MyBatis中,多对一关系通常通过使用< association>元素来映射,就像一对一关系一样。不过,在这种情况下,多个记录可能会映射到同一个Java对象上。

例子:一对多(一个用户多个订单)、多对一(多个订单属于一个用户)

Order .java

public class Order {

	//订单编号
	private int id;

	//用户编号(外键)
	private int userId; 

	//订单内容
	private String description;
	
	//订单用户(多对一:多个订单属于一个用户)
	private User user;
		
	//....get,set
}

User .java

public class User {
	
	//用户编号
	private Integer id;
	
	//用户姓名
	private String name;
	
	//用户订单(一对多:一个用户多个订单)
	private List<Order> orders;
	
	//....get,set
}

OrderMapper.xml

<mapper namespace="com.seiryo.dao.OrderMapper">

	<resultMap id="orderResultMap" type="Order">
	    <id property="id" column="id" />
	    <result property="description" column="description" />
	    <!-- 多对一映射 -->
	    <association property="user" javaType="User">
	        <id property="id" column="user_id" />
	        <result property="name" column="user_name" />
	    </association>
	</resultMap>
	
</mapper>

UserMapper.xml

<mapper namespace="com.seiryo.dao.UserMapper">

	<resultMap id="userResultMap" type="User">
	    <id property="id" column="id" />
	    <result property="name" column="name" />
	    <!-- 一对多映射 -->
	    <collection property="orders" ofType="Order">
	        <id property="id" column="order_id" />
	        <result property="description" column="description" />
	    </collection>
	</resultMap>
	
</mapper>

3 多对多

多对多关系是指多个实体对象可以与多个其他实体对象关联。在数据库中,通常通过创建一个关联表(连接表或中间表)来实现,该表包含两个表的主键作为外键。

在MyBatis中,多对多关系通常也是通过使用< collection>元素来映射的。你需要查询关联表,并将结果映射到一个集合中,这个集合包含了与原始实体对象相关联的所有其他实体对象。

例子:课程列表和学生列表多对多

Course .java

public class Course {
	
	//课程编号
	private Integer id;
	
	//课程名
	private String name;
	
	//选修该课程的学生列表
	private List<Student> students;
		
	//....get,set
}

Student .java

public class Student {
	
	//学生编号
	private Integer id;
	
	//学生姓名
	private String name;
	
	//学生选修的课程列表
	private List<Course> courses;
			
	//....get,set
}

CourseMapper.xml

<mapper namespace="CourseMapper">
  
	<resultMap id="courseResultMap" type="Course">
	    <id property="id" column="id"/>
	    <result property="name" column="name"/>
	    <!-- 多对多映射选修该课程的学生 -->
	    <collection property="students" ofType="Student">
	        <id property="id" column="student_id"/>
	        <result property="name" column="student_name"/>
	    </collection>
	</resultMap>
	
	<select id="selectCourseAndStudents" resultMap="courseResultMap">
	    SELECT
	        c.id AS id,
	        c.name AS name,
	        s.id AS student_id,
	        s.name AS student_name
	    FROM
	        Course c
	    LEFT JOIN
	        Student_Course sc ON c.id = sc.course_id
	    LEFT JOIN
	        Student s ON sc.student_id = s.id
	    WHERE
	        c.id = #{id}
	</select>
  
</mapper>

StudentMapper.xml

<mapper namespace="StudentMapper">

	<resultMap id="studentResultMap" type="Student">
	    <id property="id" column="id"/>
	    <result property="name" column="name"/>
	    <!-- 多对多映射学生选修的课程 -->
	    <collection property="courses" ofType="Course">
	        <id property="id" column="course_id"/>
	        <result property="name" column="course_name"/>
	    </collection>
	</resultMap>
	
	<select id="selectStudentAndCourses" resultMap="studentResultMap">
	    SELECT
	        s.id AS id,
	        s.name AS name,
	        c.id AS course_id,
	        c.name AS course_name
	    FROM
	        Student s
	    LEFT JOIN
	        Student_Course sc ON s.id = sc.student_id
	    LEFT JOIN
	        Course c ON sc.course_id = c.id
	    WHERE
	        s.id = #{id}
	</select>
</mapper>
相关推荐
老王笔记22 分钟前
MySQL如何区分幻读和不可重复读
数据库·mysql
不爱学习的啊Biao23 分钟前
【08】MySQL复杂查询:子查询语句详解与示例
数据库·mysql·子查询
st_3329 分钟前
Junit5 单元测试入门
数据库·单元测试·log4j
s***g54031 分钟前
MySQL-操作数据库备份与恢复
数据库·mysql
CQU_JIAKE1 小时前
11.5【算法】6-1 表彰优秀学生(多态)
数据库
Elastic 中国社区官方博客2 小时前
使用数据层进行数据生命周期管理
大数据·数据库·elasticsearch·搜索引擎·全文检索·时序数据库
我爱李星璇2 小时前
Spring Boot项目的创建
java·数据库·spring boot
锵锵锵锵~蒋2 小时前
实时数据开发|Flink异步IO--提升性能和吞吐量
jvm·数据库·flink·实时数据开发
小麦项目管理指南3 小时前
工程企业需要什么样的财务软件?
大数据·数据库·信息可视化·项目管理
青云交3 小时前
大数据新视界 -- Hive 元数据管理:核心元数据的深度解析(上)(27 / 30)
hive·sql·元数据管理·数据目录·核心元数据·元数据存储·元数据操作·大数据管理基石