高级映射
一、数据模型分析思路
1.每张表记录的数据内容
分模块对每张表记录的内容进行熟悉,相当于学习系统需求(功能)的过程
2.每张表重要字段的设置
非空字段、外键字段
3.数据库级别表与表之间的关系
外键关系
4.表与表之间的业务关系
在分析表与表之间的业务关系时,一定要建立在某个业务意义的基础之上进行
学习mysql详细之后再看。
二.延迟加载
1.什么是延迟加载
resultMap可以实现高级查询(使用association、collection实现一对一及一对多的映射),association、collection具备延迟加载的功能。
需求:
如果查询订单并且关联查询用户信息。如果先查询订单信息即个满足需求,当我们需要查询用户信息时再查询用户信息。把对用户信息的按需查询成为延迟加载。
延迟加载:先从单表查询、需要时再从关联表去进行关联查询,大大提高数据库性能。因为查询一个单表要比关联查询多张表速度要快。
学习mysql详细之后再看。
三、缓存
Mybatis提供查询缓存,用于减轻数据库压力,当缓存中有数据的时候,可以从缓存数据中获取,提高数据性能。
Mybatis提供一级缓存和耳机缓存。
一级缓存是sqlSession级别的缓存,在操作数据库是需要构造sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互不影响的。当sqlSession发起查询的时候会先查询缓存中是否存有所查数据,如果有,则直接获取。如果没有,则从数据库中获取信息,并将得到的信息存储到一级缓存中。
如果sqlSession去执行commit操作的时候(插入、更新、删除),清空sqlSession中的一级缓存。这样做的目的是保证缓存中的数据是最新的数据,避免数据的脏读。
Mybatis中默认开启一级缓存,不需要在配置文件中配置。
二级缓存是Mapper级别的缓存,多个Sqlsession操作同一个同一个sql语句,多个sqlSession可以共用二级缓存,二级缓存是跨Sqlsession的。
首先,二级缓存需要开启。
在SqlMapConfig.xml中开启二级缓存。
<!--开启二级缓存--> <settings> <setting name="cacheEnabled" value="true"/> </settings>
在mapper.xml中的某个Mapper下开始二级缓存。
<mapper namespace="Mapper.CategoryMapper"> <!--开启本mapper的二级缓存--> <cache/>
SqlSession1去查询用户id为1的用户信息,查询到的用户信息会将查询数据储存到二级缓存当中。
SqlSession2区查询用户id为1的用户信息时,会先到二级缓存中取找,如果存在则直接取出数据。
如果SqlSession3对相同mapper(namespace相同)下的sql执行了commit操作,则该Mapper的二级缓存数据清空。
二级缓存与一级缓存之间的区别,二级缓存范围更大,多个SqlSession可以共享一个Mapper的二级缓存。每个不同的Mapper之间拥有不同的二级缓存区域(按namespace划分)。如果两个mapper的namespace相同,则共享一个二级缓存区域。
statement中可以设置二级缓存禁用,在statement标签中添加useCache=false,即每次操作都会发出sql操作数据库。默认情况下是true,
<select id="findCategoryById" parameterType="Pojo.Category" resultType="Pojo.Category" useCache="false">
statement中可以设置二级缓存刷新,在statement标签中添加useCache=true,但是一般不用,默认是true。
<select id="findCategoryById" parameterType="Pojo.Category" resultType="Pojo.Category" useCache="false" flushCache="true">
四.Spring和Mybatis的整合
1.配置SqlMapConfig.xml
(1)建立Mapper接口
public interface CategoryMapper { public Category findCategoryById(int id) throws Exception; }
(2)创建Mapper.xml映射文件
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="Mapper.CategoryMapper"> <select id="findCategoryById" parameterType="int" resultType="Category"> SELECT * FROM category_ WHERE id=#{id} </select> </mapper>
(3)配置sqlMapConfig由于数据源整合之后由Spring进行管理,这里不需配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!--定义别名,在写Statement的时候就可以直接输入类名--> <typeAliases> <package name="Pojo"></package> </typeAliases> <!--加载sql语句的配置文件--> <mappers> <!--使用class按包加载--> <mapper resource="Config/sqlmap/User.xml"/> </mappers> </configuration>
(4)配置ApplicationContext.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" 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/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"> <!--加载数据库配置参数--> <context:property-placeholder location="jdbc.properties"/> <!--配置数据源--> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close"> <!-- 基本属性 url、user、password --> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 配置初始化大小、最小、最大 --> <property name="initialSize" value="1" /> <property name="minIdle" value="1" /> <property name="maxActive" value="20" /> <!-- 配置获取连接等待超时的时间 --> <property name="maxWait" value="60000" /> <!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 --> <property name="timeBetweenEvictionRunsMillis" value="60000" /> <!-- 配置一个连接在池中最小生存的时间,单位是毫秒 --> <property name="minEvictableIdleTimeMillis" value="300000" /> <property name="validationQuery" value="SELECT 1" /> <property name="testWhileIdle" value="true" /> <property name="testOnBorrow" value="false" /> <property name="testOnReturn" value="false" /> <!-- 打开PSCache,并且指定每个连接上PSCache的大小 --> <property name="poolPreparedStatements" value="true" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> </bean> <!--Spring容器创建sqlSessionFactory--> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!--加载Myabatis全局配置文件--> <property name="configLocation" value="SqlMapConfig.xml"/> <!--加载数据源--> <property name="dataSource" ref="dataSource"/> </bean> <!--Mapper的配置 MapperFactoryBean根据Mapper接口生成代理对象--> <bean id="CategoryMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!--指定Mapper接口路径--> <property name="MapperInterface" value="Mapper.CategoryMapper"/> <property name="sqlSessionFactory" ref="sqlSessionFactory"/> </bean> </beans>
(5)写测试
public class TestMybatisSping { private ApplicationContext applicationContext; /*得到Spring容器*/ @Before public void setUp() throws Exception{ applicationContext = new ClassPathXmlApplicationContext("ApplicationContext.xml"); } @Test public void testFindCategoryById() throws Exception{ CategoryMapper categoryMapper = (CategoryMapper) applicationContext.getBean("CategoryMapper"); Category category = categoryMapper.findCategoryById(2); System.out.println(category); } }
(6)结果