MyBatis---动态SQL及关联映射
动态SQL语句的标签:
1 2 3 4 5 | < if > 基本的条件判断 <where> 配置查询条件 <set> 配置update语句 <trim> 自定义条件配置 <foreach> 循环标签 |
<if>标签:
作用:当条件成立,if中的SQL语句会和外面SQL语句拼接到一起
语法:
1 2 3 4 | SQL语句 < if test= "条件" > SQL语句 </ if > |
1 2 3 4 5 6 7 8 9 | <select id= "selecUser" parameterType= "User" > select * from tb_user where < if test= "username != null" > username = #{username} </ if > < if test= "realname != null" > and realname = #{realname} </ if > <select> |
问题:username为空且realname不为空时,会出现多余的and或where
<where>标签
作用:自动添加where,去掉多余的and、or、where
语法:
1 2 3 4 5 6 | sql语句 <where> < if test= "条件" > sql语句 </ if > </where> |
1 2 3 4 5 6 7 8 | <select id= "selecUser" parameterType= "User" > select * from tb_user <where> < if test= "username != null" > username = #{username} </ if > </where> <select > |
<set>标签
用于update语句,作用是:自动添加set,去掉多余的,
1 2 3 4 5 6 7 8 9 10 11 12 | <update> update tb_user <set> < if test= "username != null and username !=' ' " > username = #{username} </ if > < if test= "phone!= null and phone!=' ' " > and phone= #{phone} </ if > </set> where user_id = #{userId} </update> |
<trim>标签
作用:灵活配置添加前缀、后缀,删除前缀、后缀
语法:使用<trim>代替<set>
1 2 3 4 5 6 7 8 9 10 11 12 | <update id= "update" parameterType= "com.mx.mybatis.entity.User" > update tb_user <trim prefix= "set" suffixOverrides= "," > < if test= "userId!=null and userId!=''" > user_id = #{userId}, </ if > < if test= "username!=null and username!=''" > username = #{username}, </ if > </trim> where user_id = #{userId} </update> |
<foreach>标签
作用:循环添加SQL语句
语法:<foreach collection="参数集合名" item="变量名" open="开始符号" close="结束符号"
separator="分隔符" index="下标名">
注意:集合参数前添加@Param("名称")
List<User> selectUserByUsernames(@Param("usernames") List<String> usernames)
1 2 3 4 5 6 7 8 | <select id= "selectUserByUsernames" resultMap= "userMap" > select * from tb_user where username in <foreach collection= "usernames" item= "name" open= "(" close= ")" separator= "," index= "index" > #{name} </foreach> </select> |
对象的关联映射
对象之间的关联关系有:
一对一 如:用户和身份证
一对多 如:用户和评论,商品和订单
多对多 如:学生和课程
通过映射文件,实现对象和对象的关系
配置方式:
方式一:子查询
1. 查询用户
2. 按用户id查询用户所有评论
方式二:连接查询
内连接直接一次查询到两个表的数据
子查询:
配置查找用户所有的评论
1.在用户类添加评论的集合属性,并添加set、get方法
2.在CommentDao中定义按用户id查询评论的方法并在XML中实现
3.修改UserMapper.xml
在resultMap添加标签<collection>
collection 用于配置一对多关系的集合
property 配置集合名称
column配置查询集合需要的列
select配置查询集合需要的方法 包名.类名.方法名

配置通过评论找到用户
1.在评论类添加用户对象属性,并添加set、get方法
2. 在UserDao中定义按用户id查询用户的方法并在XML中实现
3.修改CommentMapper.xml
在resultMap添加标签<association>用于配置一对一关系的对象
<!--配置一对一的用户对象-->
<association property="user" column="user_id" select="com.qianfeng.mybatis.dao.UserMapper.selectById"/>
连接查询:
查询用户所有评论
1.在用户类添加评论的集合属性,并添加set、get方法
2.修改UserMapper.xml
在resultMap添加标签<collection>
ofType配置的是集合中对象的类型
javaType配置的是集合的类型
1 2 3 4 5 6 7 8 9 10 11 | <collection property= "comments" column= "user_id" ofType= "com.qianfeng.mybatis.entity.Comment" javaType= "java.util.ArrayList" > <!--配置主键 property配置Java类的属性名 column表的列名--> <id property= "commentId" column= "comment_id" ></id> <!--配置一般的列--> <result property= "time" column= "time" ></result> <result property= "stars" column= "stars" ></result> <result property= "userId" column= "user_id" ></result> <result property= "nannyId" column= "nanny_id" ></result> </collection> |
3. 把所有的用户的查询改成内连接
1 2 3 4 | <select id= "selectById" parameterType= "int" resultMap= "userMap" > <!--select * from tb_user where user_id = #{userId}--> select * from tb_user u,tb_comment c where u.user_id = c.user_id and u.user_id = #{userId} </select> |
对比子查询和内连接:
子查询不用修改每个查询,内连接需要修改每个查询为连接查询
子查询可以使用延迟加载,内连接不支持延迟加载
内连接只查询一次,子查询查询多次
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· Vue3状态管理终极指南:Pinia保姆级教程