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表:

    user表:

    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表:

  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语句的书写。
©著作权归作者所有:来自51CTO博客作者Eternal_Summer的原创作品,如需转载,请注明出处,否则将追究法律责任

更多相关文章

  1. android studio怎么更换默认主题?
  2. Android(安卓)页面手势滑动
  3. 获取Android设备的唯一识别码UUID
  4. android用SharedPreferences保存登录账户密码
  5. 8款让前端开发者心动的jQuery/CSS3应用
  6. Android数据解析-JSON解析
  7. 10月份推荐android开发职位#安卓巴士公益推荐工作#
  8. ionic-android、ios账户绑定手机标识
  9. Fragment - 用法+demo

随机推荐

  1. Android自定义视图三:给自定义视图添加“
  2. 【原创】Android 耗电信息统计服务——Ba
  3. android mms流播放器
  4. android 判断是否支持闪光灯
  5. Android中C/C++的日志打印
  6. OMS:拥有Android血统的智能操作系统王
  7. Android中的异步消息处理机制Hander
  8. Android上的Back键事件捕获
  9. 如何判断用户用的是Android手机还是IOS手
  10. 2017 年 Android 领域大事件回顾