Mybatis中的多表查詢

Mybatis中的多表查詢

1.mybatis中的表之間的關係分析
表之間的關係有:
1. 一對多
2. 多對一
3. 一對一
4. 多對多
2. 表關係舉例
1. 用戶和訂單就是一對多
    {
        一個用戶可以下多個訂單
    }
2. 訂單和用戶就是多對一
    {
        多個訂單屬於同一個用戶
    }
3. 人和身份證號就是一對一
    {
        一個人對應一個身份證號
        一個身份證號只能對應一個人
    }
4. 老師和學生之間就是多對多的關係
    {
        一個老師可以教多個學生
        一個學生可以被多個老師教過
    }
3. 注意:在Mybatis中,把多對一看成是一對一進行操作。
如:多個賬戶對應一個用戶,那麼每個賬戶都對應一個用戶。所以在mybatis中把多對一看成是一對一進行操作
4. 多對一(mybatis中的一對一)、一對多、多對多三種方式在mybatis中的操作方式
  1. 多對一(mybatis中的一對一)

    1. 以賬戶Account和用戶User爲例。完成:查詢所有賬戶的同時,查詢出該賬戶對應的User用戶

    account表:Mybatis中的多表查詢

    user表:Mybatis中的多表查詢

    1. 操作方式:【重點】
    在多的一方(即account方)對應的實體類中加入一方(即user方)的對象引用
    1. 實體類代碼:
    public class Account implements Serializable {
        private Integer ID;
        private Integer UID;
        private Double MONEY;
        //從表實體應該包含一個主表實體的對象引用
        //多對一關係,要在多的一方添加上一方的主鍵,作爲多的一方的外鍵,
        // 在Java中要在多的一方加上一個一方的對象引用
        private User user;
        ...
    }
    public class User implements Serializable {
            private Integer id;
            private String username;
            private Date birthday;
            private String sex;
            private String address;
        ...
    }
    1. IAccountDao接口
    public interface IAccountDao {
    
        //查詢所有賬戶的同時,查詢出該賬戶對應的User用戶
        public List<Account> findAll();
    }
    1. 接口映射文件配置
 <?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="itlearn.zhi.dao.IAccountDao">
     <!-- type:爲當前進行配置的實體類名,在此使用了typeAliases標籤,所以可以直接寫類名,不區分大小寫 -->
     <resultMap id="accountUserMap" type="account">
>    >         <!--注意:在sql語句中給a.id取了別名,所以在這裏也要 用別名配置 【重點】 -->
>    >         <id property="ID" column="aid"></id>
>    >         <result property="UID" column="UID"></result>
>    >         <result property="MONEY" column="MONEY"></result>
>    >         <!-- 對User屬性進行配置,在此只要不是集合就使用association標籤
>    >          colum:指的是該屬性的值是通過數據庫中哪個字段來獲取的
>    >      JavaType:要封裝成的類型。
>    >      -->
>    >         <association property="user" column="UID" javaType="user">
>    >             <id property="id" column="id"></id>
>    >             <result property="username" column="username"></result>
>    >             <result property="birthday" column="birthday"></result>
>    >             <result property="sex" column="sex"></result>
>    >             <result property="address" column="address"></result>
>    >         </association>
>    >     </resultMap>
>    >     
>    >     <select id="findAll" resultMap="accountUserMap">
>    >         <!-- 注意:因爲在account和user表中都有id字段,在sql中需要起別名,防止resultMap中發生映射錯誤,同時也需要在resultMap中給取了別名的字段配置Colum-->
>    >         SELECT u.*,a.ID AS aid,a.UID,a.MONEY FROM account a ,user u WHERE a.UID = u.id;
>    >     </select>
>    > </mapper>
  1. 一對多
  1. 也是以Account表和User表爲例。完成:查詢所有用戶的同時,展示出該用戶下所有賬戶信息
public class User implements Serializable {
        private Integer id;
        private String username;
        private Date birthday;
        private String sex;
        private String address;

        //一個用戶有多個賬戶
        //那麼在一方需要加上一個多方的對象集合
        private List&lt;Account&gt; accounts;
      ...
}
  1. 操作方式
在一的一方的實體類中,加入多的一方的集合引用。即:在一的一方(User方)加入:
private List&lt;Account&gt; accounts;
  1. IUserDao接口
public interface IUserDao {
    //查詢所有用戶,並查詢到該用戶下所有賬戶信息
    public List&lt;User&gt; findAll();
}
  1. 接口映射配置文件中的配置
> > > <?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="itlearn.zhi.dao.IUserDao">
> > >     <resultMap id="userAccountMap" type="user">
> > >         <id property="id" column="id"/>
> > >         <result property="username" column="username"></result>
> > >         <result property="birthday" column="birthday"></result>
> > >         <result property="sex" column="sex"></result>
> > >         <result property="address" column="address"></result>
> > >         <!-- 因爲使集合引用,所以要用collection標籤,如果不是集合就用association標籤
> > >       ofType:指定當前要封裝的類型
> > >       -->
> > >         <collection property="accounts" ofType="account">
> > >             <!-- 因爲在sql語句中爲a.id起了別名,所以在這裏也要用別名配置 -->
> > >             <id property="ID" column="aid"></id>
> > >             <result property="UID" column="UID"></result>
> > >             <result property="MONEY" column="MONEY"></result>
> > >         </collection>
> > >     </resultMap>
> > > 
> > >     <select id="findAll" resultMap="userAccountMap">
> > >         SELECT u.*,a.id as aid,a.UID,a.MONEY FROM USER u LEFT OUTER JOIN account a ON u.`id` = a.`UID`;
> > >     </select>
> > > </mapper>
  1. 結果顯示:
-----------------------
User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京'}
[Account{ID=1, UID=41, MONEY=1000.0}, Account{ID=3, UID=41, MONEY=2000.0}]
-----------------------
User{id=42, username='小二王', birthday=Fri Mar 02 15:09:37 CST 2018, sex='女', address='北京金燕龍'}
[]
-----------------------
User{id=45, username='傳智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龍'}
[Account{ID=2, UID=45, MONEY=1000.0}]
...
可見:[Account{ID=1, UID=41, MONEY=1000.0}, Account{ID=3, UID=41, MONEY=2000.0}]mybatis會自動幫我們把用戶下面的多個賬戶進行封裝進集合。
  1. 多對多:在多對多的關係中,會有一張中間表的存在,並且存放的是兩個表的主鍵
  1. 以User和Role表爲例

Role表:Mybatis中的多表查詢

  1. 操作方式
在兩張表對應的實體類中分別加入對方的集合引用【重點】
  1. Role實體
public class Role implements Serializable {
    private Integer id;
    private String roleName;
    private String roleDesc;

    private List&lt;User&gt; users;
    ...
}
  1. User實體
public class User implements Serializable {
        private Integer id;
        private String username;
        private Date birthday;
        private String sex;
        private String address;

        private List&lt;Role&gt; roles;
    ...
}
  1. 實現1:在查詢所有用戶的同時查詢出該用戶的角色信息. 接口方法:findAll
> > > <?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="itlearn.zhi.dao.IUserDao">
> > > 
> > >     <resultMap id="userRole" type="user">
> > >         <id property="id" column="id"/>
> > >         <result property="username" column="username"></result>
> > >         <result property="birthday" column="birthday"></result>
> > >         <result property="sex" column="sex"></result>
> > >         <result property="address" column="address"></result>
> > >         <collection property="roles" ofType="role">
> > >             <id property="id" column="rid"></id>
> > >             <result property="roleName" column="ROLE_NAME"></result>
> > >             <result property="roleDesc" column="ROLE_DESC"></result>
> > >         </collection>
> > >     </resultMap>
> > > 
> > >     <select id="findAll" resultMap="userRole">
> > >         SELECT u.*,r.`ID` AS rid,r.`ROLE_NAME`,r.`ROLE_DESC` FROM USER u LEFT JOIN user_role ur
> > >         ON u.`id` = ur.`UID`
> > >         LEFT JOIN role r
> > >         ON ur.`RID` = r.`ID`;
> > >     </select>
> > > </mapper>
  1. 查詢結果:
User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京'}
[Role{id=1, roleName='院長', roleDesc='管理整個學院'}, Role{id=2, roleName='總裁', roleDesc='管理整個公司'}]
-----------------------
User{id=42, username='小二王', birthday=Fri Mar 02 15:09:37 CST 2018, sex='女', address='北京金燕龍'}
[]
-----------------------
User{id=43, username='小二王', birthday=Sun Mar 04 11:34:34 CST 2018, sex='女', address='北京金燕龍'}
[]
-----------------------
User{id=45, username='傳智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龍'}
[Role{id=1, roleName='院長', roleDesc='管理整個學院'}]
...
  1. 實現2:在查詢所有角色的同時查詢出該角色下的用戶信息. 接口方法:findAll
> > > <?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="itlearn.zhi.dao.IRoleDao">
> > >     <resultMap id="roleUser" type="role">
> > >         <id property="id" column="rid"></id>
> > >         <result property="roleName" column="ROLE_NAME"></result>
> > >         <result property="roleDesc" column="ROLE_DESC"></result>
> > >         <collection property="users" ofType="user">
> > >             <id property="id" column="id"/>
> > >             <result property="username" column="username"></result>
> > >             <result property="birthday" column="birthday"></result>
> > >             <result property="sex" column="sex"></result>
> > >             <result property="address" column="address"></result>
> > >         </collection>
> > >     </resultMap>
> > > 
> > >     <select id="findAll" resultMap="roleUser">
> > >         SELECT r.`ID` AS rid,r.`ROLE_NAME`,r.`ROLE_DESC`,u.* FROM role r LEFT JOIN user_role ur
> > >         ON r.`ID` = ur.`RID`
> > >         LEFT JOIN USER u
> > >         ON ur.`UID` = u.`id`;
> > >     </select>
> > > </mapper>

查詢結果:

Role{id=1, roleName='院長', roleDesc='管理整個學院'}
[User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京'}, User{id=45, username='傳智播客', birthday=Sun Mar 04 12:04:06 CST 2018, sex='男', address='北京金燕龍'}]
-----------------------
Role{id=2, roleName='總裁', roleDesc='管理整個公司'}
[User{id=41, username='老王', birthday=Tue Feb 27 17:47:08 CST 2018, sex='男', address='北京'}]
-----------------------
Role{id=3, roleName='校長', roleDesc='管理整個學校'}
[]
5. 多表操作總結
  1. 多對一:在多的一方加入一方的對象引用;private User user; 在resultMap中使用:association標籤對user進行配置
  2. 一對多:在一的一方加入多的一方的集合引用:private List<Account> accounts;在resultMap中使用:collection標籤對accounts進行配置
  3. 多對多:在每一方的實體類中加入另一方的集合引用。在resultMap中使用:collection標籤對集合引用進行配置
6. 注意:
1. 在進行resultMap配置時,如果兩個表中id字段相同,則需要進行對其中一個起別名,並且在resultMap中使用別名進行配置。
2. 多對多sql語句的書寫。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章