在數據庫中表具有以下幾種關係:
一對多
多對一
一對一
多對多
前期準備,我們需要在數據庫中添加賬戶表:
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`ID` int(11) NOT NULL COMMENT '編號',
`UID` int(11) default NULL COMMENT '用戶編號',
`MONEY` double default NULL COMMENT '金額',
PRIMARY KEY (`ID`),
KEY `FK_Reference_8` (`UID`),
CONSTRAINT `FK_Reference_8` FOREIGN KEY (`UID`) REFERENCES `user` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
insert into `account`(`ID`,`UID`,`MONEY`) values (1,46,1000),(2,45,1000),(3,46,2000);
分析賬戶和用戶的關係:可得一個用戶可以有一個或者多個賬戶,那麼每個賬戶都有一個用戶對應。則可以看出來 多對一是一種特殊的一對一。
一對一(多對一)查詢
查詢所有賬戶信息,並且查詢下單用戶信息。
**方式一:**通過繼承實現
- 定義賬戶實體類
package com.liang.domain;
import java.io.Serializable;
/**
* 賬戶實體類
*/
public class Account implements Serializable {
private int id;
private int uid;
private Double money;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getUid() {
return uid;
}
public void setUid(int 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 +
'}';
}
}
- 定義能夠封裝包含同時包含賬戶信息和用戶信息的類。
package com.liang.domain;
import java.io.Serializable;
import java.util.Date;
/**
* 用於存放賬戶以及賬戶持有者的信息
*/
public class AccountUser extends Account implements Serializable {
private String username;
private Date birthday;
private String sex;
private String address;
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 super.toString() + " AccountUser{" +
"username='" + username + '\'' +
", birthday=" + birthday +
", sex='" + sex + '\'' +
", address='" + address + '\'' +
'}';
}
}
- 定義持久層接口類以及查詢方法
package com.liang.dao;
import com.liang.domain.Account;
import java.util.List;
/**
* 賬戶的持久層接口
*/
public interface AccountDao {
/**
* 查詢所有賬戶信息,同時包含其用戶信息
* @return
*/
List<AccountUser> findAll();
}
- 創建映射文件,並編寫查詢配置
<?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="com.liang.dao.AccountDao">
<!--查詢所有賬戶信息,同時包含其用戶信息-->
<select id="findAll" resultType="com.liang.domain.AccountUser">
select *from account,user where account.uid=user.id;
</select>
</mapper>
- 創建測試類測試方法
/**
* 查詢所有賬戶信息,同時包含其用戶信息
*/
@Test
public void testFindAll()
{
List<AccountUser> accountUsers = accountDao.findAll();
for (AccountUser accountUser:accountUsers)
{
System.out.println(accountUser);
}
}
**方式二:**通過面向對象的has a關係,使用resultMap,映射一對一查詢結果。
- 編寫賬戶實體類,在賬戶類加入一個用戶類的對象來表示此賬戶屬於哪個用戶
- 編寫持久層接口方法
package com.liang.dao;
import com.liang.domain.Account;
import java.util.List;
/**
* 賬戶的持久層接口
*/
public interface AccountDao {
/**
* 查詢所有賬戶信息,同時包含其用戶信息
* @return
*/
List<Account> findAll();
}
- 編寫持久層接口映射文件
<?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="com.liang.dao.AccountDao">
<resultMap id="accountMap" type="com.liang.domain.Account">
<id property="id" column="id"></id>
<result column="uid" property="uid"></result>
<result column="money" property="money"></result>
<!--建立Account類中user屬性對應的數據庫表 -->
<association property="user" column="user" javaType="com.liang.domain.User">
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
<result column="address" property="address"></result>
</association>
</resultMap>
<!--查詢所有賬戶信息,同時包含其用戶信息-->
<select id="findAll" resultMap="accountMap">
select *from account,user where account.uid=user.id;
</select>
</mapper>
-
主要標籤、屬性介紹 association標籤 : 一個複雜類型的關聯,用於建立多(一)對一中對象屬性的對應關係。 javaType屬性 : 一個 Java 類的完全限定名,或一個類型別名。
- 編寫測試方法
/**
* 查詢所有賬戶信息,同時包含其用戶信息
*/
@Test
public void testFindAll()
{
List<Account> accounts = accountDao.findAll();
for (Account account:accounts)
{
System.out.println(account);
System.out.println(account.getUser());
}
}
一對多查詢
查詢所有用戶信息及用戶關聯的賬戶信息。
- 編寫用戶實體類。
上面分析過,用戶和賬戶存在一對多的關係,則需要在用戶(主表)實體類包含賬戶(從表)實體類的集合引用。
package com.liang.domain;
import java.util.Date;
import java.util.List;
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accountList;
public List<Account> getAccountList() {
return accountList;
}
public void setAccountList(List<Account> accountList) {
this.accountList = accountList;
}
public int getId() {
return id;
}
public void setId(int 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 + '\'' +
'}';
}
}
- 編寫持久層接口以及查詢方法
/**
* 查詢所有用戶,同時獲取每個用戶下的所有賬戶信息
* @return
*/
List<User> findAllUserAndAccount();
- 編寫持久層映射文件
-
主要標籤、屬性介紹 collection標籤 : 一個複雜類型的集合,用於建立一對多中集合元素屬性的對應關係。 ofType屬性 : 用於指定集合元素的數據類型。
- 編寫測試方法
/**
* 查詢所有用戶,同時獲取每個用戶下的所有賬戶信息
*/
@Test
public void testFindAllUserAndAccount()
{
List<User> users = userDao.findAllUserAndAccount();
for (User user:users)
{
System.out.println("--- --- --- --- --- ");
System.out.println(user);
System.out.println(user.getAccountList());
}
}
多對多查詢
查詢所用用戶信息並且查詢其角色信息(角色表在前面文章可查找)
1.編寫角色類,和用戶類
package com.liang.domain;
/**
* 角色類
*/
public class Role {
private int id;
private String roleName;
private String roleDesc;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleDesc() {
return roleDesc;
}
public void setRoleDesc(String roleDesc) {
this.roleDesc = roleDesc;
}
@Override
public String toString() {
return "Role{" +
"id=" + id +
", roleName='" + roleName + '\'' +
", roleDesc='" + roleDesc + '\'' +
'}';
}
}
package com.liang.domain;
import java.util.Date;
import java.util.List;
/**
* 用戶類
*/
public class User {
private int id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Role> roles;
public List<Role> getRoles() {
return roles;
}
public void setRoles(List<Role> roles) {
this.roles = roles;
}
public int getId() {
return id;
}
public void setId(int 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 + '\'' +
'}';
}
}
- 編寫持久層接口方法
/**
* 查詢所用用戶信息並且查詢其角色信息
* @return
*/
List<User> findAllUserAndRole();
- 編寫持久層接口映射文件
<resultMap id="userAndRoleMap" type="com.liang.domain.User">
<id property="id" column="id"></id>
<result column="username" property="username"></result>
<result column="address" property="address"></result>
<result column="sex" property="sex"></result>
<result column="birthday" property="birthday"></result>
<collection property="roles" ofType="com.liang.domain.Role">
<id property="id" column="rid"></id>
<result column="role_name" property="roleName"></result>
<result column="role_Desc" property="roleDesc"></result>
</collection>
</resultMap>
<select id="findAllUserAndRole" resultMap="userAndRoleMap">
select user.*, role.id as rid, role.role_name,role.role_desc from user left join
user_role on user.id = user_role.uid left join
role on user_role.rid = role.id;
</select>
4 編寫測試方法
/**
* 查詢所用用戶信息並且查詢其角色信息
*/
@Test
public void testFindAllUserAndAccount()
{
List<User> users = userDao.findAllUserAndRole();
for (User user:users)
{
System.out.println("--- --- --- --- --- ");
System.out.println(user);
System.out.println(user.getRoles());
}
}