mybatis的多表操作
- 表之间的关系有几种:一对多,多对一,一对一,多对多
- 示例:用户和订单就是一对多,订单和用户就是多对一
- 一个用户可以下多个订单
- 多个订单属于同一个用户
- 示例:人和身份证号就是一对一
- 一个人只能有一个身份证号
- 一个身份证号只能属于一个人
- 示例:老师和学生之间就是多对多
- 一个学生可以被多个老师教过
- 一个老师可以教多个学生
- 示例(特例):如果拿出每一个订单,都只能属于一个用户,所以mybatis中就把多对一看成了一对一
mybatis中的多表查询
- 示例:用户和账户
- 一个用户可以有多个账户
- 一个账户只属于一个用户
- 步骤:(一对多和多对一)
- 建立两张表:
- 用户表
- 账户表
- 建立两个实体类:
- 用户实体类
-
账户实体类
3, 让用户表和账户表之间具备一对多的关系:需要外键在账户表中添加
- 让用户和账户的实体类能体现出一对多的关系
- 建立两个配置文件:
- 用户的配置文件
- 账户的配置文件
- 实现配置:
- 当查询用户时,可以同时得到用户下所包含的账户信息
- 当查询账户时, 可以同时得到账户下所属用户的信息
- 建立两张表:
一对一案例说明
- 第一种方式:子类继承(从表继承主表)(不好)
- 实体类(User,Account,UserAccount)
public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; } public class Account implements Serializable { private Integer id; private Integer uid; private Double money; } public class AccountUser extends Account { private String username; private String address; }
- 接口类
//查询所有账户,并且带有用户名称和地址信息---接口方法 List<AccountUser> findAllAccount();
- 配置文件xml
<!--查询所有账户同时包含用户名和地址信息--> <select id="findAllAccount" resultType="accountuser"> select a.*,u.username,u.address from account a , user u where u.id = a.uid; </select>
- 实体类(User,Account,UserAccount)
- 第二种方式:配置xml文件里使用resultMap配置返回类型(好)
- 实体类(User,Account,UserAccount)
public class Account implements Serializable { private Integer id; private Integer uid; private Double money; //从表实体应该包含一个主表实体的对象引用 private User user; } public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; }
- 接口类
public interface IAccountDao { /** * 查询所有账户,同时还要获取到当前账户的所属用户信息 */ List<Account> findAll(); /** * 查询所有账户,并且带有用户名称和地址信息 * @return */ List<AccountUser> findAllAccount(); }
- 配置文件xml
<!-- 定义封装account和user的resultMap --> <resultMap id="accountUserMap" type="account"> <id property="id" column="aid"></id> <result property="uid" column="uid"></result> <result property="money" column="money"></result> <!-- 一对一的关系映射:配置封装user的内容--> <association property="user" column="uid" javaType="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> </association> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="accountUserMap"> select u.*,a.id as aid,a.uid,a.money from account a , user u where u.id = a.uid; </select> <!--查询所有账户同时包含用户名和地址信息--> <select id="findAllAccount" resultType="accountuser"> select a.*,u.username,u.address from account a , user u where u.id = a.uid; </select>
- 实体类(User,Account,UserAccount)
一对多案例说明
- 实体类(User,Account,UserAccount)
public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; //一对多关系映射:主表实体应该包含从表实体的集合引用 private List<Account> accounts; } public class Account implements Serializable { private Integer id; private Integer uid; private Double money; }
- 接口类
/** * 查询所有用户,同时获取到用户下所有账户的信息 * @return */ List<User> findAll();
- 配置文件xml
<!-- 定义User的resultMap--> <resultMap id="userAccountMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!-- 配置user对象中accounts集合的映射 --> <collection property="accounts" ofType="account"> <id column="aid" property="id"></id> <result column="uid" property="uid"></result> <result column="money" property="money"></result> </collection> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="userAccountMap"> select * from user u left outer join account a on u.id = a.uid </select> <!-- 根据id查询用户 --> <select id="findById" parameterType="INT" resultType="user"> select * from user where id = #{uid} </select>
一对多案例说明
- 示例:用户和角色
- 一个用户可以有多个角色
- 一个角色可以赋予多个用户
- 步骤:(多对多)
- 建立两张表:
- 用户表
- 角色表
- 建立两个实体类:
- 用户实体类
-
角色实体类
3, 让用户表和角色表之间具备多对多的关系:需要使用中间表,中间表中包含各自的主键,在中间表中是外键
- 让用户和角色的实体类能体现出多对多的关系:各自包含对方的一个集合引用
- 建立两个配置文件:
- 用户的配置文件
- 角色的配置文件
- 实现配置:
- 当查询用户时,可以同时得到下所包含的角色信息
- 当查询角色时, 可以同时得到角色下所属用户的信息
- 建立两张表:
- 实现代码一:多角色对多用户
- 实体类
public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; //多对多的关系映射:一个角色可以赋予多个用户 private List<User> users; } public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; }
- 接口
public interface IRoleDao { /** * 查询所有角色 * @return */ List<Role> findAll(); }
- 配置文件xml
<mapper namespace="com.itheima.dao.IRoleDao"> <!--定义role表的ResultMap--> <resultMap id="roleMap" type="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> <collection property="users" ofType="user"> <id column="id" property="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> </resultMap> <!--查询所有--> <select id="findAll" resultMap="roleMap"> select u.*,r.id as rid,r.role_name,r.role_desc from role r left outer join user_role ur on r.id = ur.rid left outer join user u on u.id = ur.uid </select> </mapper>
- 实体类
- 实现代码二:多用户对多角色
- 实体类
public class Role implements Serializable { private Integer roleId; private String roleName; private String roleDesc; } public class User implements Serializable { private Integer id; private String username; private String address; private String sex; private Date birthday; //多对多的关系映射:一个用户可以具备多个角色 private List<Role> roles; }
- 接口
public interface IUserDao { /** * 查询所有用户,同时获取到用户下所有账户的信息 * @return */ List<User> findAll(); }
- 配置文件xml
<mapper namespace="com.itheima.dao.IUserDao"> <!-- 定义User的resultMap--> <resultMap id="userMap" type="user"> <id property="id" column="id"></id> <result property="username" column="username"></result> <result property="address" column="address"></result> <result property="sex" column="sex"></result> <result property="birthday" column="birthday"></result> <!-- 配置角色集合的映射 --> <collection property="roles" ofType="role"> <id property="roleId" column="rid"></id> <result property="roleName" column="role_name"></result> <result property="roleDesc" column="role_desc"></result> </collection> </resultMap> <!-- 查询所有 --> <select id="findAll" resultMap="userMap"> select u.*,r.id as rid,r.role_name,r.role_desc from user u left outer join user_role ur on u.id = ur.uid left outer join role r on r.id = ur.rid </select> <!-- 根据id查询用户 --> <select id="findById" parameterType="INT" resultType="user"> select * from user where id = #{uid} </select> </mapper>
- 实体类