#MyBatis多表查詢 #多對一、一對多的兩種實現方式 @FDDLC
方式一(常用):
我們知道,一個使用者可以對應多個賬戶,一個賬戶只能對應一個使用者,即賬戶和使用者之間存在多對一的關係。為了表示這種關係,在賬戶類中額外增加一個使用者類的成員:
對應的mapper配置如下:
<?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="cn.liuxingchang.dao.AccountDao"> <resultMap id="accountWithUser" type="cn.liuxingchang.domain.Account"> <id property="id" column="id" /> <result property="uid" column="uid" /> <result property="money" column="money" /> <association property="user" javaType="cn.liuxingchang.domain.User"> <id property="id" column="user_id" /> <result property="name" column="name" /> <result property="age" column="age" /> </association> </resultMap> <select id="findAll" resultMap="accountWithUser"> select a.*, u.id as user_id, name, u.age from account a, user u where a.uid = u.id </select> </mapper>
為了對多表查詢結果的封閉,先定義了一個<resultMap>,然後在<select>標籤裡使用。這裡的難點是<resultMap>的書寫。id、money、uid都好理解,可能疑惑的地方是怎麼給Account類裡的user成員賦值。如你所見,用了個association標籤!
association的property是user好理解,但沒有column屬性,即資料表中沒有對應的列名。沒有column,但多了個javaType,其實又相當於來了個javaType到相應資料表的對映,即這個association標籤相當於是專用於內嵌的<resultMap>標籤!
這裡補充幾個注意事項:
1、如果在SQL語句中欄位取了別名的話,column屬性也應該填別名,而不能是原欄位名。
2、表取了別名後,別名可以隨便用;欄位取了別名後在where條件裡卻只能用原欄位名,而不能用別名。
方式二(不常用):使用繼承(也可以直接把Account類和User類的部分或全部屬性合併)
對應的ExtendedAccount類:
對應的SQL配置:
<select id="findAll2" resultType="cn.liuxingchang.domain.ExtendedAccount"> select a.*, name, u.age from account a, user u where a.uid = u.id </select>
說明:
1、用的是resultType屬性而非像方式一那樣必須使用resultMap。
2、account表中的uid和user表中的id是一樣的,故只保留了uid。
最後附上原始碼:
專案結構:
資料庫的相關資訊:
MySQL:8.0.16 port:3306 database:multi_table
account表:
user表:
Account類:
package cn.liuxingchang.domain; import java.io.Serializable; public class Account implements Serializable { private Integer id; private Integer uid; private Double money; private User user; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Double getMoney() { return money; } public void setMoney(Double money) { this.money = money; } public User getUser() { return user; } public void setUser(User user) { this.user = user; } @Override public String toString() { return "Account{" + "id=" + id + ", uid=" + uid + ", money=" + money + ", user=" + user + '}'; } }
ExtendedAccount類:
package cn.liuxingchang.domain; public class ExtendedAccount extends Account { private String name; private Integer age; public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return super.toString() + " ### " + "ExtendedAccount{" + "name='" + name + '\'' + ", age=" + age + '}'; } }
User類:
package cn.liuxingchang.domain; import java.io.Serializable; public class User implements Serializable { private Integer id; private String name; private Integer age; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + '}'; } }
AccountDao介面:
package cn.liuxingchang.dao; import cn.liuxingchang.domain.Account; import cn.liuxingchang.domain.ExtendedAccount; import java.util.List; public interface AccountDao { List<Account> findAll(); List<ExtendedAccount> findAll2(); }
AccountMapper.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"> <mapper namespace="cn.liuxingchang.dao.AccountDao"> <resultMap id="accountWithUser" type="cn.liuxingchang.domain.Account"> <id property="id" column="id" /> <result property="uid" column="uid" /> <result property="money" column="money" /> <association property="user" javaType="cn.liuxingchang.domain.User"> <id property="id" column="user_id" /> <result property="name" column="name" /> <result property="age" column="age" /> </association> </resultMap> <select id="findAll" resultMap="accountWithUser"> select a.*, u.id as user_id, name, u.age from account a, user u where a.uid = u.id </select> <select id="findAll2" resultType="cn.liuxingchang.domain.ExtendedAccount"> select a.*, name, u.age from account a, user u where a.uid = u.id </select> </mapper>
mybatis.xml:
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="mysql"> <environment id="mysql"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/multi_table?characterEncoding=UTF8&serverTimezone=Asia/Shanghai"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mapper/AccountMapper.xml" /> </mappers> </configuration>
pom.xml:
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>P074_MyBatis_Many2One</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> </dependencies> </project>
Test.java:
import cn.liuxingchang.dao.AccountDao; import cn.liuxingchang.domain.Account; import cn.liuxingchang.domain.ExtendedAccount; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.After; import org.junit.Before; import java.io.InputStream; import java.util.List; public class Test { private InputStream in; private SqlSessionFactory factory; private SqlSession sqlSession; private AccountDao accountDao; @Before public void before() throws Exception { in = Resources.getResourceAsStream("mybatis.xml"); factory = new SqlSessionFactoryBuilder().build(in); sqlSession = factory.openSession(); accountDao = sqlSession.getMapper(AccountDao.class); } @After public void after() throws Exception { sqlSession.commit(); sqlSession.close(); in.close(); } @org.junit.Test public void findAllTest() { List<Account> accounts = accountDao.findAll(); for (Account account: accounts) { System.out.println(account); } } @org.junit.Test public void findAll2Test() { List<ExtendedAccount> extendedAccounts = accountDao.findAll2(); for(ExtendedAccount extendedAccount: extendedAccounts) { System.out.println(extendedAccount); } } }
相關文章
- MyBatis多對多的兩種處理方式MyBatis
- gorm 關係一對一,一對多,多對多查詢GoORM
- Mybatis【15】-- Mybatis一對一多表關聯查詢MyBatis
- MyBatis表關聯 一對多 多對一 多對多MyBatis
- spring data jpa關聯查詢(一對一、一對多、多對多)Spring
- mybatis的一對多,多對一,以及多對對的配置和使用MyBatis
- Mybatis一對多、多對一處理MyBatis
- mybatis一對多&&多對一處理MyBatis
- MyBatis07-(多對一、一對多)MyBatis
- Mybatis【一對多、多對一、多對多】知識要點MyBatis
- jpa一對多查詢
- MyBatis初級實戰之六:一對多關聯查詢MyBatis
- Mybatis09_一對一、一對多、多對多、延遲載入MyBatis
- mybatis一對多查詢resultMap只返回了一條記錄MyBatis
- mybatis入門基礎(六)----高階對映(一對一,一對多,多對多)MyBatis
- MyBatis 查詢資料時屬性中多對一的問題(多條資料對應一條資料)MyBatis
- Spring data jpa 多表查詢(三:多對多關係動態條件查詢)Spring
- mybatis學習 - 多表查詢的實現MyBatis
- MyBatis 使用resultMap 以及 一對一和一對多MyBatis
- 幀動畫的多種實現方式與效能對比動畫
- Django Model各種操作 Meta 常用欄位 一對多操作 多對對操作 F Q查詢 聚合函式Django函式
- Mybatis plus 一對多關聯查詢分頁不準確的問題MyBatis
- JPA(3) 表關聯關係(多對一、一對多、多對多、一對一)
- 03 註解:多對多查詢
- mybatis中一對多對映,但兩張表id相同怎麼辦?MyBatis
- spring data jpa 多對一聯表查詢Spring
- [增刪改查] 最規範的 JPA 一對多/多對一 CRUD 示例
- MyBatis實現一對一關聯對映MyBatis
- Spring Data JPA 之 一對一,一對多,多對多 關係對映Spring
- 由一個博問學到的SQL查詢方法 (一道多對多關係查詢的面試題)SQL面試題
- MyBatis加強(1)~myBatis物件關係對映(多對一關係、一對多關係)、延遲/懶載入MyBatis物件
- MyBatis初級實戰之五:一對一關聯查詢MyBatis
- Mybatis-技術專區-如何清晰的解決出現「多對一模型」和「一對多模型」的問題MyBatis模型
- [增刪改查] 最簡單的 JPA 一對多/多對一 CRUD 設計
- SSH整合實現分頁查詢(兩種方式)
- JPA中對映關係詳細說明(一對多,多對一,一對一、多對多)、@JoinColumn、mappedBy說明APP
- 關於多執行緒的兩種實現方式執行緒
- Spring Boot 入門系列(二十八) JPA 的實體對映關係,一對一,一對多,多對多關係對映!Spring Boot