實際工作中,一定會遇到多表查詢業務。所以多表查詢是必學的內容。本文記錄學習一對一多表查詢簡單入門。
以訂單對用戶爲例:一個訂單隻能屬於一個用戶。
表數據:
- orders表:
- user表:
Orders實體類(其中包含User屬性用於表示一對一關係,爲了便於顯示User屬性是否查到並封裝,我在toString中輸出了User屬性,又爲了防止User沒封裝進去而報空指針,所以手動new了一個User對象):
package hh.pojo; import java.io.Serializable; import java.util.Date; public class Orders implements Serializable { /** * */ private static final long serialVersionUID = 1L; private Integer id; private Integer user_id; private String number; private Date datetime; // 引用 private User user = new User(); public User getUser() { return user; } public void setUser(User user) { this.user = user; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUser_id() { return user_id; } public void setUser_id(Integer user_id) { this.user_id = user_id; } public String getNumber() { return number; } public void setNumber(String number) { this.number = number; } public Date getDatetime() { return datetime; } public void setDatetime(Date datetime) { this.datetime = datetime; } @Override public String toString() { return "Orders [id=" + id + ", user_id=" + user_id + ", number=" + number + ", user.name=" + user.getName() + "]"; } }
Mapper接口(OrderMapper.java):
package hh.mapper; import java.util.List; import hh.pojo.Orders; public interface OrderMapper { // 一對一多表查詢 public List<Orders> selectOrderList(); }
mapper映射文件(OrderMapper.xml):
<?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"> <!-- namespace:命名空間,用於隔離sql,因爲不同mapper中可能有同名方法,命名空間起到區分作用 --> <mapper namespace="hh.mapper.OrderMapper"> <resultMap type="Orders" id="order"> <id column="id" property="id" /> <result column="user_id" property="user_id"/> <result column="number" property="number"/> <association property="user" javaType="User"> <id column="user_id" property="id" /> <result column="name" property="name"/> </association> </resultMap> <select id="selectOrderList" resultMap="order"> select o.id, o.user_id, o.number, u.name from orders o left join user u on o.user_id = u.id </select> </mapper>
測試代碼:
@Test public void testOrder2User() throws Exception { InputStream ins = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(ins); SqlSession session = sessionFactory.openSession(); OrderMapper mapper = session.getMapper(OrderMapper.class); List<Orders> orderList = mapper.selectOrderList(); for (Orders orders : orderList) { System.out.println(orders); } }
執行結果:
DEBUG [main] - ==> Preparing: select o.id, o.user_id, o.number, u.name from orders o left join user u on o.user_id = u.id DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 3 Orders [id=1, user_id=1, number=100000, user.name=張三] Orders [id=2, user_id=1, number=100001, user.name=張三] Orders [id=5, user_id=6, number=100004, user.name=胡歌]
注意:使用Mybatis進行一對一多表查詢時,建議使用手動映射,也就是resultMap,並且將要得到的屬性全部列出。
在以上例子情況下(使用對象屬性的形式表達一對一關係),經測試驗證:
-
1. 當使用自動映射(resultType)時,只會自動封裝數據庫字段名與屬性名相同的數據,名字不同的數據和對象屬性的數據不會自動封裝。
-
2. 採用手動映射時,要將所有想要得到的數據全部手動寫出映射關係,不寫出的數據不會進行映射封裝。
- 舉個手動映射不全的例子:
- mapper:
<resultMap type="Orders" id="order"> <id column="id" property="id" /> <result column="user_id" property="user_id"/> <association property="user" javaType="User"> <id column="user_id" property="id" /> </association> </resultMap> <select id="selectOrderList" resultMap="order"> select o.id, o.user_id, o.number, u.name from orders o left join user u on o.user_id = u.id </select>
- 測試代碼與上面的相同,執行結果如下:
DEBUG [main] - ==> Preparing: select o.id, o.user_id, o.number, u.name from orders o left join user u on o.user_id = u.id DEBUG [main] - ==> Parameters: DEBUG [main] - <== Total: 3 Orders [id=1, user_id=1, number=null, user.name=null] Orders [id=2, user_id=1, number=null, user.name=null] Orders [id=5, user_id=6, number=null, user.name=null]
可以看到沒有手動寫出屬性(number&user.name)都沒有封裝進去。