在数据库中表具有以下几种关系:
一对多
多对一
一对一
多对多
前期准备,我们需要在数据库中添加账户表:
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());
}
}