MyBatis动态SQL

1.MyBatis动态SQL
MyBatis 的强大特性之一便是它的动态 SQL,即拼接SQL字符串。如果你有使用 JDBC 或其他类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句有多么痛苦。拼接的时候要确保不能忘了必要的空格,还要注意省掉列名列表最后的逗号。利用动态 SQL 这一特性可以彻底摆脱这种痛苦。

通常使用动态 SQL 不可能是独立的一部分,MyBatis 当然使用一种强大的动态 SQL 语言来改进这种情形,这种语言可以被用在任意的 SQL 映射语句中。

动态 SQL 元素和使用 JSTL 或其他类似基于 XML 的文本处理器相似。在 MyBatis 之前的版本中,有很多的元素需要来了解。MyBatis 3 大大提升了它们,现在用不到原先一半的元素就可以了。MyBatis 采用功能强大的基于 OGNL 的表达式来消除其他元素。

2.动态SQL标签:if,choose (when, otherwise),trim (where, set),foreach

2.1.If标签

<select id="getUsersByNameAge" resultType="User" parameterType="User">
    SELECT * FROM USER
    WHERE 1=1
    AND uname LIKE "%"#{uname}"%"
    AND uage = #{uage}
</select>

注:if标签一般用于非空验证,如上例,若id为空,if标签里的代码,将不会执行,反之,则会执行。

2.2.Where标签

<!-- 根据uname,uage查询User-->
<select id="getUsersByNameAge" resultType="User">
  SELECT * FROM USER
    <!-- where:表示标签内部为where条件语句,会自动去除第一个前置and关键字-->
    <where>
        <!-- if:判断标签
                test:判断,boolean类型表达式,如果为真执行标签中间内容,反之不执行-->
        <if test="uname!=null and uname!=''">
            AND uname LIKE "%"#{uname}"%"
        </if>
        <if test="uage!=null and uage!=''">
            AND uage = #{uage}
        </if>
    </where>
</select>

2.3.Sql片段

<mapper namespace="mapper.UserMapper">
    <!-- sql:sql片段,标签内部文本为sql语句片段
            id:sql片段标记
            -->
    <sql id="cols">
        uid,uname,uage
    </sql>
    <!-- 根据uname,uage查询User-->
    <select id="getUsersByNameAge" resultType="User">
        <!-- include: 引用sql片段
                    refid:sql片段的id-->
      SELECT  <include refid="cols"/>  FROM USER
        <where>
            <if test="uname!=null and uname!=''">
                AND uname LIKE "%"#{uname}"%"
            </if>
            <if test="uage!=null and uage!=''">
                AND uage = #{uage}
            </if>
        </where>
    </select>
</mapper>

2.4.foreach标签

<select id="getUsersByIds" resultType="User" parameterType="Queryvo" >
    SELECT uid,uname,uage FROM USER WHERE uid
    <!-- foreach :遍历集合
            collection:集合类型(注:不是属性或变量名)
                (1)传递简单参数:
                    遍历为数组类型:array
                          list类型:list
                (2)传递对象包装类:直接写对应的属性名即可,不需要区分集合类型
            separator:分隔符(最后一个元素不加)
            item:遍历时被遍历出的元素的变量名
            open: 遍历开始前的包裹内容
            close:遍历结束后的包裹内容
            index:索引
     -->
    <!--<foreach collection="list" separator="," item="id" open="IN (" close=")">-->
    <foreach collection="ids2" separator="," item="id" open="IN (" close=")">
        ${id}
    </foreach>
    ;
</select>

3.关联查询

3.1 一对一查询
方式1:自动映射

<!-- 一对一:自动映射 -->
    <select id="findOrdersAndUser1" resultType="com.dml.pojo.CustomerOrders">
        select a.*,b.id uid,username,birthday,sex,address from orders a,user b where a.user_id = b.id;
    </select>
UserMapper.java

@Test
public void testFindOrdersAndUser1() throws Exception{
    SqlSession openSession = factory.openSession();
    //通过getMapper方法来实例化接口
    UserMapper mapper = openSession.getMapper(UserMapper.class);
    List<CustomerOrders> list = mapper.findOrdersAndUser1();
    for (CustomerOrders co : list) {
        System.out.println(co.getUsername() +"======="+co.getId() +"=======" +co.getUid());
    }

}

CustomerOrders.java

public class CustomerOrders extends Orders{
    private int uid;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
    public int getUid() {
        return uid;
    }
    public void setUid(int uid) {
        this.uid = uid;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }

方法2:手动映射

<!-- 
    id:resultMap的唯一标识
    type:将查询出的数据放入这个指定的对象中
    注意:手动映射需要指定数据库中标的字段名与java中pojo类的属性名称的对应关系
 -->
<resultMap type="com.dml.pojo.Orders" id="orderAndUserResultMap">
    <!-- id标签指定主键字段对应关系
        column:列,数据库中的字段名称
        property:属性,java中pojo中的属性名称
     -->
    <id column="id" property="id"/>

    <!-- result:标签指定非主键字段的对应关系 -->
    <result column="user_id" property="userId"/>
    <result column="number" property="number"/>
    <result column="createtime" property="createtime"/>
    <result column="note" property="note"/>

    <!-- 这个标签指定单个对象的对应关系 
        property:指定将数据放入orders中的user属性中
        javaType:user属性的类型
    -->
    <association property="user" javaType="com.dml.pojo.User">
        <id column="uid" property="id"/>
        <result column="username" property="username"/>
        <result column="sex" property="sex"/>
        <result column="birthday" property="birthday"/>
        <result column="address" property="address"/>
    </association>

</resultMap>
<select id="findOrdersAndUser2" resultMap="orderAndUserResultMap">
    select a.*,b.id uid,username,birthday,sex,address from orders a,user b where a.user_id = b.id;
</select>

UserMapper.java

//一对一:手动映射
    public List<Orders> findOrdersAndUser2();

UserMapperTest.java

public void testFindOrdersAndUser2() throws Exception{
        SqlSession openSession = factory.openSession();
        //通过getMapper方法来实例化接口
        UserMapper mapper = openSession.getMapper(UserMapper.class);
        List<Orders> list = mapper.findOrdersAndUser2();
        for (Orders co : list) {
            System.out.println(co.getUser().getUsername() +"======="+co.getId() +"=======" +co.getUser().getId());
        }
    }
3.2 一对多查询

<resultMap type="com.dml.pojo.User" id="userAndOrdersResultMap">
    <id column="id" property="id"/>
    <result column="username" property="username"/>
    <result column="sex" property="sex"/>
    <result column="birthday" property="birthday"/>
    <result column="address" property="address"/>

    <!-- 指定对应的集合对象关系映射
    property:将数据放入User对象中的ordersList属性中
    ofType: 指定ordersList属性的泛型类型
     -->
    <collection property="ordersList" ofType="com.dml.pojo.Orders">
        <id column="oid" property="id"/>
        <result column="user_id" property="userId"/>
        <result column="number" property="number"/>
        <result column="createtime" property="createtime"/>
        <result column="note" property="note"/>

    </collection>
</resultMap>
<select id="findUserAndOrders" resultMap="userAndOrdersResultMap">
    select a.*,b.id oid,user_id,number,createtime from user a,orders b where a.id = b.user_id
</select>

UserMapper.java

//一对多
public List findUserAndOrders();
UserMapperTest.java

//一对多
@Test
public void testFindUserAndOrders() throws Exception{
SqlSession openSession = factory.openSession();
//通过getMapper方法来实例化接口
UserMapper mapper = openSession.getMapper(UserMapper.class);
List list = mapper.findUserAndOrders();
for (User user : list) {
System.out.print(user.getId() +"="+ user.getUsername() +"=");
List list2 = user.getOrdersList();
for (Orders orders : list2) {
System.out.print(orders.getId() + “===”);
}
System.out.println();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值