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的标签介绍
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>