一、动态sql
通过mybatis提供的标签,实现sql语句的拼接。
1.where
<select id="findUserList" parameterType="user" resultType="user"> select * from user <!--使用where可以自动处理第一个and--> <where> <if test="id!=null and id!=‘‘"> and id=#{id} </if> <if test="username!=null and username!=‘‘"> and username like ‘%${username}%‘ </if> </where> </select>
2.foreach
场景:当传入参数为一个数组或者集合时,mybatis提供了foreach标签解析
<if test="ids!=null"> <!-- 使用foreach遍历传入的ids collection:输入对象中的集合属性 item:每次遍历的生成的对象名 open:开始遍历时拼接的串 close:结束遍历时拼接的串 separator:遍历的两个对象中需要拼接的串 --> <!-- 实现以下拼接 AND(id=1 or id=2 or id=3) --> <foreach collection="ids" item="id" open="AND(" close=")" separator="or"> id=#{id} </foreach> </if>
3.sql片段
当sql语句重复使用时,我们可以对sql进行抽取,使用时直接引用,提升代码的复用性。
<!-- 传递pojo综合查询用户信息 --> <select id="findUserList" parameterType="user" resultType="user"> select * from user <where> <if test="id!=null and id!=‘‘"> and id=#{id} </if> <if test="username!=null and username!=‘‘"> and username like ‘%${username}%‘ </if> </where> </select>
对where条件中的sql进行抽取
<sql id="query_user_where"> <if test="id!=null and id!=‘‘"> and id=#{id} </if> <if test="username!=null and username!=‘‘"> and username like ‘%${username}%‘ </if> </sql>
引用sql
<select id="findUserList" parameterType="user" resultType="user"> select * from user <where> <include refid="query_user_where"/> </where> </select>
二、关联查询(重点)
resultType和resultMap
resultType指定输出结果类型,可以是基本类型,也可以 是pojo对象。
mapper.xml文件
<!-- 根据id查询用户信息 --> <select id="findUserById" parameterType="int" resultType="user"> select * from user where id = #{id} </select>
resultMap
resultType可以指定pojo将查询结果映射为pojo,但需要pojo的属性名和sql查询的列名一致方可映射成功.
如果sql查询字段名和pojo的属性名不一致,可以通过resultMap将字段名和属性名作一个对应关系 ,resultMap实质上还需要将查询结果映射到pojo对象中。resultMap可以实现将查询结果映射为复杂类型的pojo,比如在查询结果映射对象中包括pojo和list实现一对一查询和一对多查询。
<!-- 配置resultmap type:为映射结果类型 --> <resultMap type="orders" id="user_orders_resultmap"> <!-- 配置要映射的订单信息 --> <!-- id为要查询对象的唯一标识(orders的主键 ) 如果有多个唯一表示都都配置上即可 column:唯一标识的咧 property:为结果类型的属性 --> <id column="id" property="id" /> <result column="user_id" property="userId" /> <result column="number" property="number" /> <result column="createtime" property="createtime" /> <result column="note" property="note" /> <!-- 配置要映射的关联用户的信息 --> <!-- assocation用来映射关联查询单个对象的信息 property:要将关联的信息映射到Orders中的那个属性 --> <association property="user" javaType="cn.mycookies.mybatis.demo.po.User"> <result column="user_id" property="id" /> <result column="username" property="username" /> <result column="sex" property="sex" /> <result column="address" property="address" /> </association> </resultMap>
1.一对一查询
场景:查询所有订单信息,关联查询下单用户信息。
注意:因为一个订单信息只会是一个人下的订单,所以从查询订单信息出发关联查询用户信息为一对一查询。如果从用户信息出发查询用户下的订单信息则为一对多查询,因为一个用户可以下多个订单
way1:使用resultType定义返回值结果类型 返回结果为Orders的po类 类中有User属性
mapper.xml配置
<select id="findOrdersListResultMap" resultType="Orders"> SELECT orders.*, user.username, user.address FROM orders, user WHERE orders.user_id = user.id </select>
way2:使用resultMap定义返回 结果类型
<!--定义resultMap--> <resultMap type="orders" id="user_orders_resultmap"> <!--配置映射的订单信息--> <!-- id为要查询对象的唯一标识(orders的主键 ) 如果有多个唯一表示都都配置上即可 column:唯一标识的咧 property:为结果类型的属性 --> <id column="id" property="id" /> <result column="user_id" property="userId" /> <result column="number" property="number" /> <result column="createtime" property="createtime" /> <result column="note" property="note" /> <!-- 配置要映射的关联用户的信息 --> <!-- assocation用来映射关联查询单个对象的信息 property:要将关联的信息映射到Orders中的那个属性 --> <association property="user" javaType="cn.mycookies.mybatis.demo.po.User"> <result column="user_id" property="id" /> <result column="username" property="username" /> <result column="sex" property="sex" /> <result column="address" property="address" /> </association> </resultMap>
<!-- resultMap映射结果查询 --> <select id="findOrdersUserResultMap" resultMap="user_orders_resultmap"> SELECT orders.* ,User.username,User.sex,User.address from orders ,user where orders.user_id = user.id </select>
2.一对多查询
案例:查询所有订单信息一级订单下的订单明细
订单与订单明细是一对多的关系
只能用resultMap实现
<!-- 一对多查询 订单与订单明细 --> <resultMap type="orders" id="OrdersAndOrderDetailResultMap" extends="user_orders_resultmap"> <!-- 因为出现了重复 我们可以使用restulemap的继承 --> <!-- 订单信息 <id column="id" property="id"/> <result column="user_id" property="userid"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> 用户信息 <association property="user" javaType="user"> <result column="user_id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> </association> --> <!-- 订单明细信息 property:po类中对应的属性名 ofType映射到list集合属性中的po类型 --> <collection property="orderdetailsList" ofType="Orderdetail"> <id column="ordertaile_id" property="id" /> <result column="items_id" property="itemsId" /> <result column="items_num" property="itemsNum" /> <result column="orders_id" property="ordersId" /> </collection> </resultMap>
<select id="findOrdersAndOrderDetailsresultMap" resultMap="OrdersAndOrderDetailResultMap"> SELECT orders.* , User.username, User.sex, User.address, orderdetail.id ordertaile_id , orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id from orders ,user,orderdetail where orders.user_id = user.id and orderdetail.orders_id=orders.id </select>
3.多对多的查询
案例:查询用户购买的商品信息。
需要查询用户信息,关联查询订单和订单明细,通过订单明细关联查询商品信息
<!--用户与items的 多对多映射关系 --> <resultMap type="User" id="userAndItemsResultMap"> <!-- 用户信息 --> <id column="user_id" property="id" /> <result column="username" property="username" /> <result column="sex" property="sex" /> <result column="address" property="address" /> <!-- 用户所购买的订单信息 --> <collection property="ordersList" ofType="orders"> <id column="id" property="id" /> <result column="user_id" property="userId" /> <result column="number" property="number" /> <result column="createtime" property="createtime" /> <result column="note" property="note" /> <!-- 订单明细 --> <collection property="orderdetailsList" ofType="orderdetail"> <id column="orderdetail_id" property="id" /> <result column="items_id" property="itemsId" /> <result column="items_num" property="itemsNum" /> <result column="orders_id" property="ordersId" /> <!-- 商品明细 一个订单包括一个item --> <association property="items" javaType="Items"> <id column="items_id" property="id" /> <result column="items_name" property="name" /> <result column="items_detail" property="detail" /> <result column="items_price" property="price" /> </association> </collection> </collection> </resultMap>
<select id="findUserandItemsResultMap" resultMap="userAndItemsResultMap"> SELECT orders.*, User.username, User.sex, User.address, orderdetail.id ordertaile_id , orderdetail.items_id, orderdetail.items_num, orderdetail.orders_id, items.price items_price, items.detail items_detail, items.name items_name from orders ,user,orderdetail,items where orders.user_id = user.id and orderdetail.orders_id=orders.id and orderdetail.items_id=items.id </select>
总结:
resulttype:将查询的结果按照sql列名pojo属性名一致性映射到pojo中。
使用场景:常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面上时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list即可。
resultMap:使用association和collection完成一对一和一对多高级映射(对结果有特殊要求时使用)
association:将关联查询信息映射到一个pojo对象中
使用场景:为了方便查询关联信息可以使用association将关联订单信息映射到用户对象的pojo属性中,比如,查询订单的用户信息。
collection:将关联查询信息映射到一个list集合中
使用场景:为了方便查询遍历关联信息可以使用collection将关联信息映射到一个集合中,比如,查询用户权限范围模块以及模块下的菜单,可以使用collection将模块映射到模块list中,将菜单列表映射到模块对象的list属性中,这样做的目的是方便对查询结果集进行遍历查询。