MyBatis的多表操作
1、表的关系有几种?
一对多(多对一)
一对一
多对多
2、如何实现数据库中的表关系
一对多(多对一)
在数据库中,从表方添加外键。引用主表的主键。外键字段默认可以为null。
多对多
在数据库中,建立中间表,中间表包含两张表的主键作为外键,并且建立联合主键。
一对一
在数据库中,加外键约束,外键约束可以建在从表的主键字段上,这种方式是通过主键实现一对一。
另外还可以在从表中添加一列,让该列成为外键,同时添加非空和唯一约束,这种方式是通过外键实现一对一。
3、实体类中如何建立关系
一对多的实体类:
主表实体:包含从表实体的集合引用
从表实体:包含主表实体的对象引用
多对多的实体类:
各自包含对方的一个集合引用
一对一的实体类:
各自包含对方一个对象引用
4、多表操作:
增删改:
增删改和单表几乎没有区别,只是在保存和更新时需要提供外键字段
删除从表数据,直接删除
删除主表数据,两种情况:
第一种:有从表引用时,一起把从表引用的都删了
第二种:有从表引用时,不让删。
查询:
我们希望的是,查询一个实体信息时,希望能同时把关联的数据一起查询出来。
多表建立关系
一对多关系:
/wp-content/uploads/image/20181019/1539943276717445.png
多对多关系:
/wp-content/uploads/image/20181019/1539943244518048.png
一对一关系:
/wp-content/uploads/image/20181019/1539943251139764.png
实体类的建立
一对一的实体建立:
//POJO类:
public class Account {
private Integer id;
private Integer uid;
private Double money;
private User user;
……
}
// DAO层接口
public interface IAccountDao {
// 一对一查询 查询所有账户信息以及所属用户信息
// Acount类封装User类信息
List<Account> findAccountList();
}
一对一的查询配置
<select id="findAccountList"resultMap="AccountMap">
SELECT u.* , a.id aid,a.uid,a.money from user u, account awhere u.id = a.UID;
</select>
<resultMapid="AccountMap" type="account">
<idcolumn="aid" property="id"></id>
<idcolumn="uid" property="uid"></id>
<idcolumn="money" property="money"></id>
<!--association 用于一对一加载关联的对象 property代表要加载的对象
根据 public classAccount {… private User user;…}来的
JavaType代表加载对象的JAVA数据类型-->
<association property="user" javaType="User">
<idproperty="id" column="id"></id>
<idproperty="username" column="username"></id>
<idproperty="birthday" column="birthday"></id>
<idproperty="sex" column="sex"></id>
<idproperty="address" column="address"></id>
</association>
</resultMap>
一对多的实体建立:
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
private List<Account> accountList;
……
}
public interface IUserDao {
// 一对多查询 查询用户信息以及账户信息
List<User> findUserList();
}
一对多的查询配置
<select id="findUserList" resultMap="userMap">
SELECT user.* , account.id aid ,account.uid,account.MONEY from user LEFT JOIN account on user.id=account.UID
</select>
<resultMap id="userMap" type="user">
<id property="id" column="id"></id>
<result property="username" column="username"></result>
<result property="birthday" column="birthday"></result>
<result property="sex" column="sex"></result>
<result property="address" column="address"></result>
<!-- collection 部分定义了用户关联的账户信息。表示关联查询结果集
property="accList": 关联查询的结果集存储在 User 对象的上哪个属性。
ofType="account": 指定关联查询的结果集中的对象类型即 List 中的对象类型。此处可以使用别
名,也可以使用全限定名。
<id />及<result/>的意义同一对一查询。-->
<collection property=" accountList " ofType="account">
<id property="id" column="aid"></id>
<result property="uid" column="uid"></result>
<result property="money" column="money"></result>
</collection>
</resultMap>
多对多和一对多类似…
动态sql语句生成
if和where标签
<select id="findByVo" parameterType="queryvo" resultMap="UserMap">
SELECT id id_,username username_,birthday birthday_,sex sex_,address address_ from user /* where 1=1*/
<!--
<if>标签的 test 属性中写的是对象的属性名,如果是包装类的对象要使用 OGNL 表达式的写法。
另外要注意 where 1=1 的作用~!
<if test="user.id!=null and user.id!='' ">
and id = #{user.id}
</if>
<if test="user.username!=null and user.username!='' ">
and username = #{user.username}
</if>
为了简化上面 where 1=1 的条件拼装,可以采用<where>标签来简化开发。
-->
<where>
<if test="user.id!=null and user.id!='' ">
and id = #{user.id}
</if>
<if test="user.username!=null and user.username!='' ">
and username = #{user.username}
</if>
</where>
</select>
foreach标签
<!--select 字段 from user where id in (?)
标签用于遍历集合,它的属性:
collection:代表要遍历的集合元素,注意编写时不要写#{}
open:代表语句的开始部分
close:代表结束部分
item:代表遍历集合的每个元素,生成的变量名
sperator:代表分隔符 -->
<select id="findByRange" parameterType="queryvo" resultType="User">
SELECT * from user WHERE;
<if test=" ids != null and ids.size>0 ">
<foreach collection="ids" open=" id in (" close=")" item="id" separator=",">
#{id}
</foreach>
</if>
</select>