Mybatis查詢和多表

mybatis查詢和多表

resultMap標籤

  • 如果數據庫返回結果的列名和要封裝的實體的屬性名完全一致的話用 resultType 屬性
  • 如果數據庫返回結果的列名和要封裝的實體的屬性名有不一致的情況用 resultMap 屬性
    • 使用resultMap手動建立對象關係映射
  • 代碼測試:
    UserMapper接口:
public interface UserMapper {
    //ResultMap標籤
    public List<User> findAllResultMap();
}

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">
<mapper namespace="cn.itcast.dao.UserMapper">
    <!--
       resultMap 手動建立映射
           id="userResultMap"
           type="cn.itcast.domain.User" 建立映射的java類型
       id 標籤 主鍵
           column="uid" 列名
           property="id" 實體屬性名
      result 標籤 普通字段
           column="name" 列名
           property="username" 實體屬性名
   -->
    <resultMap id="userResultMap" type="cn.itcast.domain.User">
        <id column="uid" property="id"></id>
        <result column="name" property="username"></result>
        <result column="bir" property="birthday"></result>
        <result column="gender" property="sex"></result>
        <result column="address" property="address"></result>

    </resultMap>
    <!--模擬表與實體的屬性不一致的情況-->
    <select id="findAllResultMap" resultMap="userResultMap">
        select id as uid , username as `name`, birthday as bir,sex as gender,address as address  from user
    </select>
</mapper>

測試代碼:

package cn.itcast.test;

import cn.itcast.dao.UserMapper;
import cn.itcast.domain.User;
import cn.itcast.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.Date;
import java.util.List;

public class UserMapperTest {
    //模擬service
    @Test
    public void testfindAllResultMap() throws Exception {
        //需要通過mybatis幫我們根據接口規範創建實現類
        SqlSession sqlSession = MyBatisUtils.openSession();
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //執行sql
        final List<User> list = userMapper.findAllResultMap();
        for (User user : list) {
            System.out.println(user);
        }
        //關閉會話
        MyBatisUtils.close(sqlSession);

    }


}

多條件查詢(二種)

需求:根據id和username查詢user表
UserMapper接口:

   //多條件查詢,方式一
    public List<User> findByIdAndUsername1(@Param("id") Integer id, @Param("username") String username);

    //多條件查詢,方式二
    public List<User> findByIdAndUsername2(User user);

UserMapper.XML映射配置文件:

  <!--多條件查詢方式一,如果傳遞多個參數parameterType屬性省略不寫-->
    <select id="findByIdAndUsername1" resultType="cn.itcast.domain.User">
        select * from user where id =#{id} and username=#{username}
    </select>

    <!--多條件查詢方式二-->
    <select id="findByIdAndUsername2" parameterType="cn.itcast.domain.User" resultType="cn.itcast.domain.User">
        select * from user where id=#{id } and username=#{username}
     </select>

測試代碼:

 //多條件查詢
    @Test
    public void test01() throws Exception {
        //需要通過mybatis幫我們根據接口規範創建實現類
        SqlSession sqlSession = MyBatisUtils.openSession();
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //方式一
        final List<User> list = userMapper.findByIdAndUsername1(41, "老王");
        System.out.println(list);
        //方式二
        final User user = new User();
        user.setId(41);
        user.setUsername("老王");
        final List<User> list1 = userMapper.findByIdAndUsername2(user);
        System.out.println(list1);
    }

模糊查詢(四種)

需求:根據username模糊查詢user表
UserMapper接口:

   //模糊查詢,方式一
    public List<User> findByUsername1(String username);

    //模糊查詢,方式二
    public List<User> findByUsername2(String username);

    //模糊查詢,方式三
    public List<User> findByUsername3(String username);

    //模糊查詢,方式四
    public List<User> findByUsername4(String username);

UserMapper.XML映射配置文件:

 <!--模糊查詢,方式一 缺點:java代碼和sql語句有耦合性-->
    <select id="findByUsername1" parameterType="string" resultType="User">
        select  * from user where username like #{username}
    </select>

    <!--方式二-->
    <select id="findByUsername2" parameterType="string" resultType="User">
        select  * from user where username like "%" #{usrname} "%"
    </select>

    <!--方式三-->
    <select id="findByUsername3" parameterType="string" resultType="User">
     select * from user where username like '%${value}%'
    </select>

    <!--方式四 使用concat()函數拼接-->
    <select id="findByUsername4" parameterType="string" resultType="User">
      select * from user where username like concat(concat('%',#{username}),'%')
    </select>

測試代碼:

  //模糊查詢
    @Test
    public void test02() throws Exception {
        //需要通過mybatis幫我們根據接口規範創建實現類
        SqlSession sqlSession = MyBatisUtils.openSession();
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //方式一
        final List<User> list = userMapper.findByUsername1("%王%");
        System.out.println(list);
        //方式二
        final List<User> list1 = userMapper.findByUsername2("王");
        System.out.println(list1);
        //方式三
        final List<User> list3 = userMapper.findByUsername3("王");
        System.out.println(list3);
        //方式四
        final List<User> list4 = userMapper.findByUsername4("王");
        System.out.println(list4);
    }

${}和#{}的區別【面試題】

  • ${}:底層Statement
  1. sql與參數拼接在一起,會出現sql注入問題
  2. 每次執行sql語句都會編譯一次
  3. 接收簡單數據類型,命名:${value}
  4. 接收引用數據類型,命名: ${屬性名}
  5. 字符串類型需要加 ‘${value}’
  • #{}:底層PreparedStatement
  1. sql與參數分離,不會出現sql注入問題
  2. sql只需要編譯一次
  3. 接收簡單數據類型,命名:#{隨便寫}
  4. 接收引用數據類型,命名:#{屬性名}

mybatis映射文件深入

返回主鍵

應用場景:向數據庫保存一個user對象後,然後在控制檯記錄下此新增user的主鍵值(id)
UserMapper接口:

package cn.itcast.dao;

import cn.itcast.domain.User;
import org.apache.ibatis.annotations.Param;

import java.util.List;

public interface UserMapper {
    //返回主鍵方式一
    public void save1(User user);
    //返回主鍵方式二
    public void save2(User user);
}

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">
<mapper namespace="cn.itcast.dao.UserMapper">
    <!--
         返回主鍵,方式一 useGeneratedKeys屬性
             useGeneratedKeys="true" 開啓新增主鍵返回功能
             keyColumn="id"  user表中主鍵列
             keyProperty="id" user實體主鍵屬性

             注意:僅支持主鍵自增類型的數據庫 MySQL 和 SqlServer , oracle不支持

     -->
    <insert id="save1" parameterType="User" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
        insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
    </insert>

    <!--
      返回主鍵,方式二  <selectKey>
           keyColumn="id" user表中主鍵列
           keyProperty="id" user實體主鍵屬性
           resultType="int" user實體主鍵屬性類型
           order="AFTER"  表示此標籤內部sql語句在insert執行之前(執行),還是之後執行(執行)
              AFTER 之後執行【在自增主鍵時】
              BEFORE 之前執行【使用指定主鍵時】

  -->
    <insert id="save2" parameterType="User">
        <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
            SELECT LAST_INSERT_ID()
        </selectKey>
        insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
    </insert>
</mapper>

測試代碼:

package cn.itcast.test;

import cn.itcast.dao.UserMapper;
import cn.itcast.domain.User;
import cn.itcast.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import java.util.Date;
import java.util.List;

public class UserMapperTest {
    private SqlSession sqlSession = null;

    //此方法在測試方法執行之前,執行
    @Before
    public void before() {
        //需要通過mybatis幫我們根據接口規範創建實現類
         sqlSession = MyBatisUtils.openSession();
    }

    //此方法在測試方法執行後,執行
    @After
    public void after() {
        //關閉會話
        MyBatisUtils.close(sqlSession);
    }

    //返回主鍵
    @Test
    public void test01() throws Exception {
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        final User user = new User();
        user.setUsername("小六");
        user.setBirthday(new Date());
        user.setAddress("中國");
        user.setSex("男");
        //方式一
        //userMapper.save1(user);
        //System.out.println("新增時,主鍵返回" + user.getId());
        //方式二
        userMapper.save2(user);
        System.out.println("新增時,主鍵返回" + user.getId());

    }


}

動態SQL

什麼是動態SQL

需求:把id和username封裝到user對象中,將user對象中不爲空的屬性作爲查詢條件
這個時候我們執行的sql就有多種可能

-- 如果id和用戶名不爲空
select * from user where id= #{id} and username = #{username}

-- 如果只有id
select * from user where id= #{id} 

-- 如果只有用戶名
select * from user where username = #{username}

-- 如果id和用戶名都爲空
select * from user

像上面這樣, 根據傳入的參數不同, 需要執行的SQL的結構就會不同,這就是動態SQL

if條件判斷

需求:把id和username封裝到user對象中,將user對象中不爲空的屬性作爲查詢條件
UserMapper接口:

    //if條件判斷
    public List<User> findByIdAndUsernaemIf(User user);

UserMapper.xml映射配置文件:

 <!--
    if標籤 條件判斷
    where標籤  相當於 where 1=1 功能,如果沒有條件情況下 where語句不在sql語句拼接
        可以去掉第一個 and 或者 or
    -->
    <select id="findByIdAndUsernaemIf" parameterType="User" resultType="User">
        select * from user
        <where>
            <if test="id !=null">
                and id =#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
        </where>
    </select>

測試代碼:

 @Test
    public void test02() throws Exception {
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        //拼接條件
        final User param = new User();
        param.setId(41);
        param.setUsername("老王");
        final List<User> list = userMapper.findByIdAndUsernaemIf(param);
        for (User user : list) {
            System.out.println(user);
        }

    }

set用於update語句

需求:動態更新user表數據,如果該屬性有值就更新,沒有值不做處理
UserMapper接口:

    //set更新
    public void updateIf(User user);

UserMapper.xml:

   <!--
        set標籤 更新 ,將條件中的最後一個逗號抹除
    -->
    <update id="updateIf" parameterType="User">
        update user
        <set>
            <if test="username!=null">
                username=#{username},
            </if>
            <if test="birthday!=null">
                birthday=#{birthday},
            </if>
            <if test="sex!=null">
                sex=#{sex},
            </if>
            <if test="address!=null">
                address=#{address},
            </if>

        </set>
        where id =#{id}
    </update>

測試代碼:

  @Test
    public void test03() throws Exception {
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //設置更新內容
        final User user = new User();
        user.setId(51);
        user.setUsername("小四");
        userMapper.updateIf(user);

    }

foreach用於循環遍歷【重點】

需求:根據多個id查詢,user對象的集合

select * from user where id in (41,43,46);
* <foreach>標籤用於遍歷集合,它的屬性:

    • collection:代表要遍歷的集合元素

    • open:代表語句的開始部分

    • close:代表結束部分

    • item:代表遍歷集合的每個元素,生成的變量名

    • sperator:代表分隔符

UserMapper接口:

    //foreach標籤,普通list集合
    public List<User> findByList(List<Integer> ids);

    //foreach標籤,普通array數組
    public List<User> findByArray(Integer[] ids);
    
    //foreach標籤,實體屬性list集合
    public List<User> findByQueryVo(QueryVo queryVo);

UserMapper.xml映射配置文件:

  <!--
       foreach標籤,普通list集合
           傳遞 普通類型list集合   collection="list" 屬性取值:collection、list
   -->
    <select id="findByList" parameterType="list" resultType="User">
        select * from user where id in
        <foreach collection="list" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>

    <!--
       foreach標籤,普通array數組
           傳統 普通類型array數組  collection="array" 屬性取值 array
   -->
    <select id="findByArray" parameterType="int" resultType="User">
        select * from user where id in
        <foreach collection="array" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>

    <!--
        foreach標籤,實體屬性list集合
            傳遞 實體中list屬性集合的話,collection="ids" 取值,實體的屬性名
    -->
    <select id="findByQueryVo" parameterType="QueryVo" resultType="User">
        select * from user where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>

測試代碼:

    //foreach標籤
    @Test
    public void test04() throws Exception {
        //創建代理對象(實現類)
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        //普通list集合
        //List ids = new ArrayList();
        //ids.add(41);
        //ids.add(46);
        //final List list = userMapper.findByList(ids);
        //System.out.println(list);

        //普通array數組
        //Integer[] ids={41,46,49};
        //final List<User> list = userMapper.findByArray(ids);
        //System.out.println(list);

        //實體屬性list集合
        List ids = new ArrayList();
        ids.add(41);
        ids.add(46);
        final QueryVo queryVo = new QueryVo();
        queryVo.setIds(ids);
        final List<User> list = userMapper.findByQueryVo(queryVo);
        System.out.println(list);
    }

QueryVo實體類:

package cn.itcast.domain;

import java.util.List;

//根據頁面查詢條件封裝到實體中 View Object
public class QueryVo {
    public List<Integer> getIds() {
        return ids;
    }

    public void setIds(List<Integer> ids) {
        this.ids = ids;
    }

    public List<Integer> ids;

}

SQL片段

映射文件中可將重複的 sql 提取出來,使用時用 include 引用即可,最終達到 sql 重用的目的

 <!--
        foreach標籤,普通list集合
            傳遞 普通類型list集合   collection="list" 屬性取值:collection、list
    -->
    <select id="findByList" parameterType="list" resultType="User">
        <include refid="selectUser"></include> where id in
        <foreach collection="list" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>


    <!--
        foreach標籤,普通array數組
            傳統 普通類型array數組  collection="array" 屬性取值 array
    -->
    <select id="findByArray" parameterType="int" resultType="User">
        <include refid="selectUser"></include>  where id in
         <foreach collection="array" open="(" close=")" item="id" separator=",">
             #{id}
         </foreach>
    </select>

    <!--
        foreach標籤,實體屬性list集合
            傳遞 實體中list屬性集合的話,collection="ids" 取值,實體的屬性名
    -->
    <select id="findByQueryVo" parameterType="QueryVo" resultType="User">
         <include refid="selectUser"></include> where id in
        <foreach collection="ids" open="(" close=")" item="id" separator=",">
            #{id}
        </foreach>
    </select>


    <!--
        將當前映射文件的共同的sql代碼抽取一個片段,實現sql的複用性...
         id="selectUser" 當前sql片段的唯一標識
    -->
    <sql id="selectUser">
         select id,username,birthday,sex,address from user
    </sql>

表關係回顧

  • 特殊情況:
    一個訂單隻能從屬於一個用戶,mybatis框架就把這個多對一看做成一對一來實現

  • 數據建立表關係:通過主外鍵關聯

  • 實體建立關係:通過屬性關聯

mybatis多表查詢

一對一(多對一)

一對一查詢模型
用戶表和訂單表的關係爲,一個用戶有多個訂單,一個訂單隻從屬於一個用戶
一對一查詢的需求:查詢一個訂單,與此同時查詢出該訂單所屬的用戶
Order實體類:

package cn.itcast.domain;

import java.util.Date;

public class Order {
    private Integer id;
    private Date ordertime;
    private Double money;

    //一個訂單從屬於一個用戶
    private User user;

    public Order() {
    }

    public Order(Integer id, Date ordertime, Double money, User user) {
        this.id = id;
        this.ordertime = ordertime;
        this.money = money;
        this.user = user;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public Date getOrdertime() {
        return ordertime;
    }

    public void setOrdertime(Date ordertime) {
        this.ordertime = ordertime;
    }

    public Double getMoney() {
        return money;
    }

    public void setMoney(Double money) {
        this.money = money;
    }

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;
    }

    @Override
    public String toString() {
        return "Order{" +
                "id=" + id +
                ", ordertime=" + ordertime +
                ", money=" + money +
                ", user=" + user +
                '}';
    }
}

OrderMapper接口:

public interface OrderMapper {
    //一對一關聯查詢
    public Order findByIdWithUser(Integer id);

}

OrderMapper.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="cn.itcast.dao.OrderMapper">

    <resultMap id="orderMap" type="cn.itcast.domain.Order">
        <id column="id" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="money" property="money"></result>
        <!--一對多關聯 association標籤
         property="user" 關聯實體的屬性名
         javaType="cn.itcast.domain.User" 關聯實體java類型
        -->
        <association property="user" javaType="cn.itcast.domain.User">
            <id column="uid" property="id"></id>
            <result column="username" property="username"></result>
            <result column="birthday" property="birthday"></result>
            <result column="sex" property="sex"></result>
            <result column="address" property="address"></result>
        </association>
    </resultMap>
    <!--一對一關聯查詢
    resultType:單表映射封裝
    resultMap:多表查詢必須手動映射封裝-->
    <select id="findByIdWithUser" parameterType="int" resultMap="orderMap">
        SELECT * FROM orders o INNER JOIN `user` u ON o.`uid` = u.`id` WHERE o.`id` = #{id}
    </select>
</mapper>

測試代碼:

package cn.itcast.test;


import cn.itcast.dao.OrderMapper;
import cn.itcast.domain.Order;
import cn.itcast.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

public class OrderMapperTest {
    private SqlSession sqlSession = null;

    // 此方法在測試方法執行之前,執行
    @Before
    public void before() {
        // 獲取sqlSession對象
        sqlSession = MyBatisUtils.openSession();// 此方法必須線程內獨享....
    }

    // 此方法在測試地方法執行之後,執行
    @After
    public void after() {
        // 關閉sqlSession
        MyBatisUtils.close(sqlSession);
    }

    //一對一關聯測試
    @Test
    public void test01() throws Exception {
        //獲取代理對象
        final OrderMapper orderMapper = sqlSession.getMapper(OrderMapper.class);
        //根據id查詢
        final Order order = orderMapper.findByIdWithUser(1);
        System.out.println(order);
    }

}

一對多

一對多查詢模型
用戶表和訂單表的關係爲,一個用戶有多個訂單,一個訂單隻從屬於一個用戶
一對多查詢的需求:查詢一個用戶,與此同時查詢出該用戶具有的訂單
User實體類:

package cn.itcast.domain;

import java.util.Date;
import java.util.List;

//實體類
public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    public List<Order> getOrderList() {
        return orderList;
    }

    public void setOrderList(List<Order> orderList) {
        this.orderList = orderList;
    }

    //一個用戶具有多個訂單
    private List<Order> orderList;

    public User() {
    }

    public User(Integer id, String username, Date birthday, String sex, String address, List<Order> orderList) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
        this.orderList = orderList;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", orderList=" + orderList +
                '}';
    }
}

UserMapper接口:

package cn.itcast.dao;

import cn.itcast.domain.Order;

public interface OrderMapper {
    //一對一關聯查詢
    public Order findByIdWithUser(Integer id);

}

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">
<mapper namespace="cn.itcast.dao.UserMapper">

    <resultMap id="userMap" type="cn.itcast.domain.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>

        <!--一對多關聯 collection標籤
         property="orderLlist" 關聯實體的屬性名
        ofType="cn.itcast.domain.Order" 關聯實體java類型(集合泛型的類型)
        -->
        <collection property="orderList" ofType="cn.itcast.domain.Order">
            <id column="oid" property="id"></id>
            <result column="ordertime" property="ordertime"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>
    <!--一對多查詢關聯-->
    <select id="findByIdWithOrders" parameterType="int" resultMap="userMap">
      SELECT *,o.id AS oid FROM `user` u INNER JOIN orders o ON u.`id` = o.`uid` WHERE u.`id`=#{id}
    </select>
</mapper>

測試代碼:

package cn.itcast.test;

import cn.itcast.dao.UserMapper;
import cn.itcast.domain.User;
import org.junit.Test;

public class UserMapperTest extends BaseMapperTest {
    // 一對多測試
    @Test
    public void test01() throws Exception {
        // 獲取代理
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);

        User user = userMapper.findByIdWithOrders(41);

        System.out.println(user);
    }
}

多對多(由兩個一對多組成)

多對多查詢的模型
用戶表和角色表的關係爲,一個用戶有多個角色,一個角色被多個用戶使用
多對多查詢的需求:查詢用戶同時查詢出該用戶的所有角色
在mybatis中多對多實現,跟一對多步驟是一樣,區別就在於sql語句
User和Role實體:

package cn.itcast.domain;

import java.util.Date;
import java.util.List;

//實體類
public class User {
    private Integer id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;

    //一個用戶可以具有多個角色
    private List<Role> roleList;

    public List<Role> getRoleList() {
        return roleList;
    }

    public void setRoleList(List<Role> roleList) {
        this.roleList = roleList;
    }

    public List<Order> getOrderList() {
        return orderList;
    }

    public void setOrderList(List<Order> orderList) {
        this.orderList = orderList;
    }

    //一個用戶具有多個訂單
    private List<Order> orderList;


    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    public String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public User() {
    }

    public User(Integer id, String username, Date birthday, String sex, String address, List<Role> roleList, List<Order> orderList) {
        this.id = id;
        this.username = username;
        this.birthday = birthday;
        this.sex = sex;
        this.address = address;
        this.roleList = roleList;
        this.orderList = orderList;
    }

    @Override
    public String toString() {
        return "User{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", birthday=" + birthday +
                ", sex='" + sex + '\'' +
                ", address='" + address + '\'' +
                ", roleList=" + roleList +
                ", orderList=" + orderList +
                '}';
    }
}

package cn.itcast.domain;

public class Role {
    private Integer id;
    private String roleName;
    private String roleDesc;

    public Role() {
    }

    public Role(Integer id, String roleName, String roleDesc) {
        this.id = id;
        this.roleName = roleName;
        this.roleDesc = roleDesc;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getRoleName() {
        return roleName;
    }

    public void setRoleName(String roleName) {
        this.roleName = roleName;
    }

    public String getRoleDesc() {
        return roleDesc;
    }

    public void setRoleDesc(String roleDesc) {
        this.roleDesc = roleDesc;
    }

    @Override
    public String toString() {
        return "Role{" +
                "id=" + id +
                ", roleName='" + roleName + '\'' +
                ", roleDesc='" + roleDesc + '\'' +
                '}';
    }
}

UserMapper接口:

public interface UserMapper {
    //一對多關聯
    public User findByIdWithOrders(Integer id);

    //多對多關聯
    public User findByIdWithRoles(Integer id);
}

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">
<mapper namespace="cn.itcast.dao.UserMapper">

    <resultMap id="userMap" type="cn.itcast.domain.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>

        <!--一對多關聯 collection標籤
         property="orderLlist" 關聯實體的屬性名
        ofType="cn.itcast.domain.Order" 關聯實體java類型(集合泛型的類型)
        -->
        <collection property="orderList" ofType="cn.itcast.domain.Order">
            <id column="oid" property="id"></id>
            <result column="ordertime" property="ordertime"></result>
            <result column="money" property="money"></result>
        </collection>
    </resultMap>
    <!--一對多查詢關聯-->
    <select id="findByIdWithOrders" parameterType="int" resultMap="userMap">
      SELECT *,o.id AS oid FROM `user` u INNER JOIN orders o ON u.`id` = o.`uid` WHERE u.`id`=#{id}
    </select>

    <!--多對多-->
    <resultMap id="userWithRoleMap" type="cn.itcast.domain.User">
        <id column="id" property="id"></id>
        <result column="username" property="username"></result>
        <result column="birthday" property="birthday"></result>
        <result column="sex" property="sex"></result>
        <result column="address" property="address"></result>
        <!--
            多對多實現步驟和一對多一樣(區別在於sql語句的不同)
        -->
        <collection property="roleList" ofType="cn.itcast.domain.Role">
            <id column="rid" property="id"></id>
            <result column="role_name" property="roleName"></result>
            <result column="role_desc" property="roleDesc"></result>
        </collection>
    </resultMap>
    <!--多對對的關聯-->
    <select id="findByIdWithRoles" parameterType="int" resultMap="userWithRoleMap">
select * from `user` u
inner join user_role ur onu.`id`=ur.`uid` -- 用戶連接中間表
inner join role r on ur.`rid`=r.`id` -- 根據中間表連接角色
where u.id=#{id} -- 用戶id作爲條件
        </select>
</mapper>

測試代碼:

    //多對多測試(根據用戶查詢角色)
    @Test
    public void test02() throws Exception {
        //獲取代理
        final UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findByIdWithOrders(41);
        System.out.println(user);
    }
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章