Mybatis及联查询
一对多与多对多
实体类Student
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private Classes classes;
}
实体类Classes
import lombok.Data;
import java.util.List;
@Data
public class Classes {
private int id;
private String name;
private List<Student> students;
}
⼀对一(association): 一个学生对应一个班级
StudentsMapper.xml
<resultMap id="studentMap" type="com.yt.pojo.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<!--一对一关联-->
<association property="classes" javaType="com.yt.pojo.Classes">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
</association>
</resultMap>
<select id="findById" parameterType="long" resultMap="studentMap">
select s.id,s.name,c.id as cid,c.name as cname from student s,classes c
where s.id = #{id} and s.cid = c.id
</select>
⼀对多(collection) 一个班级对应多个学生
ClassesMapper.xml
<resultMap id="classesMap" type="com.yt.pojo.Classes">
<id column="cid" property="id"></id>
<result column="cname" property="name"></result>
<!-- 一对多关联映射 -->
<collection property="students" ofType="com.yt.pojo.Student">
<id column="id" property="id"/>
<result column="name" property="name"/>
</collection>
</resultMap>
<select id="findById" parameterType="long" resultMap="classesMap">
select s.id,s.name,c.id as cid,c.name as cname from student s,classes c
where c.id = #{id} and s.cid = c.id
</select>
Mybatis延迟加载
什么是延迟加载?
延迟加载也叫懒加载,根据需求加载数据,加载部分显示的数据,如果需要其关联表的数据显示,再加载关联表数据显示。不同的业务需求,需要查询不同的表,根据具体的业务需求来动态减少数据表查询的⼯作就是延迟加载。
使⽤延迟加载可以提⾼程序的运⾏效率,从⼀定程度上减少了 Java应⽤与数据库的交互次数。
首先在 config.xml 中开启延迟加载
<settings>
<!-- 打印SQL便于观察查询过程-->
<setting name="logImpl" value="STDOUT_LOGGING" />
<!-- 开启延迟加载 -->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
将关联查询代码改为单表查询
<resultMap id="studentMapLazy" type="com.yt.pojo.Student">
<id column="id" property="id"></id>
<result column="name" property="name"></result>
<!--association节点加入懒加载需要的查询条件 和sql语句statementId 原始resultMap映射-->
<association property="classes" javaType="com.yt.pojo.Classes"
select="com.yt.repository.ClassesRepository.findByIdLazy" column="cid">
</association>
</resultMap>
<select id="findByIdLazy" parameterType="long" resultMap="studentMapLazy">
select * from student where id = #{id}
</select>
Mybatis动态SQL
动态 SQL 是 MyBatis 的强大特性之一。如果你使用过 JDBC 或其它类似的框架,你应该能理解根据不同条件拼接 SQL语句有多痛苦,利用动态 SQL,可以彻底摆脱这种痛苦。动态SQL主要通过这些标签:if、choose (when, otherwise)、trim (where, set)、foreach
动态查询
where标签 可以⾃动判断是否要删除语句块中的 and 关键字,如果检测到 where 直接跟 and 拼接,则⾃动删除 and。
if 标签可以⾃动根据表达式的结果来决定是否将对应的语句添加到 SQL 中,如果条件不成⽴则不添加,如果条件成⽴则添加。
select * from dome
<where>
<if test="id!=0">
id = #{id}
</if>
<if test="username!=null">
and username = #{username}
</if>
<if test="password!=null">
and password = #{password}
</if>
</where>
choose 、when 标签
select * from dome
<where>
<choose>
<when test="id!=0">
id = #{id}
</when>
<when test="username!=null">
username = #{username}
</when>
<when test="password!=null">
password = #{password}
</when>
</choose>
</where>
trim 标签中的 prefix 和 suffix 属性会被⽤于⽣成实际的 SQL 语句,会和标签内部的语句进⾏拼接,如果语句前后出现了 prefixOverrides 或者 suffixOverrides 属性中指定的值,MyBatis 框架会⾃动将其删除。
select * from dome
<trim prefix="where" prefixOverrides="and">
<if test="id!=0">
id = #{id}
</if>
<if test="username!=null">
and username = #{username}
</if>
<if test="password!=null">
and password = #{password}
</if>
</trim>
set标签
更新数据
update dome
<set>
<if test="username!=null">
username = #{username},
</if>
<if test="password!=null">
password = #{password},
</if>
</set>
where id = #{id}
foreach标签⽤于迭代数组元素 ,collection:指定输入的集合参数的参数名称、open:集合遍历时,需要拼接到遍历sql语句的前面、close:集合遍历时,需要拼接到遍历sql语句的后面、item:声明集合参数中的元素变量名、separator:集合遍历时,需要拼接到遍历sql语句之间的分隔符号
<where>
<foreach collection="ids" open="id in (" close=")" item="id"
separator=",">
#{id}
</foreach>
</where>
⭐完结