天天看點

Mybatis實作多表查詢(一對一、一對多、多對多)

文章目錄

    • 一、一對一查詢
      • 1.1 模型
      • 1.2 SQL語句
      • 1.3 建立Order和User實體類
      • 1.4 建立OrderMapper接口
      • 1.5 配置OrderMapper.xml
      • 1.6 測試
    • 二、一對多查詢
      • 2.1 模型
      • 2.2 SQL語句
      • 2.3 修改User和Order實體類
      • 2.4 建立UserMapper接口
      • 2.5 建立UserMapper.xml
      • 2.6 測試
    • 三、多對多查詢
      • 3.2 SQL語句
      • 3.3 修改User類,建立Role類
      • 3.4 UserMapper接口添加方法
      • 3.5 配置UserMapper.xml
      • 3.6 測試
    • 四、小結

一、一對一查詢

1.1 模型

使用者表和訂單表的關系為,一個使用者有多個訂單,一個訂單隻從屬于一個使用者

一對一查詢的需求:查詢一個訂單,與此同時查詢出該訂單所屬的使用者

Mybatis實作多表查詢(一對一、一對多、多對多)

1.2 SQL語句

對應的sql語句:

select * from orders o,user u where o.uid=u.id

查詢結果如下:

Mybatis實作多表查詢(一對一、一對多、多對多)

1.3 建立Order和User實體類

Order.java

public class Order {    
	private int id;    
	private Date ordertime;    
	private double total;    
	//代表目前訂單從屬于哪一個客戶    
	private User user;
	// 省略get set方法
}
           

User.java

public class User {
   private int id;    
   private String username;    
   private String password;    
   private Date birthday;
   // 省略get set方法
}
           

1.4 建立OrderMapper接口

public interface OrderMapper {    
	List<Order> findAll();
}
           

1.5 配置OrderMapper.xml

通過

sql

查詢并封裝資料,此處傳回類型使用的

resultMap

,在這裡完成資料的封裝。

<mapper namespace="com.happy.mapper.OrderMapper">
    <resultMap id="orderMap" type="order">
        <!--手動指定字段與實體屬性的映射關系
            column: 資料表的字段名稱
            property:實體的屬性名稱
        -->
        <id column="oid" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="total" property="total"></result>
        <result column="uid" property="user.id"></result>
        <result column="username" property="user.username"></result>
        <result column="password" property="user.password"></result>
        <result column="birthday" property="user.birthday"></result>
    </resultMap>   
    <select id="findAll" resultMap="orderMap">        
    	select * from orders o,user u where o.uid=u.id    
    </select>
</mapper>
           

當然,除了改方式外,還可通過

association

完成對象封裝,如下:

<resultMap id="orderMap" type="order">
    <!--手動指定字段與實體屬性的映射關系
        column: 資料表的字段名稱
        property:實體的屬性名稱
    -->
    <id column="oid" property="id"></id>
    <result column="ordertime" property="ordertime"></result>
    <result column="total" property="total"></result>
    <result column="uid" property="user.id"></result>
    <!--
        property: 目前實體(order)中的屬性名稱(private User user)
        javaType: 目前實體(order)中的屬性的類型(User)
    -->
    <association property="user" javaType="user">
        <id column="uid" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="birthday" property="birthday"></result>
    </association>
</resultMap>
           

1.6 測試

執行測試代碼,如下:

@Test
public void test1() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();

    OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
    List<Order> orderList = mapper.findAll();
    for (Order order : orderList) {
        System.out.println(order);
    }

    sqlSession.close();
}
           

輸出結果為:

Mybatis實作多表查詢(一對一、一對多、多對多)

二、一對多查詢

2.1 模型

使用者表和訂單表的關系為,一個使用者有多個訂單,一個訂單隻從屬于一個使用者

一對多查詢的需求:

查詢一個使用者,與此同時查詢出該使用者具有的訂單

Mybatis實作多表查詢(一對一、一對多、多對多)

2.2 SQL語句

對應的sql語句:

select *,o.id oid from user u left join orders o on u.id=o.uid;

查詢的結果如下:

Mybatis實作多表查詢(一對一、一對多、多對多)

2.3 修改User和Order實體類

Order.java

public class Order {    
	private int id;    
	private Date ordertime;    
	private double total;    
	//代表目前訂單從屬于哪一個客戶    
	private User user;
	// 省略get set方法
}
           

User.java

public class User {        
	private int id;    
	private String username;    
	private String password;    
	private Date birthday;
    //代表目前使用者具備哪些訂單    
    private List<Order> orderList;
    // 省略get set方法
}
           

2.4 建立UserMapper接口

public interface UserMapper {    
	List<User> findAll();
}
           

2.5 建立UserMapper.xml

<resultMap id="userMap" type="user">
    <id column="uid" property="id"></id>
    <result column="username" property="username"></result>
    <result column="password" property="password"></result>
    <result column="birthday" property="birthday"></result>
    <!--配置集合資訊
        property:集合名稱
        ofType:目前集合中的資料類型
    -->
    <collection property="orderList" ofType="order">
        <!--封裝order的資料-->
        <id column="oid" property="id"></id>
        <result column="ordertime" property="ordertime"></result>
        <result column="total" property="total"></result>
    </collection>
</resultMap>

<select id="findAll" resultMap="userMap">
    SELECT *,o.id oid FROM USER u,orders o WHERE u.id=o.uid
</select>
           

2.6 測試

執行如下測試代碼:

@Test
public void test2() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> all = mapper.findAll();
    for(User user : all){    
    	System.out.println(user.getUsername());    
    	List<Order> orderList = user.getOrderList();    
    	for(Order order : orderList){        
    		System.out.println(order);    
    	}    
    	System.out.println("----------------------------------");
    }
    sqlSession.close();
}
           

輸出結果為:

Mybatis實作多表查詢(一對一、一對多、多對多)

三、多對多查詢

使用者表和角色表的關系為,一個使用者有多個角色,一個角色被多個使用者使用

多對多查詢的需求:

查詢使用者同時查詢出該使用者的所有角色

Mybatis實作多表查詢(一對一、一對多、多對多)

3.2 SQL語句

對應的sql語句:

select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id inner join role r on ur.role_id=r.id;

查詢的結果如下:

Mybatis實作多表查詢(一對一、一對多、多對多)

3.3 修改User類,建立Role類

public class Role {    
	private int id;    
	private String rolename;
	// 省略get set方法
}
           
public class User {    
	private int id;    
	private String username;    
	private String password;    
	private Date birthday;
    //代表目前使用者具備哪些訂單    
    private List<Order> orderList;
    //代表目前使用者具備哪些角色    
    private List<Role> roleList;
    // 省略get set方法
}
           

3.4 UserMapper接口添加方法

添加查詢方法,如下:

3.5 配置UserMapper.xml

<resultMap id="userRoleMap" type="user">
        <!--user的資訊-->
        <id column="userId" property="id"></id>
        <result column="username" property="username"></result>
        <result column="password" property="password"></result>
        <result column="birthday" property="birthday"></result>
        <!--user内部的roleList資訊-->
        <collection property="roleList" ofType="role">
            <id column="roleId" property="id"></id>
            <result column="roleName" property="roleName"></result>
            <result column="roleDesc" property="roleDesc"></result>
        </collection>
    </resultMap>

    <select id="findUserAndRoleAll" resultMap="userRoleMap">
        SELECT * FROM USER u,sys_user_role ur,sys_role r WHERE u.id=ur.userId AND ur.roleId=r.id
    </select>
           

3.6 測試

執行如下測試代碼:

@Test
public void test3() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();

    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    List<User> all = mapper.findAllUserAndRole();
    for(User user : all){    
    	System.out.println(user.getUsername());    
    	List<Role> roleList = user.getRoleList();    
    	for(Role role : roleList){        
    		System.out.println(role);    
    	}    
    System.out.println("----------------------------------");}
    sqlSession.close();
}
           

輸出結果為:

Mybatis實作多表查詢(一對一、一對多、多對多)

四、小結

Mybatis

多表配置方式:

  • 一對一,使用

    <resultMap>

    做配置
  • 一對多,使用

    <resultMap>

    <collection>

    做配置
  • 多對多,使用

    <resultMap>

    <collection>

    做配置