上一节 SSM之mybatis(1/2)
目录
SqlSessionFactory(applicationContext.xml)
通过MapperScannerConfigurer进行mapper扫描
订单商品数据模型对mybatis进行分析
数据模型分析思路
- 每张表记录的数据内容
分模块戳每张表记录的内容进行熟悉。
- 每张表重要字段的设置
非空字段、外键字段。
- 数据库级别表与表之间的关系
外键关系。
- 表与表之间的业务关系
在分析与表之间的业务关系时一定要建立在某个业务意义基础上去分析。
用户表:user
记录了购买商品的用户信息
订单表:orders
记录了用户所创建的订单(购买商品的订单)
订单明细表:orderdetail
记录了订单的详细信息即购买商品的信息
商品表:items
记录了商品信息
表与表之间的业务关系:
在分析表与表之间的业务关系时需要建立在某个业务意义基础上去分析。
先分析数据级别之间有关系的表之间的业务关系。
User和orders:
User --> orders:一个用户可以创建多个订单,一对多
Orders --> user:一个订单只由一个用户创建,一对一
Orders和orderdetail:
Orders --> orderdetail:一个订单可以包括多个订单明细,因为一个订单可购买多个订单,每个商品的购买信息在orderdetail记录,一对多
Orderdetail --> orders:一个订单明细只能包括在一个订单中,一对一
Orderdetail和items:
Orderdetail --> items:以恶搞订单明细只对应一个商品信息,一对一
Items --> orderdetail:一个商品可以包括在多个订单明细,一对多
一对一查询
resultType:使用resultType实现较为简单,如果pojo中没有包括查询出来的列名,需要增加列名对应的属性,即可完成映射。
如果没有查询结果的特殊要求建议使用resultType。
resultMap:需单独定义resultMap,实现有点麻烦,如果对查询结果有特殊要求,使用resultMap可以完成将关联查询映射pojo的属性中。
resultMap可以实现延迟加载,resultType无法实现延迟加载。
一对多查询
Mybatis使用resultMap的collection对关联查询的多条记录映射到一个list集合属性中。
使用resultType实现:
将订单明细映射到orders中的orderdetails中,需要自己处理,使用双重循环遍历,去掉重复记录,将订单明细放在orderdetails中。
多对多查询
需求:将查询用户购买的商品信息明细清单,(用户名、用户地址、购买商品名称、购买商品时间、购买商品数量)
针对上边的需求就使用resultType将查询到的记录映射到一个扩展的pojo’中,很简单实现明细清单的功能。
一对多是多对多的特例,如下需求:
查询用户购买的商品信息,用户和商品的关系是多对多关系。
需求1:
查询字段:用户账号、名称、性别,商品名称、价格(最常见)
企业开发中常见明细清单列表,用户购买商品明细清单列表,
使用resultType将上边查询列映射到pojo输出。
需求2:
查询字段:用户账号、名称,购买商品数量、商品明细(鼠标移上显示明细)
使用resultMap将用户购买的商品明细列表映射到user对象中。
总结
使用resultMap是针对那些对查询结果映射有特殊要求的功能,比如特殊要求映射成list中包括多个list。
resultType和resultMap的总结
resultType:
作用:
将查询结果按照sql列名pojo属性名一致映射到pojo中。
场合:
常见一些明细记录的展示,比如用户购买商品明细,将关联查询信息全部展示在页面时,此时可以直接使用resultType将每一条记录映射到pojo中,在前端页面遍历list(list是pojo)即可。
resultMap:
使用association和collection完成一对一和一对多高级映射(对结果有特殊映射要求)。
Association:
作用:
将关联查询信息映射到一个pojo对象中。
场合:
为了方便查询关联信息可以使用association将关联订单信息映射为用户对象的pojo属性中,比如:查询订单及关联用户信息。
使用resultType无法将查询结果映射到pojo对象的pojo属性中,根据对结果集查询遍历的需要选择使用resultType还是resultMap。
Collection:
作用:
将关联查询信息映射到一个list集合中。
场合:
为了方便查询遍历关联信息可以使用collection将关联信息映射到list集合中,比如:查询用户权限范围模块及模块以下的菜单,可以使用collection将模块映射到模块list中,将菜单列表映射到模块对象的list属性中,这样做的目的也是方便对查询结果集进行遍历查询。
如果使用resultType无法将查询结果映射到list集合中。
延迟加载
地址:https://blog.csdn.net/qq_40802448/article/details/88583745
查询缓存
地址:https://blog.csdn.net/qq_40802448/article/details/88583616
Spring和mybatis整合
整合思路
需要spring通过单例方式管理SqlSessionFactory。
Spring和mybatis整合生成代理对象,使用SqlSessionFactory创建SqlSession。(Spring和mybatis整合自动完成)。
持久层的mapper都需要由spring进行管理。
整合环境
创建一个新的java工程
Jar包:
SqlSessionFactory(applicationContext.xml)
在applicationContext.xml配置SqlSessionFactory和数据源(这里使用dbcp)
SqlSessionFactory在mybatis-spring-1.2.2.jar中
dbcp数据源在commons-dbcp-1.2.2.jar中
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- 加载配置文件:数据库 -->
… …
<!-- 数据源,使用dbcp -->
… …
<!-- 配置SqlSessionFactory -->
… …
<!-- 使用原始dao接口开发时 -->
… …
<!-- 使用mapper开发时 -->
… …
</beans>
<!-- 加载配置文件:数据库 -->
<context:property-placeholder location="classpath:db.properties" />
<!-- 数据源,使用dbcp -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="maxActive" value="10" />
<property name="maxIdle" value="5" />
</bean>
<!-- 配置SqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载mybatis的配置文件 -->
<property name="configLocation" value="mybatis/SqlMapConfig.xml" />
<!-- 数据源 -->
<property name="dataSource" ref="dataSource"/>
</bean>
mapper代理开发
mapper.xml和mapper.java
mapper.xml
<mapper namespace="com.mybatis.mapper.UserMapper">
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id=#{id}
</select>
</mapper>
mapper.java
public interface UserMapper {
//根据id查询用户信息
public User findUserById(int id) throws Exception;
}
通过MapperFactoryBean创建代理对象
applicationContext.xml文件
<!-- mapper配置
MapperFactoryBean:根据mapper接口生成代理对象
-->
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<!-- mapperInterface指定mapper接口 -->
<property name="mapperInterface" value="com.mybatis.mapper.UserMapper"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
org.mybatis.spring.mapper.MapperFactoryBean在mybatis-spring-1.2.2.jar中
此方法存在问题:
需要针对每个mapper进行配置,有些麻烦。
通过MapperScannerConfigurer进行mapper扫描
<!-- mapper批量扫描,从mapper包中扫描出mapper接口,自动创建代理对象并且在spring容器中注册
遵循规范:mapper.xml和mapper,java名一致且在同一目录
SqlMapConfig.xml中的<package name="com.mybatis.mapper"/>去掉
自动扫描出来的mapper的bean的id为mapper的类名(首字母小写)
-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 指定扫描的包名
如果扫描多个包,每个包中间使用半角逗号分隔 -->
<property name="basePackage" value="com.mybatis.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
</bean>
org.mybatis.spring.mapper.MapperScannerConfigurer在mybatis-spring-1.2.2.jar中
测试方法
public class UserMapperTest {
private ApplicationContext applicationContext;
@Before
public void setUp() throws Exception {
applicationContext = new ClassPathXmlApplicationContext("classpath:spring/applicationContext.xml");
}
@Test
public void testFindUserById() throws Exception {
UserMapper userMapper = (UserMapper) applicationContext.getBean("userMapper");
User user = userMapper.findUserById(1);
System.out.println(user);
}
}
逆向工程
地址:https://blog.csdn.net/qq_40802448/article/details/88583907