MyBatis(二、基础进阶)


1、什么是动态sql语句?

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

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

MyBatis(二、基础进阶)

2、动态sql语句

1) 动态 SQL 之< if />

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

    <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>

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

MyBatis(二、基础进阶)

2) 动态 SQL 之< foreach >

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

 	<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>

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

MyBatis(二、基础进阶)

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>

③ 测试分页数据获取

@Test
public void testPageHelper(){
	//设置分页参数
	PageHelper.startPage(1,2);
	List<User> select = userMapper2.select(null);
	for(User user : 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多表查询

一对一查询

​ 用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户 一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户。
MyBatis(二、基础进阶)

​ 对应的sql语句:

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

​ 创建Order和User实体:

public class User {
	private int id;
	private String username;
	private String password;
	private Date birthday;
}
public class Order {
	private int id;
	private Date ordertime;
	private double total;
	//代表当前订单从属于哪一个客户
	private User user;
}

​ 创建OrderMapper接口:

public interface OrderMapper {
	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

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

一对多查询

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

MyBatis(二、基础进阶)

​ 对应的sql语句:

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

​ 修改User实体:

public class User {
	private int id;
	private String username;
	private String password;
	private Date birthday;
	//代表当前用户具备哪些订单
	private List<Order> orderList;
}

​ 创建UserMapper接口:

public interface UserMapper {
	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:

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

多对多查询

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

MyBatis(二、基础进阶)

​ 对应的sql语句:

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;

​ 创建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:

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

MyBatis多表配置方式:

  • 一对一配置:使用< resultMap >做做配置
  • 一对多配置:使用< resultMap >+< collection >做配置
  • 多对多配置:使用< resultMap >+< collection > 做配置

原创文章,作者:ItWorker,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/279333.html

(0)
上一篇 2022年8月7日 10:24
下一篇 2022年8月7日 10:51

相关推荐

发表回复

登录后才能评论