复合条件查询(动态SQL)
MyBatis 的强大特性之一便是它的动态 SQL。如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦。例如拼接时要确保不能忘记添加必要的空格,还要注意去掉列表最后一个列名的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。
虽然在以前使用动态 SQL 并非一件易事,但正是 MyBatis 提供了可以被用在任意 SQL 映射语句中的强大的动态 SQL 语言得以改进这种情形。
动态 SQL 元素和 JSTL 或基于类似 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多元素需要花时间了解。MyBatis 3 大大精简了元素种类,现在只需学习原来一半的元素便可。MyBatis 采用功能强大的基于 OGNL 的表达式来淘汰其它大部分元素。
if
choose (when, otherwise)
trim (where, set)
foreach
创建PO类 作为导航
package com.foreknow.bean;
public class UserInfo extends User {
}
UserQueryInfo.java
package com.foreknow.bean;
import java.util.List;
/**
* 根据多个条件查询用户的信息
* @author Administrator
*
*/
public class UserQueryInfo {
//传入多个id
private List<Integer> ids;
//在这里包装所需要的查询条件
//用户查询条件
private UserInfo userInfo;
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public UserInfo getUserInfo() {
return userInfo;
}
public void setUserInfo(UserInfo userInfo) {
this.userInfo = userInfo;
}
public static void main(String[] args) {
}
}
UserMapper.java 接口
// 用户信息综合查询
public List<UserInfo> findUserList(UserQueryInfo userQueryInfo) throws Exception;
// 用户信息综合查询总数
public int findUserCount(UserQueryInfo userQueryInfo) throws Exception;
UserMapper.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">
<!--namespace命名空间 ,它的作用是对SQL进行分类化管理 -->
<mapper namespace="com.foreknow.dao.UserMapper">
<!--
Java代码:
public User findUserById(int id)
id:唯一标识 相当于方法的名称
parameterType:输入参数的类型 相当于方法的参数类型
resultType:方法返回值的类型 注意:全路径(包名+类名)
#{id}:相当于一个占位符
-->
<!-- 所有的select标签都能引用他 -->
<sql id="query_user_where">
<if test="userInfo!=null">
<if test="userInfo.sex!=null and userInfo.sex!=''">
and USER .sex = #{userInfo.sex}
</if>
<if test="userInfo.username!=null and userInfo.username!=''">
and USER.username LIKE '%${userInfo.username}%'
</if>
<if test="ids!=null">
<foreach collection="ids" item="user_id" open="AND (" close=")" separator="or">
<!-- 每个遍历需要拼接的串 -->
id=#{user_id}
</foreach>
</if>
</if>
</sql>
<select id="findUserById" parameterType="int" resultType="com.foreknow.bean.User" >
select * from user where id=#{id}
</select>
<!-- public void insertUser(User user) -->
<insert id="insertUser" parameterType="com.foreknow.bean.User">
insert into User(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
<!--
${value}表示拼接sql字符串
-->
<select id="findUserByName" parameterType="java.lang.String" resultType="com.foreknow.bean.User">
select * from user where username like '%${value}%'
</select>
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
<update id="updateUser" parameterType="com.foreknow.bean.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
<select id="findUserList" parameterType="com.foreknow.bean.UserQueryInfo" resultType="com.foreknow.bean.UserInfo">
select*from user
<!-- 导航语音userInfo -->
<where>
<!-- include是包含 refid是引用 引用sql 的 ID -->
<include refid="query_user_where"></include>
</where>
</select >
<!-- 查询订单关联查询用户信息,使用resultmap -->
<select id="findOrderUser" resultType="com.foreknow.bean.OrderUserInfo">
SELECT
orders.*,
USER.username,
USER.sex,
USER.address
FROM
orders,
USER
WHERE orders.user_id = user.id
</select>
<!-- 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -->
<!-- 查询订单关联查询用户信息,使用resultmap association (一对一)-->
<resultMap type="com.foreknow.Orders" id="OrdersUserResultMap">
<!-- 配置映射的订单信息 -->
<!-- id:指定查询列中的唯 一标识,订单信息的中的唯 一标识,如果有多个列组成唯一标识,配置多个id
column:订单信息的唯 一标识 列
property:订单信息的唯 一标识 列所映射到Orders中哪个属性
-->
<id column="id" property="id"/>
<!-- user_id是数据库的表的列 property 是对应bean中private的属性名称 正常应该是一一对应的 但是
在Mybatis半自动框架中 可以不一一对应 -->
<result column="user_id" property="userId"/>
<!-- <result column="orderid" property代表属性名="orderid"/> -->
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 配置映射的关联的用户信息 -->
<!-- association:用于映射关联查询单个对象的信息
property:要将关联查询的用户信息映射到Orders中哪个属性
-->
<association property="user" javaType="com.foreknow.User">
<!-- id:关联查询用户的唯 一标识
column:指定唯 一标识用户信息的列
javaType:映射到user的哪个属性
-->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
</association>
</resultMap>
<select id="findOrdersUserResultMap" resultMap="OrdersUserResultMap">
SELECT
orders.*,
USER.username,
USER.sex,
USER.address
FROM
orders,
USER
WHERE orders.user_id = user.id
</select>
<!-- 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -->
<!--描述一对多的关联关系 collection -->
<!-- 订单及订单明细的resultMap
使用extends继承,不用在中配置订单信息和用户信息的映射
-->
<!-- 订单信息 -->
<!-- 用户信息 -->
<!-- 使用extends继承,不用在中配置订单信息和用户信息的映射 -->
<!-- 订单明细信息
一个订单关联查询出了多条明细,要使用collection进行映射
collection:对关联查询到多条记录映射到集合对象中
property:将关联查询到多条记录映射到Orders哪个属性
ofType:指定映射到list集合属性中pojo的类型
-->
<resultMap type="com.foreknow.bean.Orders" id="OrdersDetailResultMap" extends="OrdersUserResultMap">
<collection property="orderdetails" ofType="com.foreknow.bean.Orderdetail">
<!-- id:订单明细唯 一标识
property:要将订单明细的唯 一标识 映射到com.foreknow.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"/>
</collection>
</resultMap>
<select id="findOrderDetailResultMap" resultMap="OrdersDetailResultMap">
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
USER,
orderdetail
WHERE orders.user_id=user.id and orders.id=orderdetail.orders_id
</select>
<!-- 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111 -->
<!-- 查询用户及购买的商品 -->
<resultMap type="com.foreknow.bean.User" id="UserItemsResultMap">
<!-- 用户信息 -->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!-- 订单信息
一个用户对应多个订单,使用collection映射
-->
<collection property="ordersList" ofType="com.foreknow.bean.Orders">
<id column="id" property="id"/>
<result column="user_id" property="userId"/>
<result column="orderid" property="orderid"/>
<result column="createtime" property="createtime"/>
<result column="note" property="note"/>
<!-- 订单明细
一个订单包括 多个明细
-->
<collection property="orderdetails" ofType="com.foreknow.bean.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"/>
<!-- 商品信息
一个订单明细对应一个商品
-->
<association property="items" javaType="com.foreknow.bean.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="findUserItemsResultMap" resultMap="UserItemsResultMap">
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id,
items.id items_id,
items.name items_name,
items.detail items_detail,
items.price items_price
from
orders,
user,
orderdetail,
items
where orders.user_id=user.id and orders.id=orderdetail.orders_id and orderdetail.items_id=items.id
</select>
</mapper>
Junit测试 MybatisUserMapperTest.java
网友评论