Day15 Mybatis (7) multi-table query (one-to-one, one-to-many)

Mybatis multi-table query

  1. The project cannot have only one table, generally multiple tables
  2. The multi-table relationship is one-to-one, one-to-many, and many-to-many
  3. The data to be queried comes from multiple tables. To use multi-table query
    Cartesian set, display inner join, left outer join, right outer join, and subquery select nested select.
  4. The result of the query should be encapsulated into a javaBean object, and focus on resultType and resultMap in Mybatis

Let's analyze the Mybatis multi-table relationship through the model of users and orders.

User table
Insert picture description here

Order table
Insert picture description here
Schema relationship
Insert picture description here

One, related query (one to one)

  1. From the perspective of an order , an order corresponds to a user, which represents a one-to-one relationship .
  2. The data comes from two tables, use join query, need to output all orders, use left outer join
  3. Query results can encapsulate data in two ways
  • resultType specifies a custom javaBean class (usually to write a new javaBean class)
  • resultMap specifies the mapping relationship (recommended to use without writing a new javaBean class) mapping file

1. Use resultType to write an OrderUser class

Write test

@Test
public void test01(){
    
    
    SqlSession sqlSession = MySessionUtils.getSession();

    OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
    List<OrderUser> list = orderDao.findAllOrderUser();
    
    sqlSession.close();
}

Create new class OrderUser

public class OrderUser {
    
    
    //订单的属性
    private int oid;
    private Integer user_id;
    private String number;
    private Date createtime;
    private String note;
    //用户的属性
    private int uid;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //省略get set toString方法
}    

Define interface methods

List<OrderUser> findAllOrderUser();

resultType configuration mapping

<select id="findAllOrderUser" resultType="cn.cyl.bean.OrderUser">
    select o.id as oid,
        o.user_id ,
        o.number,
        o.createtime,
        o.note,
        u.id as uid,
        u.username,
        u.birthday,
        u.sex,
        u.address
        from  `order` o left join `user` u
        on o.user_id=u.id;
</select>

Output result

Insert picture description here
Insert picture description here

summary:

Define a special javabean class as the output type, which defines all the fields of the sql query result set . This method is relatively simple and widely used in enterprises.

2. Using resultMap, define a special resultMap for mapping one-to-one query results.

Write test

@Test
public void test01(){
    
    
    SqlSession sqlSession = MySessionUtils.getSession();

    OrderDao orderDao = sqlSession.getMapper(OrderDao.class);
    List<Order> list = orderDao.findAllOrder2();
    
    sqlSession.close();
}

Transform the Order class

Through the object-oriented (has a) relationship, we can know that we can add a User class object to the Order class to represent which user this order belongs to.

public class Order {
    
    
    // 订单id
    private int id;
    // 用户id
    private Integer userId;
    // 订单号
    private String number;
    // 订单创建时间
    private Date createtime;
    // 备注
    private String note;

    //增加User成员变量来接收一条记录的用户的查询字段。
    private User user;
    //省略get set toString方法
} 

Define interface methods

//因为Order类中包含了一个User类的对象,它可以封装订单所对应的用户信息
List<Order> findAllOrder2();

Association configuration mapping of resultMap

<!--select标签中的属性resultMap,会在select语句执行之后,查找resultMap属性对应的resultMap标签
    在resultMap标签中必须指定order类与连接查询的结果字段的对应关系
        (1)property指定的java中的变量
        (2)column指定的是数据中的字段
            两者相同可以不写(但是要添加antoMapping="true")
        (3)association关联标签,表示自定义类的类型
        (4)autoMapping:关联查询必须添加此属性,表示自动映射。
            如果不添加,相同名的就查不到值-->
<resultMap id="findAllOrder2Map" type="cn.cyl.bean.Order" autoMapping="true">
    <id property="id" column="id"></id>
    <!--property:表示Order类中User类对象的名字
        javaType:表示Order类中包含的User类的全路径名
        autoMapping:表示如果字段名和属性名一致,则自动映射-->
    <association property="user" javaType="cn.cyl.bean.User" autoMapping="true">
        <!--查询的字段名为uid,成员变量名为id-->
        <id column="uid" property="id"/>
    </association>
</resultMap>
<select id="findAllOrder2" resultMap="findAllOrder2Map">
    select o.id as id,
        o.user_id as userId,
        o.number,
        o.createtime,
        o.note,
        u.id as uid,
        u.username,
        u.birthday,
        u.sex,
        u.address
        from  `order` o left join `user` u
        on o.user_id=u.id;
</select>

Output result

Insert picture description here
Insert picture description here

Two, related query (one to many)

  1. From the user's point of view, a user (User) can have multiple orders (Order), which represents a one-to-many relationship.
  2. The data comes from two tables, using join query, you need to output how many orders each user has
  3. The query result uses the collection tag to map List<element>

Write test

@Test
public void test01(){
    
    
    SqlSession sqlSession = MySessionUtils.getSession();

    UserDao userDao = sqlSession.getMapper(UserDao.class);
    List<User> list = userDao.findAllUsers();
    for(User user:list){
    
    
        System.out.println(user);
    }
    sqlSession.close();
}

Transform the User class

Add the User class to List<Order> to store all orders of the user

public class User {
    
    
    private int id;
    private String username;
    private Date birthday;
    private String sex;
    private String address;
    //变量类型是集合List
    private List<Order> orders;
    //省略get set toString方法
}

Define interface methods

List<User> findAllUsers();

Collection configuration mapping of ResultMap

<resultMap id="findAllUsersMap" type="cn.cyl.bean.User" autoMapping="true">
    <id property="id" column="uid"></id>
    <!--如果一个类中出现集合类型List,则需要使用collection标签来映射字段与变量的关系-->
    <!--property表示集合变量名,ofType表示集合元素的类型-->
    <collection property="orders" ofType="cn.cyl.bean.Order" autoMapping="true">
        <id property="id" column="oid"></id>
    </collection>
</resultMap>
<select id="findAllUsers" resultMap="findAllUsersMap">
    select u.id as uid,
        u.username,
        u.birthday,
        u.sex,
        u.address,
        o.id as oid,
        o.user_id as userId,
        o.number,
        o.createtime,
        o.note
        from `user` u left join `order` o
        on u.id=o.user_id;
</select>

Output result

Insert picture description here
Insert picture description here

Guess you like

Origin blog.csdn.net/qq_43639081/article/details/108856046