Mybatis_day3_Mybatisのマルチテーブルクエリ

Mybatisマルチテーブルクエリ

  • このケースでは、主にMybatisの複数テーブルの関係を、最も単純なユーザーおよびアカウントモデルと分析します。ユーザーはUserテーブルで、アカウントはAccountテーブルです。ユーザー(User)は複数のアカウント(Account)を持つことができます。具体的な関係は次のとおりです。

ここに画像の説明を挿入


1対1のクエリ(多対1)

  • 需要
    • すべてのアカウント情報、関連するクエリユーザー情報をクエリします。
  • 注:
    • 1つのアカウント情報は特定のユーザーのみが使用できるため、アカウント情報のクエリからの関連するクエリユーザー情報は1対1のクエリです。ユーザー情報からユーザーアカウント情報をクエリする場合、ユーザーは複数のアカウントを持つことができるため、1対多のクエリです。
方法1
  1. アカウント情報を定義するエンティティクラス
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;

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;
}
@Override
public String toString() {
return "Account [id=" + id + ", uid=" + uid + ", money=" + money + "]";
	}
}

  1. AccountUserクラスを定義する
public class AccountUser extends Account implements Serializable {
private String username;
private String address;

public String getUsername() {
	return username;
}
public void setUsername(String username) {
	this.username = username;
}
public String getAddress() {
	return address;
}
public void setAddress(String address) {
	this.address = address;
}
@Override
public String toString() {
return super.toString() + " AccountUser [username=" + username + ", 
address=" + address + "]";
	}
}

  1. SQLステートメントを書く
实现查询账户信息时,也要查询账户所对应的用户信息。
SELECT  
	account.*, 
	user.username, 
	user.address
FROM 
	account,
 	user
WHERE account.uid = user.id

  1. アカウントの永続化レイヤーのDaoインターフェースを定義する
public interface IAccountDao {
/**
* 查询所有账户,同时获取账户的所属用户名称以及它的地址信息
* @return
*/
List<AccountUser> findAll();
}

  1. AccountDao.xmlファイルでクエリ構成情報を定義する
<mapper namespace="cn.myp666.dao.IAccountDao">
<!-- 配置查询所有操作-->
<select id="findAll" resultType="accountuser">
	select a.*,u.username,u.address from account a,user u where a.uid =u.id;
</select>
</mapper>
  • 注:上記のクエリの結果にはアカウント情報とユーザー情報が含まれているため、戻り値の型returnTypeの値はAccountUserタイプに設定され、アカウント情報とユーザー情報を受け取ることができます。

  1. AccountTestテストクラスを作成する
@Test
public void testFindAll() {
//6.执行操作
	List<AccountUser> accountusers = accountDao.findAll();
	
	for(AccountUser au : accountusers) {
		System.out.println(au);
	}

  1. まとめ
  • 特別なpoクラスを出力タイプとして定義します。これは、sqlクエリ結果セットのすべてのフィールドを定義します。この方法は比較的簡単で、企業で広く使用されています。


方法2
  • resultMapを使用して、1対1のクエリ結果をマッピングするための特別なresultMapを定義します。
  • オブジェクト指向の(ある)関係から、UserクラスのオブジェクトをAccountクラスに追加して、アカウントのどのユーザーを表すかを知ることができます。
  1. Accountクラスの変更

    UserクラスオブジェクトをAccountクラスの属性としてAccountクラスに追加します。
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
//添加User对象
private User 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 getUid() {
	return uid;
}
public void setUid(Integer uid) {
	this.uid = uid;
}
public Double getMoney() {
	return money;
}
public void setMoney(Double money) {
	this.money = money;
}
@Override
public String toString() {
return "Account [id=" + id + ", uid=" + uid + ", money=" + money + "]";
	}
}

  1. AccountDaoインターフェースのメソッドを変更する

    注:2番目の方法では、戻り値がAccountタイプに変更されます。AccountクラスにはUserクラスのオブジェクトが含まれているため、アカウントに対応するユーザー情報をカプセル化できます。
public interface IAccountDao {
/**
* 查询所有账户,同时获取账户的所属用户名称以及它的地址信息
* @return
*/
List<Account> findAll();
}

  1. AccountDao.xmlファイルを再定義します
<mapper namespace="cn.myp666.dao.IAccountDao">
	<!-- 建立对应关系 -->
	<resultMap type="account" id="accountMap">
		<id column="aid" property="id"/>
		<result column="uid" property="uid"/>
		<result column="money" property="money"/>
		<!-- 它是用于指定从表方的引用实体属性的 -->
		 <!--多对一的关系, property: 指的是属性的值, javaType:指的是属性的类型 -->
		<association property="user" javaType="user">
			<id column="id" property="id"/>
			<result column="username" property="username"/>
			<result column="sex" property="sex"/>
			<result column="birthday" property="birthday"/>
			<result column="address" property="address"/>
		</association>
	</resultMap>
	
<select id="findAll" resultMap="accountMap">
	select u.*,a.id as aid,a.uid,a.money from account a,user u where a.uid =u.id;
</select>
</mapper>

  1. AccountTestクラスにテストメソッドを追加する
@Test
public void testFindAll() {
	List<Account> accounts = accountDao.findAll();
	for(Account au : accounts) {
		System.out.println(au);
		System.out.println(au.getUser());
	}
}



1対多のクエリ

  • 要件:

    • すべてのユーザー情報とユーザー関連のアカウント情報をクエリします。
  • 分析:

    • ユーザー情報と彼のアカウント情報は1対多の関係にあり、クエリ中にユーザーがアカウント情報を持っていない場合は、この時点でユーザー情報もクエリする必要があります。左側の外部接続クエリがより適切であると考えました。
  • 手順は次のとおりです。

  1. SQLステートメントを書く
SELECT
	u.*, 
	acc.id as aid,
	acc.uid,
 	acc.money
FROM
	user u
LEFT JOIN account acc ON u.id = acc.uid

  1. リスト<アカウント>に追加されたユーザークラス
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accounts;

public List<Account> getAccounts() {
	return accounts;
}
public void setAccounts(List<Account> accounts) {
	this.accounts = accounts;
}
public Integer getId() {
	return id;
}
public void setId(Integer id) {
	this.id = id;
}
public String getUsername() {
	return username;
}
public void setUsername(String username) {
	this.username = username;
}
public Date getBirthday() {
	return birthday;
}
public void setBirthday(Date birthday) {
	this.birthday = birthday;
}
public String getSex() {
	return sex;
}
public void setSex(String sex) {
	this.sex = sex;
}
public String getAddress() {
	return address;
}
public void setAddress(String address) {
	this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", birthday=" + birthday
+ ", sex=" + sex + ", address="
+ address + "]";
	}
}

  1. ユーザー永続性レイヤーのDaoインターフェースに追加されたクエリメソッド
List<User> findAll();

  1. ユーザー永続性レイヤーのDaoマッピングファイルの構成
<mapper namespace="cn.myp666.dao.IUserDao">
	<resultMap type="user" id="userMap">
		<id column="id" property="id"></id>
		<result column="username" property="username"/>
		<result column="address" property="address"/>
		<result column="sex" property="sex"/>
		<result column="birthday" property="birthday"/>
		<!-- collection 是用于建立一对多中集合属性的对应关系
ofType 用于指定集合元素的数据类型
-->
		<collection property="accounts" ofType="account">
			<id column="aid" property="id"/>
			<result column="uid" property="uid"/>
			<result column="money" property="money"/>
		</collection>
	</resultMap>
	
<!-- 配置查询所有操作 -->
<select id="findAll" resultMap="userMap">
	select u.*,a.id as aid ,a.uid,a.money from user u left outer join account 
a on u.id =a.uid
</select>
</mapper>
  • コレクション
    セクションは、ユーザーに関連付けられたアカウント情報を定義します。関連するクエリ結果セット
  • property = "accounts":
    Userオブジェクトのどのプロパティに、関連付けられたクエリの結果セットが格納されているか。
  • ofType = "account":
    関連するクエリの結果セット内のオブジェクトタイプ、つまりリスト内のオブジェクトタイプを指定します。ここでは、エイリアスまたは完全修飾名を使用できます。

  1. 試験方法
@Test
public void testFindAll() {
//6.执行操作
	List<User> users = userDao.findAll();
	for(User user : users) {
		System.out.println("-------每个用户的内容---------");
		System.out.println(user);
		System.out.println(user.getAccounts());
	}
}
元の記事94件を公開 称賛された0 2097を訪問

おすすめ

転載: blog.csdn.net/qq_16836791/article/details/104779111