四、多对多查询
多对多怎么理解呢?
一个用户可以属于多个集体(家人,朋友,同学),当然一个集体也包含了多个用户
小配置:
<!-- 查询用户即购买的商品信息的ResultMap -->
<resultMap type="com.mybatis.entity.User" id="userAndItemsResultMap">
<!-- 用户信息 -->
<id column="user_id" property="id"/>
<result column="username" property="username"/>
<result column="sex" property="sex"/>
<result column="address" property="address"/>
<!-- 订单信息
一个用户对应多个订单,使用collection映射 -->
<collection property="ordersList" ofType="com.mybatis.entity.Orders">
<id column="id" property="id"/>
<result column="user_id" property="userid"/>
<result column="number" property="number"/>
<result column="createtime" property="createTime"/>
<result column="note" property="note"/>
<!-- 订单明细
一个订单包括 多个明细
-->
<collection property="orderdetails" ofType="com.mybatis.entity.OrderDetail">
<id column="orderdetail_id" property="id"/>
<result column="items_id" property="itemsId"/>
<result column="items_num" property="itemsNum"/>
<result column="orders_id" property="ordersId"/>
<!-- 商品信息
一个订单明细对应一个商品
-->
<association property="items" javaType="com.mybatis.entity.Items">
<id column="items_id" property="id"/>
<result column="items_name" property="itemsName"/>
<result column="items_detail" property="detail"/>
<result column="items_price" property="price"/>
</association>
</collection>
</collection>
</resultMap>
<!-- 查询用户及用户购买的商品信息,使用resulaMap-->
<select id="findUserAndItemsResultMap" resultMap="userAndItemsResultMap">
SELECT
t1.*,
t2.username,
t2.sex,
t2.address,
t3.id orderdetail_id,
t3.items_id,
t3.items_num,
t3.orders_id,
t4.itemsname items_name,
t4.detail items_detail,
t4.price items_price
FROM
orders t1,
t_user t2,
orderdetail t3,
items t4
WHERE t1.user_id = t2.id AND t3.orders_id=t1.id AND t3.items_id = t4.id
</select>
接口:
/** 查询用户及用户所购买的商品信息 */
public List<User> findUserAndItemsResultMap();
测试类:
// 查询用户及用户购买的商品的信息
@Test
public void TestFindUserAndItemsResultMap() {
SqlSession sqlSession = sqlSessionFactory.openSession();
// 创建代理对象
OrdersCustomMapper oc = sqlSession.getMapper(OrdersCustomMapper.class);
// 调用mapper的方法
List<User> list = oc.findUserAndItemsResultMap();
System.out.println(list);
sqlSession.close();
}
缓存
一级缓存:
存储的内容:key(SQLID+SQL)+value(检索的结果)
节点的flushCache=false,不起作用
只要MyBatis,一级不可卸载,天然和MyBatis集成
二级缓存:
MyBatis自身集成,二级缓存是SQLSessionFactory级别的,根据namespace保存
有三个条件:
1)在大配置中设定settings setting name=”cacheEnabled”value=”true”
2)在mapper中,书写一个空的<cache/>
3)保证被缓存的类型可以被序列化
工厂对象每创建一个会话,就会生成一个工厂
注意:用完第一个session一定close()
增删改默认会清空一级和二级缓存。但是我们可以通过设置一个属性flushCache=”false” ,来阻止该操作。示例:
//02.一级缓存
@Test
public void testOneLeveCache() {
SqlSession session = MyBatisUtil.getSession();
IStudentInfoDAO dao = session.getMapper(IStudentInfoDAO.class);
StudentInfo stu = dao.getStudentById(1);
System.out.println(stu.getStuName());
System.out.println("-----------------");
StudentInfo stu2 = dao.getStudentById(1);
System.out.println(stu2.getStuName());
session.close();
}
//03.增删改对一级缓存的影响
@Test
public void testUpdateHasSomeThingToOneLeveCache() {
SqlSession session = MyBatisUtil.getSession();
IStudentInfoDAO dao = session.getMapper(IStudentInfoDAO.class);
StudentInfo stu = dao.getStudentById(1);
System.out.println(stu.getStuName());
StudentInfo s1=new StudentInfo();
s1.setStuAge(20);
s1.setStuName("张三");
s1.setStuDate(new Date());
dao.addStudent(s1);
System.out.println("-----------------");
StudentInfo stu2 = dao.getStudentById(1);
System.out.println(stu2.getStuName());
session.close();
}
//04.二级缓存
@Test
public void testSecondLeveCache() {
SqlSession session = MyBatisUtil.getSession();
IStudentInfoDAO dao = session.getMapper(IStudentInfoDAO.class);
StudentInfo stu = dao.getStudentById(1);
System.out.println(stu.getStuName());
session.close();
SqlSession session2 = MyBatisUtil.getSession();
IStudentInfoDAO dao2 = session.getMapper(IStudentInfoDAO.class);
System.out.println("-----------------");
StudentInfo stu2 = dao.getStudentById(1);
System.out.println(stu2.getStuName());
session.close();
}