SQL语句:用户订单查询
SELECT
orders.*,
USER.username,
USER.sex,
USER.address
FROM
orders,
USER
WHERE orders.user_id = user.id
1. 定义pojo对象
由于原始的Orders.java不能映射全部字段,所以需要新创建的pojo。如下:
2. 在mapper.xml相应的sql语句配置中,输出类型为上边定义的pojo对象。其他照旧。
1. 思路:
1) 使用resultMap将查询结果中的订单信息映射到Orders对象中。
2) 在orders类中添加User属性,将关联查询出来的用户信息映射到orders对象中的user属性中。
2. 方法:
1) 在主表对应类中添加关联表对应的对象
2) 在mapper.xml中定义resultMap
3) Sql语句的配置
Sql语句:用户订单及订单明细
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.idorderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id
FROM
orders,
USER,
orderdetail
WHERE orders.user_id = user.id ANDorderdetail.orders_id=orders.id
1. 主表对应实体类中添加属性:在orders.java类中添加List
2. 定义resultMap
sql语句:由于用户和商品没有直接关联,通过订单和订单明细进行关联,所以关联表:
orders、orderdetail、items
SELECT
orders.*,
USER.username,
USER.sex,
USER.address,
orderdetail.id orderdetail_id,
orderdetail.items_id,
orderdetail.items_num,
orderdetail.orders_id,
items.name items_name,
items.detail items_detail,
items.price items_price
FROM
orders,
USER,
orderdetail,
items
WHERE orders.user_id = user.id ANDorderdetail.orders_id=orders.id AND orderdetail.items_id = items.id
1. 思路:将用户信息映射到user中。
1) 在user类中添加订单列表属性List
2) 在Orders中添加订单明细列表属性List
3) 在OrderDetail中添加Items属性,将订单明细所对应的商品映射到Items
2. 定义resultMap
|
resultType |
resultMap(常用) |
|
association |
collection |
||
作用 |
将查询结果按照sql列名与pojo中属性名,以一致性关系进行映射 |
将关联查询信息映射到一个pojo对象中 |
将关联查询信息映射到一个list集合中 |
场合 |
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list中是pojo)即可 |
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
|
为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中 |
延迟加载 |
不可 |
可以 |
1. 延迟加载:先从单表查询、需要时再从关联表去关联查询,大大提高 数据库性能,因为查询单表要比关联查询多张表速度要快。
1. Sql语句:
Select order.*,
(select username from user where orders.user_id = user.id)username
(select sex from user whereorders.user_id = user.id)sex
from orders
2. 目的:
1) 首先加载orders表中的满足orders.user_id = user.id条件的user_id。
2) 然后在需要时加载User表中orders.user_id = user.id项中的username和sex。
3. 方法:
1) 在SqlMapConfig.xml开启延迟加载
2) 将上面的sql语句拆分成两个statement,即:
SELECT * FROMorders
3) 关联查询用户信息,通过上边查询到的订单信息中user_id去关联查询用户信息。
4) 将这两个statement通过resultMap关联起来:上边先去执行findOrdersUserLazyLoading,当需要去查询用户的时候再去执行findUserById。配置延迟加载的resultMap。
5) 小结:关系图如下
1. 一级缓存是SqlSession级别的缓存。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的,默认自动开启。
2. 二级缓存是mapper的命名空间级别的缓存,一个命名空间对应一个二级缓存。多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的
1. 第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。得到用户信息,将用户信息存储到一级缓存中。
2. 第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。
3. 如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。
1. 在Mybatis的全局配置文件中(SqlMapconfig.xml文件)开启开启二级缓存。
2. 在mapper.xml映射文件中开启二级缓存
3. 对需要缓存的pojo实体类对象实现序列化,这是因为二级缓存数据存储介质多种多样,为了将缓存数据取出执行反序列化操作。
1. useCache配置:在statement中设置useCache=false可以禁用当前select语句的二级缓存。针对每次查询都需要最新的数据sql,要设置成useCache=false,禁用二级缓存。
2. 刷新缓存(清空缓存):设置statement配置中的flushCache="true" 属性,默认情况下为true即刷新缓存。一般下执行完commit操作都需要刷新缓存,flushCache=true表示刷新缓存,这样可以避免数据库脏读。(一般无需特别设置)
1. 优点:缓存的数据在各各服务单独存储,不方便系统开发,使用分布式缓存对缓存数据进行集中管理。
mybatis无法实现分布式缓存,需要和其它分布式缓存框架进行整合。
1. 实质:mybatis提供了一个cache接口,如果要实现自己的缓存逻辑,实现cache接口开发即可。
mybatis和ehcache整合,mybatis和ehcache整合包中提供了一个cache接口的实现类。
2. 与ehcache整合步骤
1) 导入ehcache包
2) 加入ehcache的配置文件:在classpath下配置ehcache.xml
3) 配置mapper中cache中的type为ehcache对cache接口的实现类型
1. 需要spring通过单例方式管理SqlSessionFactory。
2. spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSession。(spring和mybatis整合自动完成)。
3. 持久层的mapper都需要由spring进行管理。
1. 创建整合环境
2. 在spring中配置SQLSessionFactory:(applicationConfig.xml)
3. spring管理mapper的代理对象,即将mapper的代理对象注入的spring容器中
1) 遵循规范:将mapper.java和mapper.xml映射文件名称保持一致,且在一个目录中。
2) 自动扫描出来的bean 的id为mapper类名,首字母小写。
3) Mybatis扫描包与Spring扫描包的关系