mybatis/mybatis-plus 自定义SQL(多表查询)
转:https://blog.csdn.net/aiwangtingyun/article/details/120225563
一、Mapper.java 和 Mapper.xml 映射关系
Mybatis 为我们提供了基本的增删改查的接口,特别是 Mybatis-Plus 提供的 Wrappers 更是可以组合出更复杂的查询语句以满足我们需求。但有些复杂的操作,比如联表查询等,这些就需要使用自定义 SQL 语句进行操作的。
而编写自定义 SQL 的操作为:
- 在 Java 包下创建 xxxMapper.java 接口类,然后再 resources 资源包下创建对应的 xxxMapper.xml 文件;
- 创建好 .java 和 .xml 文件后,在 Java 文件编写接口方法,然后再 xml 文件中编写对应方法的 SQL 语句;
- 当调用接口中方法后,Mybatis 就会去 xml 文件中找到对应的 SQL。
那么,现在的问题是:Mybatis 是如何将接口中的方法与 xml 文件中的 SQL 关联起来的呢?
下面我们以一个具体实例进行讲解,下面是接口文件内容:
package com.example.demo.mapper; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.example.demo.model.User; import org.apache.ibatis.annotations.Param; public interface UserMapper extends BaseMapper<User> { /** * 根据名称查询用户 * @param name 用户名 * @return 用户实体 */ User selectByName(@Param("name") String name); }
然后在 resource 下创建对应的 xml 文件:
<?xml version="1.0" encoding="utf-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace="com.example.demo.mapper.UserMapper"> <!-- selectByName --> <select id="selectByName" resultType="com.example.demo.model.User"> select * from `user` where `name` = #{name} </select> </mapper>
现在,我们可以解答它们的映射原理了:
- xml 文件关联 .java 文件是通过 xml 文件中 <mapper> 标签的 namespace 属性指定要映射文件所在的路径来讲两者关联起来的;
- xml 文件中的 sql 通过 Mybatis 的语句标签,比如 <select> 标签中的 id 属性指定接口中的方法名称进行映射的。在这里,id="selectByName" 表示该 SQL 语句标签和接口中的 selectByName 方法进行关联。
这里需要注意的是:
- 接口中的方法参数想要传递给 xml 中,除非参数是唯一的,否则需要使用 @Param 来表名参数名称;
- xml 中使用接口方法参数的方式为 #{item} ,item 为参数名,可以多级使用,比如 item.user.name。
二、我的项目上实例:
@Mapper @Component public interface ConferenceDao extends MyBaseMapper<Conference> { /** * * @Title: queryConferenceList * @Description: 查询会议列表 * @param conferenceQueryListVo * @return 参数 * @return List<ConferenceListVo> 返回类型 * @throws */ List<ConferenceListVo> queryConferenceList(ConferenceQueryListVo conferenceQueryListVo); List<ConfServiceList> getVipConfServiceList(@Param("roomIds")List<Integer> roomIds,@Param("type") Integer type);
List<Integer> selectDeviceIdsByConfIds(@Param("confIds") List<Integer> confIds);
Integer getCompleteConfServiceSum();
…… }
ConferenceMapper.xml
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zst.aim.dao.conference.ConferenceDao"> <resultMap type="com.zst.aim.model.conference.vo.ConferenceListVo" id="queryListMap"> <id column="id" property="id" /> <result column="name" property="name" /> <result column="status" property="status" /> <result column="type" property="type" /> <result column="startTime" property="startTime" /> <result column="endTime" property="endTime" /> <result column="gmt_create" property="gmtCreate" /> <result column="display_name" property="createUserName" /> <result column="phone_number" property="createUserPhoneNumber" /> <result column="isSeatLayout" property="isSeatLayout" />
<!--一对多查询-> <collection property="rooms" ofType="com.zst.aim.model.conference.vo.RoomNameAndId" select="findRoomNameAndId" column="{conf_id = id}"> </collection> </resultMap> <select id="queryConferenceList" resultMap="queryListMap" parameterType="com.zst.aim.model.conference.vo.ConferenceQueryListVo"> SELECT a.id, a.`name`, a.`status` , a.`type` type, a.end_time endTime, a.start_time startTime, a.gmt_create, d.display_name, d.phone_number, IF(e.is_seat_layout=1, 1,0) isSeatLayout FROM conference a LEFT JOIN sys_user_info d on a.create_by = d.id LEFT JOIN nps_conference e on a.id = e.conf_id WHERE a.is_deleted = 0 and a.is_show = 1 and is_template = #{isTemplate} <if test = "name !=null and name !=''" > AND a.`name` LIKE CONCAT('%',#{name},'%') </if> <if test = "status!=null and status >= 0" > AND a.`status` = #{status} </if> <if test = "type!=null and type > 0" > AND a.`type` = #{type} </if> order by a.id desc </select> <select id="findRoomNameAndId" resultType="com.zst.aim.model.conference.vo.RoomNameAndId"> SELECT a.id as roomId,a.`name` as roomName FROM nps_room as a LEFT JOIN conference_equ as b on a.id = b.room_id WHERE b.conf_id = #{conf_id} </select> <select id="getVipConfServiceList" resultType="com.zst.aim.model.confService.ConfServiceList" parameterType="integer"> SELECT s.id, s.request_content, s.request_time, s.complete_time, s.state, s.room_id, i.display_name userName, i.phone_number, r.`name` roomName, c.`name` confName, c.start_time confStartTime, c.end_time confEndTime FROM nps_conf_service s LEFT JOIN sys_user_organization o ON o.id=s.request_user_id LEFT JOIN sys_user_info i ON i.id = o.user_id LEFT JOIN conference c ON c.id = s.request_conf_id LEFT JOIN conference_equ e ON c.id = e.conf_id LEFT JOIN nps_room r ON r.id = e.room_id WHERE <if test="type == 0"> s.state=0 </if> <if test="type == 1"> s.state=1 </if> <if test="null != roomIds and roomIds.size > 0"> and s.room_id in <foreach collection="roomIds" item="vipRoomId" open="(" separator="," close=")"> #{vipRoomId} </foreach> </if> <if test="null == roomIds or roomIds.size == 0"> and s.room_id is not null </if> ORDER BY s.request_time DESC </select>
<select id="selectDeviceIdsByConfIds" resultType="java.lang.Integer">
SELECT a.device_id FROM nps_device_room as a
LEFT JOIN conference_equ as b ON b.room_id = a.room_id
WHERE b.conf_id in
<foreach collection="confIds" item="confId" open="(" close=")" separator=",">
#{confId}
</foreach>
</select>
<select id="getCompleteConfServiceSum" resultType="integer">
select count(0) from nps_conf_service where date_format(complete_time,'%Y-%m')=date_format(now(),'%Y-%m')
</select>
…… </mapper>
springboot,resource文件夹下,新建mapper文件,***map.xml放在里面,系统中的mybatis-plus是可以自动找到这些map xml文件的,当然也可以在yml文件中指定:
mybatis:
mapper-locations: classpath:mapper/*.xml #配置map xml
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #控制台打印sql