MyBatis(二、基础进阶)

简介: mybatis多表查询,一对一,一对多,多对多动态sql < if > < foreach >MyBatis映射文件配置

1、什么是动态sql语句?

动态sql语句概述:Mybatis 的映射文件中,前面我们的 SQL 都是比较简单的,有些时候业务逻辑复杂时,我们的 SQL是动态变化的, 此时在前面的学习中我们的 SQL 就不能满足要求了。

参考的官方文档,描述如下:

image-20220806182634195.png

2、动态sql语句

1) 动态 SQL 之< if />

我们根据实体类的不同取值,使用不同的 SQL语句来进行查询。比如在 id如果不为空时可以根据id查询,如果 username 不同空时还要加入用户名作为条件。这种情况在我们的多条件组合查询中经常会碰到。

 

<selectid="findByCondition"parameterType="user"resultType="user"><includerefid="selectUser"></include><where><iftest="id!=0">andid=#{id}
</if><iftest="username!=null">andusername=#{username}
</if><iftest="password!=null">andpasswords=#{passwords}
</if></where></select>

当查询条件id和username都存在时,控制台打印的sql语句如下:

image-20220806183207984.png

2) 动态 SQL 之< foreach >

循环执行sql的拼接操作,例如:SELECT * FROM USER WHERE id IN (1,2,5)。

<selectid="findByIds"parameterType="list"resultType="user"><includerefid="selectUser"></include><where><foreachcollection="list"open="id in("close=")"item="id"separator=",">#{id}
</foreach></where></select>

控制台打印的sql语句如下:

image-20220806183333423.png

foreach标签的属性含义如下:

< foreach >标签用于遍历集合,它的属性:

  • collection:代表要遍历的集合元素,注意编写时不要写#{}
  • open:代表语句的开始部分
  • close:代表结束部分
  • item:代表遍历集合的每个元素,生成的变量名
  • sperator:代表分隔符

3、SQL片段抽取

Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的

   <!--sql语句抽取-->

   <sql id="selectUser">select * from user</sql>

   <select id="findByCondition" parameterType="user" resultType="user">

       <include refid="selectUser"></include>

       <where>

           <if test="id!=0">

               and id=#{id}

           </if>

           <if test="username!=null">

               and username=#{username}

           </if>

           <if test="password!=null">

               and passwords=#{passwords}

           </if>

       </where>

   </select>

   <select id="findByIds" parameterType="list" resultType="user">

       <include refid="selectUser"></include>

       <where>

           <foreach collection="list" open="id in(" close=")" item="id" separator=",">

               #{id}

           </foreach>

       </where>

   </select>

4、MyBatis映射文件配置:

< select > :查询

< insert > :插入

< update>:修改

< delete > :删除

< where> :where条件

< if>:if判断

< foreach > :循环

< sql > :sql片段抽取

5、plugins标签

MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即 可获得分页的相关数据 开发步骤:

① 导入通用PageHelper的坐标

<!--分页助手--><dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>3.7.5</version></dependency><dependency><groupId>com.github.jsqlparser</groupId><artifactId>jsqlparser</artifactId><version>0.9.1</version></dependency>

② 在mybatis核心配置文件中配置PageHelper插件

<!-- 注意:分页助手的插件 配置在通用馆mapper之前 -->

<plugin interceptor="com.github.pagehelper.PageHelper">

       <!-- 指定方言 -->

       <property name="dialect" value="mysql"/>

</plugin>

③ 测试分页数据获取

@TestpublicvoidtestPageHelper(){
//设置分页参数PageHelper.startPage(1,2);
List<User>select=userMapper2.select(null);
for(Useruser : select){
System.out.println(user);
    }
}

获得分页相关的其他参数

PageInfo<User> pageInfo = new PageInfo<User>(select);

System.out.println("总条数:"+pageInfo.getTotal());

System.out.println("总页数:"+pageInfo.getPages());

System.out.println("当前页:"+pageInfo.getPageNum());

System.out.println("每页显示长度:"+pageInfo.getPageSize());

System.out.println("是否第一页:"+pageInfo.isIsFirstPage());

System.out.println("是否最后一页:"+pageInfo.isIsLastPage());

6、Mybatis多表查询

一对一查询

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户。

image-20220806184809381.png

对应的sql语句:

select*fromorderso,useruwhereo.uid=u.id;

创建Order和User实体:

publicclassUser {
privateintid;
privateStringusername;
privateStringpassword;
privateDatebirthday;
}
publicclassOrder {
privateintid;
privateDateordertime;
privatedoubletotal;
//代表当前订单从属于哪一个客户privateUseruser;
}
创建OrderMapper接口:publicinterfaceOrderMapper {
List<Order>findAll();
}

配置OrderMapper.xml:

<mapper namespace="com.xmp.mapper.OrderMapper">

<resultMap id="orderMap" type="com.xmp.domain.Order">

<result column="uid" property="user.id"></result>

<result column="username" property="user.username"></result>

<result column="passwords" property="user.passwords"></result>

<result column="birthday" property="user.birthday"></result>

</resultMap>

<select id="findAll" resultMap="orderMap">

select * from orders o,user u where o.uid=u.id

</select>

</mapper>

Test

OrderMappermapper=sqlSession.getMapper(OrderMapper.class);
List<Order>all=mapper.findAll();
for(Orderorder : all){
System.out.println(order);
 }


一对多查询

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单。

image-20220806185205589.png

对应的sql语句:

select*,o.idoidfromuseruleftjoinordersoonu.id=o.uid;

修改User实体:

publicclassUser {
privateintid;
privateStringusername;
privateStringpassword;
privateDatebirthday;
//代表当前用户具备哪些订单privateList<Order>orderList;
}

创建UserMapper接口:

publicinterfaceUserMapper {
List<User>findAll();
}

配置UserMapper.xml:

<mapper namespace="com.xmp.mapper.UserMapper">

<resultMap id="userMap" type="com.xmp.domain.User">

<result column="id" property="id"></result>

<result column="username" property="username"></result>

<result column="password" property="password"></result>

<result column="birthday" property="birthday"></result>

  <collection property="orderList" ofType="com.xmp.domain.Order">

  <result column="oid" property="id"></result>

  <result column="ordertime" property="ordertime"></result>

  <result column="total" property="total"></result>

  </collection>

</resultMap>

<select id="findAll" resultMap="userMap">

select *,o.id oid from user u left join orders o on u.id=o.uid

</select>

</mapper>


Test:

UserMappermapper=sqlSession.getMapper(UserMapper.class);
List<User>all=mapper.findAll();
for(Useruser : all){
System.out.println(user.getUsername());
List<Order>orderList=user.getOrderList();
for(Orderorder : orderList){
System.out.println(order);
    }
}

多对多查询

用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用 多对多查询的需求:查询用户同时查询出该用户的所有角色。

image-20220806185625660.png

对应的sql语句:

selectu.*,r.*,r.idridfromuseruleftjoinuser_roleuronu.id=ur.user_idinnerjoinroleronur.role_id=r.id;

创建Role实体,修改User实体

public class User {

private int id;

private String username;

private String password;

private Date birthday;

//代表当前用户具备哪些订单

private List<Order> orderList;

//代表当前用户具备哪些角色

private List<Role> roleList;

}

public class Role {

private int id;

private String rolename;

}

添加UserMapper接口方法

List<User>findAllUserAndRole();

配置UserMapper.xml

<resultMap id="userRoleMap" type="com.itheima.domain.User">

<result column="id" property="id"></result>

<result column="username" property="username"></result>

<result column="password" property="password"></result>

<result column="birthday" property="birthday"></result>

<collection property="roleList" ofType="com.itheima.domain.Role">

  <result column="rid" property="id"></result>

  <result column="rolename" property="rolename"></result>

</collection>

</resultMap>

<select id="findAllUserAndRole" resultMap="userRoleMap">

select u.*,r.*,r.id rid from user u left join user_role ur on

u.id=ur.user_id

inner join role r on ur.role_id=r.id

</select>


Test:

UserMappermapper=sqlSession.getMapper(UserMapper.class);
List<User>all=mapper.findAllUserAndRole();
for(Useruser : all){
System.out.println(user.getUsername());
List<Role>roleList=user.getRoleList();
for(Rolerole : roleList){
System.out.println(role);
 }
}

MyBatis多表配置方式:

  • 一对一配置:使用< resultMap >做做配置
  • 一对多配置:使用< resultMap >+< collection >做配置
  • 多对多配置:使用< resultMap >+< collection > 做配置
相关文章
|
7月前
|
SQL Java 数据库连接
MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射
MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射
165 0
|
3月前
|
SQL XML Java
【JavaEE进阶】 MyBatis之动态SQL
【JavaEE进阶】 MyBatis之动态SQL
|
3月前
|
XML Java 数据库连接
【JavaEE进阶】 MyBatis使用XML实现增删改查
【JavaEE进阶】 MyBatis使用XML实现增删改查
|
3月前
|
Java 关系型数据库 数据库连接
【JavaEE进阶】 MyBatis使用注解实现增删改查
【JavaEE进阶】 MyBatis使用注解实现增删改查
|
3月前
|
Java 关系型数据库 数据库连接
【JavaEE进阶】MyBatis⼊⻔
【JavaEE进阶】MyBatis⼊⻔
|
8月前
|
SQL Java 数据库连接
MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射,让你在面试中脱颖而出!!
MyBatis进阶:掌握MyBatis动态SQL与模糊查询、结果映射,让你在面试中脱颖而出!!
141 0
|
7月前
|
SQL Java 数据库连接
“MyBatis进阶:分页与特殊字符处理“
“MyBatis进阶:分页与特殊字符处理“
21 0
|
8月前
|
SQL XML Java
MyBatis进阶:告别SQL注入!MyBatis分页与特殊字符的正确使用方式
MyBatis进阶:告别SQL注入!MyBatis分页与特殊字符的正确使用方式
163 0
|
11月前
|
SQL Java 程序员
Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)(3)
Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)
121 0
|
11月前
|
数据库 数据安全/隐私保护
Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)(2)
Mybatis-Plus 进阶开发 -- Mybatis-Plus 入门教程(二)
108 0