mybatis学习
配置:
一个mybatis配置文件,用于指定数据源、事物管理和sql映射文件位置(<properties resource="xxx.properties"/>)
一些sql映射文件
一些实体类
最后一个main方法启动就可以了。
一对一查询:
嵌套结果:<association property="属性名" javaType="实体类"/>
嵌套查询:<association property="属性名" column="列名" select="某sql语句的id"/>
一对多查询:
嵌套结果:<collection property="属性名" ofType="实体类"/>
嵌套查询:<collection property="属性名" column="列名" select="某sql语句的id"/>
其它标签:
定义别名:
<typeAliases>
<typeAlias type="实体类" alias="别名"/>
<package name="实体类的包路径"/>
</typeAliases>
结果映射:<resultMap type="实体类" id="xx">
动态sql语句:
<if test='属性 != null'></if>
<choose><when,other></choose>
<foreach>
调存储过程:
代码定义一个map传过来
<select id="" paramterMap="参数映射id" statementType="CALLABLE">
call 存储过程名(?,?)
</select>
<parameterMap type="java.util.Map" id="xxx">
<parameter property="参数名(map的key)" mode="IN" jdbcType="INTEGER"/>
<parameter property="参数名(map的key)" mode="OUT" jdbcType="INTEGER"/>
</parameterMap>
缓存
一级缓存:
解释:mybatis默认开启一级缓存,作用域为session,没有更新缓存和缓存过期的概念,粒度较粗很容易失效.
由于它简单粗暴的使用hashMap作为缓存原理,所以建议不要用一个session执行过多sql和过长时间不释放,否则容易造成内存积压和脏数据的出现。
缓存命中条件:
1.statementId相同
2.最终生成的JDBC的sql语句相同
3.最终传给JDBC的参数相同
4.mybatis自带分页功能的结果范围相同(它是基于查询结果的再过滤,而非数据库的物理分页)
失效条件:
1.不同session
2.同一session中途执行了增删改且co操作,无论修改任何表任何行的数据。
2.执行session.clearCache();
二级缓存:
解释:mybatis默认不开启二级缓存,作用域namespace.所以可以对某个mapper文件配置<cache/>标签来开启二级缓存。
二级缓存可以将内存的数据写到磁盘,及从磁盘恢复到内存,存在对象的序列化,所以实体类需要实现序列化接口。
以mapper为粒度缓存,对细粒度的缓存不友好。(比如只更新了一个商品信息,它却清空了所有商品的信息)
开启方式:
1.在mybatis总配置文件加入
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2.在具体的mapper文件中加入<cache/>来开启这个mapper命名空间下的二级缓存。
<cache/>标签有eviction="FIFO"属性表示回收策略为先进先出。
size=1024属性表示缓存的最大对象数目,根据可用内存资源来设置。
readOnly=false表示命中的对象返回相同实例,因此这些对象不能被修改。为true时会通过序列化拷贝对象。
命中条件:
1.增删改的statement可以设置<insert flushCache="true"/>表示:不清空缓存。
失效条件:
1.<select useCache="false"/>表示:执行此statement时禁用二级缓存,每次都查数据库。
2.执行增删改commit命令,会刷新缓存(即清空缓存)
Ehcache二级缓存:
解释:只要实现mybatis的cache接口,就可以接入并代替mybatis的二级缓存。
步骤:1.依赖ehcache.jar、mybatis-ehcache.jar
2.开启mybatis二级缓存
3.配置ehcache的xml配置文件,可以指定硬盘存储的位置、刷新时间等。
4.在具体的mapper.xml文件中,用cache标签的type属性指定要使用的二级缓存实现类(即ehcache提供的实现cache接口的实现类)
<cache type="org.mybatis.cache.ehcache.EhcacheCache>
<!--这里可以覆盖ehcache配置文件中的配置,以实现对每个mapper的个性化配置-->
<property name="timeToIdLeSeconds" value="12000"/>
</cache>
懒加载(延迟加载):
配置下面内容,且要用嵌套sql查询
<settings>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
一对一嵌套查询:<association property="属性名" column="列名" select="某sql语句的id"/>
一对多嵌套查询:<collection property="属性名" column="列名" select="某sql语句的id"/>
mybatis和spring整合:(每次执行mapper一级缓存会立即失效,所以此时基本没有一级缓存。)
1.数据源由org.springframwork.jdbc.datasource.DriverManagerDataSource配置
2.sqlSession由org.mybatis.spring.SqlSessionFactoryBean配置,引用上面的数据源,还要可以指定别名的实体类包路径。
3.扫描映射文件由org.maybatis.spring.mapper.MapperScannerConfigurer配置,引用上面的sqlSession.
4.事物管理器由org.springframework.jdbc.datasource.DataSourceTransactionManager配置,引用上面的数据源。
5.声明式事物由<tx:annotation-driven transaction-manager="上面的事物管理器"/>标签配置。
6.mybatis的配置文件可以是空的。
使用方式:
1.dao方式:自己的daoImpl可以继承SqlSeesionDaoSupport也可以不继承,它里面提供了基本的方法。再往daoImpl中注入sqlSeesionFactory。
1.mapper方式:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="xx.xx.UserMapper"/>
<property name="sqlSessionFactory" value="sqlSession工厂bean的id"/>
</bean>
或
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="Mapper接口的包路径"/>
<property name="sqlSessionFactoryBeanName" value="sqlSession工厂bean的id"/>
</bean>