Mybatis的多表查询

一、一对一的查询(<assocation>)

1、创建User类(用户类):
    public class User implements Serializable {
         private static final long serialVersionUID = 6716332190979093860L;
         private Integer Id;
         private String username;
         private String sex;
         private String password;
         private Date birthday;
         private Department department;
        //get/set方法
@Override
public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + ((age == null) ? 0 : age.hashCode());
    result = prime * result + ((department == null) ? 0 : department.hashCode());
    result = prime * result + ((id == null) ? 0 : id.hashCode());
    result = prime * result + ((password == null) ? 0 : password.hashCode());
    result = prime * result + ((username == null) ? 0 : username.hashCode());
   return result;
 }
@Override
public boolean equals(Object obj) {
     if (this == obj)
         return true;
     if (obj == null)
        return false;
     if (getClass() != obj.getClass())
        return false;
     User other = (User) obj;
     if (age == null) {
        if (other.age != null)
           return false;
      } else if (!age.equals(other.age))
           return false;
      if (department == null) {
      if (other.department != null)
           return false;
      } else if (!department.equals(other.department))
           return false;
      if (id == null) {
          if (other.id != null)
             return false;
     } else if (!id.equals(other.id))
            return false;
      if (password == null) {
      if (other.password != null)
             return false;
      } else if (!password.equals(other.password))
             return false;
      if (username == null) {
      if (other.username != null)
             return false;
       } else if (!username.equals(other.username))
             return false;
    return true;
   }
2、创建Department类(部门类)
  public class Department {
     private Integer dep_id;
     private String  dep_name;
     private String  manager;
     //get/set方法
   @Override
   public int hashCode() {
     final int prime = 31;
     int result = 1;
     result = prime * result + ((id == null) ? 0 : id.hashCode());
     result = prime * result + ((name == null) ? 0 : name.hashCode());
     return result;
    }
 @Override
public boolean equals(Object obj) {
    if (this == obj)
       return true;
    if (obj == null)
       return false;
    if (getClass() != obj.getClass())
       return false;
       Department other = (Department) obj;
    if (id == null) {
    if (other.id != null)
        return false;
     } else if (!id.equals(other.id))
        return false;
     if (name == null) {
     if (other.name != null)
        return false;
     } else if (!name.equals(other.name))
       return false;
  return true;
}
 

分析

  • 我们知道一个用户只能属于一个部门,因此这里在User类中只是使用了Department对象,而不是个集合
  • 那么我们想要查询所有的用户信息和其所在的部门信息,此时的sql语句为:select * from db_user u left join db_department d on u.dep_id=d.dep_id;。但是我们在mybaits中如果使用这条语句查询,那么返回的结果类型是什么呢?如果是User类型的,那么查询结果返回的还有Department类型的数据,那么肯定会对应不上的。
  • 我们可以使用resultMap解决对应问题

实现

  • 使用resultMap解决查询结果的对应问题
    • 这里一定要在resultMap将每一个字段和查询结果返回的字段对应上,否则此时的结果就为null
<!-- 定义resultMap -->
<resultMap type="User" id="userDepartment">
  <!-- 配置id的对应 -->
  <id property="Id" column="id" javaType="java.lang.Integer"/>
 
  <!-- 配置其他字段的对应关系
       column: 查询结果中的列名字,如果没有起别名,那么就是表中的字段名
       property: java类中的属性名称
   -->
    <result property="username" column="name" javaType="java.lang.String"/>
    <result property="sex" column="sex" javaType="java.lang.String"/>
    <result property="birthday" column="birthday" javaType="java.util.Date"/>
    <result property="password" column="password" javaType="java.lang.String"/>
 
   <!-- 配置对1的数据类型,即User类中的Department对象是单一的具体类型
        property: 这个是在User类中的字段名称
        javaType: 这个是java类的全名,是Department类的全名
   -->
   <association property="department" javaType="Department">
        <id property="dep_id" column="dep_id"/>
        <result property="dep_name" column="dep_name"/>
        <result property="manager" column="manager"/>
    </association>
</resultMap>
 
<!--
    User findUserAndDepartment();
    resultMap: 指定上面resultMap的id的值
-->
  <select id="findUserAndDepartment" resultMap="userDepartment">
      select * from db_user u left join db_department d on u.dep_id=d.dep_id
  </select>
 
注: association字面意思关联,这里只专门做一对一关联; property表示是属性名称; javaType表示该属性是什么类型对象
 
测试方法
public class MybatisTest {
    @Test
    public void test() {
        SqlSession session = DBTools.getSession();
        UserMapper mapper = session.getMapper(UserMapper.class);
        try {
            List<User> list = mapper.findUserAndDepartment();
            for(User u:list) {
                System.out.println(u);
            }
            session.commit();
        } catch (Exception e) {
            e.printStackTrace();
            session.rollback();
        }finally {
            session.close();
        }
    }
}
 
 
二、一对多的查询(<collection>):一个宿舍可以住多个学生,那么我们通过宿舍查询学生,那么就是一对多查询。
   1、创建Student类:
     public class Student implements Serializable {
          private static final long serialVersionUID = 8673238196042278929L;
          private Integer id;
          private String name;
          private Integer age;
          //省略set/get方法
      }
   2、创建Dormitory类: 其中有一个Set<Student>集合用来存储学生对象
     public class Dormitory implements Serializable{
         private static final long serialVersionUID = 1359749532219773083L;
         private Integer id;
         private String number; //编号
         private Set<Student> students; //学生集合,一个宿舍可以住多个学生
         //省略set/get方法
       }
    3、创建表
      create table student(id int primary key auto_increment,name varchar(10) not null unique,age int,dormitory_id int);
    create table dormitory(id int primary key auto_increment,number varchar(20) not null unique);
 
    4、创建DormitoryMapper.java(接口)
      public interface DormitoryMapper {
          //查询所有的宿舍信息
          List<Dormitory> findDormitories();
         //根据id查询宿舍信息
          Dormitory findDormitory(Integer id);
       }
     5、创建DormitoryMapper.xml
        
        <!-- MyBatis的接口映射文件,根节点是mapper -->
          <!-- 接口映射文件是与Java接口文件(interface)相对应的 -->
          <!-- 根节点的namespace属性用于指定Java接口文件 -->
         <mapper namespace="cn.tedu.spring.mapper.DormitoryMapper">
      
                <!-- 定义resultMap-->
            <resultMap type="cn.tedu.spring.entity.Dormitory" id="DormitoryStudentRs">
            <id column="id" property="id"/>
          <result column="number" property="number"/>
         <!-- 因为Dormitoy中的Student使用set集合存储的,因此这里使用collection标签
             property : Java类中的集合对象
             ofType: 集合对象的泛型类型
         -->
            <collection property="students" ofType="cn.tedu.spring.entity.Student">
               <id column="id" property="id"/>
               <result column="name" property="name"/>
               <result column="age" property="age"/>
           </collection>
        </resultMap>
       <!-- List<Dormitory> findDormitories();查询所有的宿舍信息
            resultMap: 指定前面定义的resultMap
        -->
         <select id="findDormitories" resultMap="DormitoryStudentRs">
             select * from student s left join dormitory d on s.dormitory_id=d.id
         </select>
             <!--
                    Dormitory findDormitory(Integer id);
               -->
                   <select id="findDormitory" resultType="cn.tedu.spring.entity.Dormitory">
                 select * from dormitory where id=#{id}
            </select>
         </mapper>
 
注: collection字面意思是集合,这里专门做一对多关联 ,property表示集合类型属性名称,ofType表示集合中的对象是什么类型
 
    6、在配置文件中添加DormitoryMapper.xml文件
       
    7、测试
         @Test
         public void testFindDormitory() {
           DormitoryMapper dormitoryMapper=ac.getBean("dormitoryMapper",DormitoryMapper.class);
           //执行查询方法
           List<Dormitory> dormitories=dormitoryMapper.findDormitories();
           for (Dormitory dormitory : dormitories) {
                System.out.println(dormitory);
             }
            ac.close();
          }
 
三、多对多查询:
    
       1、类之间的关系:
     
         2、对应的表:
     
            
 
          3、思路
      
           (1)将用户信息映射到User中;
       (2) 在User类中添加订单列表属性List<Orders>ordersList,将用户创建的订单映射到ordersList中;
       (3)在Orders中添加订单明细列表属性List<OrderDetail>orderDetails,将订单的明细映射到orderDetails中;
       (4)在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items中。
 
           4、定义持久化类:
  
                User.java
          //客户类
       public class User implements Serializable{
         private static final long serialVersionUID = 1L;
         private int id; //编号
         private String username; //用户名
         private String gender; //性别
         private Date birthday; //生日
         private String address; //地址
         private List<Orders> OrdersList;//订单列表
             } 
 
              Items.java
          //商品类
    public class Items implements Serializable{
       private static final long serialVersionUID = 1L;
       private int id; //商品编号
       private String name;//商品名称
       private double price;//商品价格
       private String detail;//商品描述
       private String pic;//商品图片
       private Date createTime;//生产时间
            }
 
         Orders.java
        //订单类
    public class Orders implements Serializable {
        private static final long serialVersionUID = 1L;
        private Integer id;//流水号
        private Integer userId;//用户编号
        private String number;//订单编号
        private Date createTime;//创建时间
        private String note;//备注
        private List<Orderdetail> orderdetails;//订单明细
    }
      Orderdetail.java
      //订单明细
    public class Orderdetail implements Serializable{
       private static final long serialVersionUID = 1L;
       private Integer id;
       private Integer ordersId;//订单编号
       private Integer itemsId;//商品编号
       private Double  itemsNum;//商品数量
       private Items items;//明细对应的商品信息
     }
   5、创建代理 即mapper.java
        public interface OrdersMapperUser {
       //查询用户购买的商品信息
       public List<User> findUserAndItemsResultMap() throws Exception;
      }
   6、创建映射文件OrdersMapperCustom.xml  
    <mapper namespace="com.mybatis.mapper.OrdersMapperUser">
   <!--查询用户购买的商品-->
    <resultMap id="UserAndItemsResultMap" type="User">
      <!-- 用户信息映射 -->
      <id property="id" column="user_id" javaType="java.lang.Integer"/>
      <result property="username" column="user_name" javaType="java.lang.String"/>
      <result property="gender" column="user_gender" javaType="java.lang.String"/>
      <result property="birthday" column="user_birthday" javaType="java.util.Date"/>
      <result property="address" column="user_address" javaType="java.lang.String"/>
     
      <!--订单信息-->
      <!--一个用户可以对应多个订单,故使用collection映射-->
      <collection property="OrdersList" ofType="Orders" fetchType="lazy">
         <id property="id" column="order_id" javaType="java.lang.Integer" />
         <result property="userId" column="user_id" javaType="java.lang.Integer"/>
         <result property="number" column="order_number" javaType="java.lang.String"/>
         <result property="createTime" column="order_createTime" javaType="java.util.Date"/>
         <result property="note" column="order_note" javaType="java.lang.String"/>
        
           <!--订单明细-->
           <!--一个订单包括多个明细,故使用collection-->
            <collection property="orderdetails" ofType="Orderdetail" fetchType="lazy">
               <id property="id" column="orderdetil_id" javaType="java.lang.Integer"/>
               <result property="itemsId" column="item_id" javaType="java.lang.Integer"/>
               <result property="ordersId" column="order_id" javaType="java.lang.Integer"/>
               <result property="itemsNum" column="item_num" javaType="java.lang.Double"/>
              
                 <!--商品信息-->
                 <!--一个订单明细对应一个商品,故使用association -->
                 <association property="items" javaType="Items">
                     <id property="id" column="item_id" javaType="java.lang.Integer"/>
                     <result property="name" column="item_name" javaType="java.lang.String"/>
                     <result property="price" column="item_price" javaType="java.lang.Double"/>
                     <result property="detail" column="item_detail" javaType="java.lang.String"/>
                     <result property="pic" column="item_picture" javaType="java.lang.String"/>
                     <result property="createTime" column="createTime" javaType="java.util.Date"/>
                 </association>
            </collection>
      </collection>
    </resultMap>
    <select id="findUserAndItemsResultMap" resultMap="UserAndItemsResultMap">
       SELECT
        orders.*,
        user.user_name,
        user.user_gender,
        user.user_address,
        orderdetail.orderdetail_id,
        orderdetail.item_id,
        orderdetail.item_num,
        orderdetail.order_id,
        items.item_name,
        items.item_detail,
        items.item_price
        FROM
        orders,
        user,
        orderdetail,
        items
        WHERE orders.user_id=user.user_id AND orders.order_id = orderdetail.order_id AND orderdetail.item_id=items.item_id
    </select>
</mapper>  
7、测试
posted @ 2019-05-31 16:08  #独狼  阅读(319)  评论(0编辑  收藏  举报