多表设计
- 一对一 :用户 购物车
- 一对多 :用户 订单
- 多对多 :用户 商品
MyBatis的一对一关系查询
直接在mysql里边操作
新建一张表Student;
再建一张表Cellphone
建立关联关系
写sql语句
在idea里边怎么做呢?
新建一个class叫User,里边列出Student里所有的分类,
再建一个class叫Cellphone,里边列出Cellphone里所有的分类,
在User里边放置一个Cellphone对象
这样就完成了两个表的关联操作
public class User {
int id ;
String name;
int chinese;
int english;
int math;
Cellphone cellphone;
...
}
public class Cellphone {
int cid ;
String cname ;
String cnumber;
...
}
问题是如何在Mybatis的前提下进行查询呢?
- 第一种方法
新建一个UserExt,让他继承User,同时在UserExt中装入Cellphone中的分类;所以UserExt中的每一个成员都与查询的结果对应。
public class UserExt extends User{
int cid ;
String cname ;
String cnumber;
...
}
<select id="queryUserAndCellphone" resultType="com.bamzhy.bean.UserExt">
SELECT * FROM student LEFT OUTER JOIN cellphone ON student.id = cellphone.sid
</select>
记得要用ArrayList< UserExt>这样的数组装,因为返回回来的是多个结果
@Test
public void test11(){
ArrayList<UserExt> userExt = dao.queryUserAndCellphone();
System.out.println("userext= "+userExt);
}
第二种方法
同时,可以使用ResultMap,把结果映射到一个Map里边,并且新建一个POJO保存Map里边的参数。第三种方法
直接利用User里边的Cellphone引用(比较复杂的方法)
<resultMap id="usersandCellphone" type="user">
<id column="id" property="id"></id>
<result property="name" column="name"/>
<result property="chinese" column="chinese"/>
<result property="english" column="english"/>
<result property="math" column="math"/>
<!--Map里边的名为property的javaType类型引用使用select方法以column作为参数查找-->
<association property="cellphone"
javaType="com.bamzhy.bean.Cellphone"
select="com.bamzhy.dao.UserDao.queryCellphoneBySid"
column="id">
<id column="cid" property="cid"></id>
<result property="cname" column="cname"/>
<result property="cnumber" column="cnumber"/>
</association>
</resultMap>
<select id="queryUserAndCellphone2" resultMap="usersandCellphone" >
select * from student
</select>
<select id="queryCellphoneBySid" parameterType="int" resultType="com.bamzhy.bean.Cellphone">
select * from cellphone where sid = #{id}
</select>
流程:
先去查select * from student,查出来的结果封装到usersandCellphone,usersandCellphone按照内容进行封装,发现了一个引用(关联)对象,再调用引用对象的查询方法(queryCellphoneBySid)再次做一个查询,然后最后把Map映射到user并返回。结果:
User{id=1, name=’haha1’, chinese=90, english=89, math=82, cellphone=Cellphone{ cid=1, cname=’iPhone’, cnumber=’123456’}},等当封装对象的列名(属性)跟该对应POJO的字段名保持一致的时候,可以把这些属性都去了
<association property="cellphone"
javaType="com.bamzhy.bean.Cellphone"
select="com.bamzhy.dao.UserDao.queryCellphoneBySid"
column="id">
<id column="cid" property="cid"></id>
</association>
MyBatis的一对多关系查询
也没有很复杂,就是一个结果里边包含另一个表的很多记录(关联主键的)
<resultMap id="userAndCellphones" type="user">
<id column="id" property="id"></id>
<result property="name" column="name"/>
<result property="chinese" column="chinese"/>
<result property="english" column="english"/>
<result property="math" column="math"/>
<collection property="cellphones"
javaType="list"
select="com.bamzhy.dao.UserDao.queryCellphoneBySid"
column="id">
<id column="cid" property="cid"></id>
</collection>
</resultMap>
<select id="queryUserById" parameterType="int" resultMap="userAndCellphones" >
select * from student WHERE id = #{id}
</select>
<select id="queryCellphoneBySid" parameterType="int" resultType="com.bamzhy.bean.Cellphone">
select * from cellphone where sid = #{id}
</select>
MyBatis的多对多关系查询
student类
course类
t_sc表
<resultMap id="studentAndCourses" type="com.bamzhy.bean.Student">
<id column="id" property="id"></id>
<collection property="courses"
javaType="list"
select="com.bamzhy.dao.UserDao.findcourseBySid"
column="id">
<id column="cid" property="cid"></id>
</collection>
</resultMap>
<select id="findStudentByID" parameterType="int" resultMap="studentAndCourses" >
select * from student WHERE id = #{id}
</select>
<select id="findcourseBySid" parameterType="int" resultType="com.bamzhy.bean.Course">
select * from t_sc INNER JOIN course on t_sc.cid = course.cid and sid = #{sid}
</select>
</mapper>
- sql语句解析:SELECT * FROM t_sc INNER JOIN course ON t_sc.cid = course.cid AND sid = #{id}
在t_sc表中找出cid=course表中cid的选项,并把course中满足条件的选项全部列出来,最后把这些选项中sid=输入的id的选项保留下来,给到course。
最后把这些course封装成student类,给到前台。
全文最重要的地方来了
- 一对一
一个POJO里边包含别的类对象的引用;
Student student; - 一对多
一个POJO里边包含别的类对象List的引用
ArrayList< Student> student; - 多对多
两个POJO中分别含有对方对象List的引用(要记得toString方法改写,不然就循环调用导致溢出)
ArrayList< Student> studentList;
ArrayList< Course> courseList;