ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

MyBatis(二、基础进阶)

2022-08-07 08:30:08  阅读:145  来源: 互联网

标签:进阶 基础 private 查询 println user sql MyBatis id


1、什么是动态sql语句?

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

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

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语句如下:

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语句如下:

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多表查询

一对一查询

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

​ 对应的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);
	}

一对多查询

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

​ 对应的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);
		}
}

多对多查询

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

​ 对应的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 > 做配置

标签:进阶,基础,private,查询,println,user,sql,MyBatis,id
来源: https://www.cnblogs.com/xmpy/p/16558420.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有