一.快速查找学习地址
1.mybatis 源码地址: https://gitee.com/weixinmayun/mycode
2.mybatis 官方学习文档地址:http://www.mybatis.org/mybatis-3/
3.maven 导入相关坐标的地址:https://mvnrepository.com/
二.Mybatis环境搭建注意事项
1.自己写的xml文件没有在mybatis主配置文件注册
会报如下错误:
org.apache.ibatis.binding.BindingException: Type interface com.my.dao.UserDao is not known to the MapperRegistry.
解决办法在:核心配置文件注册mappers
例如: mybatis-config.xml主配置文件添加如下代码:(注意:以自己的工程名为主)
<!--每一个mapper.xml都需要注册--> <mappers> <mapper resource="com/my/dao/UserMapper.xml"/> </mappers> |
2.当resultMap和resultType弄混了是会报如下错误:
java.lang.IllegalArgumentException: Result Maps collection does not contain value for com.yang.domain.TArticle
3.当返回值类型错误或返回值类型起的别名没对应上,会报如下错误:
org.apache.ibatis.exceptions.PersistenceException:
### Error building SqlSession.
### The error may exist in com/yang/mapper/TCommentMap.xml
### The error occurred while processing mapper_resultMap[articleMap]
### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper
4.Maven导出资源问题
Maven工程当无法导出静态资源
解决办法:在maven工程的pom.xml 添加如下代码:
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
|
三.配置文件深入解析
1.Mybatis的核心配置 (官网示例图)
2. 属性properties
实际开发中,习惯将数据源的配置信息单独抽取成一个jdbc.properties文件,该标签可以加载额外配置的 properties:
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql:///mybatis_db jdbc.username=root jdbc.password=root |
然后在mybatis主配置xml文件mybatis-config.xml 中引入如下标红的代码:
<?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>
<!--加载properties文件--> <properties resource="jdbc.properties"></properties> <settings> <!--开启全局延迟加载功能--> <setting name="lazyLoadingEnabled" value="false"/> <!--所有方法都会延迟加载--> <setting name="lazyLoadTriggerMethods" value="toString()"/> <!-- 因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。 为true代表开启二级缓存;为false代表不开启二级缓存。 --> <setting name="cacheEnabled" value="true"/> </settings> <!--设置别名--> <typeAliases> <!--方式一:给单个实体起别名--> <!-- <typeAlias type="com.yang.domain.User" alias="user"></typeAlias>--> <!--方式二:批量起别名 别名就是类名,且不区分大小写--> <package name="com.yang.domain"/> </typeAliases> <!--environments: 运行环境--> <environments default="development"> <environment id="development"> <!--当前的事务事务管理器是JDBC--> <transactionManager type="JDBC"></transactionManager> <!--数据源信息 POOLED:使用mybatis的连接池--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--引入映射配置文件--> <mappers> <!--<mapper resource="com/yang/mapper/UserMapper.xml"></mapper>--> <!--使用该方式:接口和映射文件需要同包同名--> <!-- <mapper class="com.yang.mapper.UserMapper"></mapper>--> <!--批量加载映射--> <package name="com.yang.mapper"/> </mappers> </configuration> |
3.置Settings
官网参数连接: https://mybatis.org/mybatis-3/zh/configuration.html#settings
具体用法在mybatis主配置xml文件mybatis-config.xml 中引入如下代码:
<settings> <!--开启全局延迟加载功能--> <setting name="lazyLoadingEnabled" value="false"/> <!--所有方法都会延迟加载--> <setting name="lazyLoadTriggerMethods" value="toString()"/> <!--因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。 为true代表开启二级缓存;为false代表不开启二级缓存--> <setting name="cacheEnabled" value="true"/> </settings>
|
4. typeAliases标签
官网参数详解: https://mybatis.org/mybatis-3/zh/configuration.html#typeAliases
具体用法在mybatis主配置xml文件mybatis-config.xml中引入如下代码:
<!--设置别名--> <typeAliases> <!--方式一:给单个实体起别名--> <!-- <typeAlias type="com.yang.domain.User" alias="user"></typeAlias>--> <!--方式二:批量起别名 别名就是类名,且不区分大小写--> <package name="com.yang.domain"/> </typeAliases> |
例如:原来的类型名称配置如下
<select id="findAll" resultType="com.yang.domain.User"> select * from User </select> |
设置了typeAliases后,com.yang.domain.User定义别名为User, 使代码更简洁。
5.environments标签
数据库环境的配置,支持多环境配置
6.映射器mappers
该标签的作用是加载映射的,加载方式有如下几种:
<!--引入映射配置文件--> <mappers> 1. <!--使用该方式:接口和映射文件需要同包同名--> <mapper resource="com/yang/mapper/UserMapper.xml"></mapper> 2. 使用完全限定资源定位符(URL),例如: <mapper url="file:///var/mappers/userMapper.xml"/> 3. <!--批量加载映射--> <package name="com.yang.mapper"/> </mappers> |
(注:通俗的说就是把每接口对应的xml文件需要在mybatis主配置文件注册下,才能加载到)
7.Mybaits生命周期
声明周期和作用域是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBuilder:一旦创建了SqlSessionFactory,就不再需要它了
局部变量SqlSessionFactory:说白了就可以想象为,数据库连接池.
SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建一个实例。
因此SqlSessionFactory的最佳作用域是应用作用域(ApplocationContext)。
最简单的就是使用单例模式或静态单例模式。
SqlSession:连接到连接池的一个请求
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。用完之后需要赶紧关闭,否则资源被占用!
四.解决属性名和字段名不一致
使用resultMap,使数据库字段和实体类,对应起来。
<resultMap id="UserMap" type="User"> <!--column数据库中的字段,property实体类中的属性--> <result column="id" property="id"></result> <result column="name" property="name"></result> <result column="pwd" property="password"></result> </resultMap>
<select id="getUserList" resultMap="UserMap"> select * from USER </select> |
五.Mybaits分页用法
MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封
装,使用简单的方式即可获得分页的相关数据
开发步骤:
①导入通用PageHelper的坐标
②在mybatis核心配置文件中配置PageHelper插件
③测试分页数据获取
1. 导入通用PageHelper坐标
<!-- 分页助手--> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>3.7.5</version> </dependency> <dependency> <groupId>com.github.jsqlparser</groupId> <artifactId>jsqlparser</artifactId> <version>0.9.1</version> </dependency> |
2. 在mybatis核心配置文件中配置PageHelper插件
<!-- 分页助手的插件--> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 指定方言--> <property name="dialect" value="mysql"/> </plugin> |
3. 测试分页代码实现
@Test public void testPageHelper(){ //设置分页参数 PageHelper.startPage(1,2);// Mybaits很强大这行代码加在查询的列表上面就可以分页 List<User> select = userMapper2.select(null); for(User user : select){ System.out.println(user); } }
|
获得分页相关的其他参数
//其他分页的数据 PageInfo<User> pageInfo = new PageInfo<User>(select); System.out.println("总条数:"+pageInfo.getTotal()); System.out.println("总页数:"+pageInfo.getPages()); System.out.println("当前页:"+pageInfo.getPageNum()); System.out.println("每页显示长度:"+pageInfo.getPageSize()); System.out.println("是否第一页:"+pageInfo.isIsFirstPage()); System.out.println("是否最后一页:"+pageInfo.isIsLastPage());
|
六.联合查询
1.联合查询MyBatis多表配置方式
* 多对一(一对一)配置:使用<resultMap>+<association>做配置 * 一对多配置:使用<resultMap>+<collection>做配置 * 多对多配置:使用<resultMap>+<collection>做配置 * 多对多的配置跟一对多很相似,难度在于SQL语句的编写。 |
2.一对一联合查询代码详解
例如一个订单从属一个用户,(一对一)
SELECT * FROM orders o LEFT JOIN USER u ON o.`uid`=u.`id`; |
实体:
public class Order { private Integer id; private Date ordertime; private double money; // 表示当前订单属于哪个用户 private User user; } |
OrderMapper接口
public interface OrderMapper { public List<Order> findAllWithUser(); } |
OrderMapper.xml映射
<resultMap id="orderMap" type="com.yang.domain.Order"> <id column="id" property="id"></id> <result column="ordertime" property="ordertime"></result> <result column="money" property="money"></result> <!-- 一对一(多对一)使用association标签关联 property="user" 封装实体的属性名 javaType="user" 封装实体的属性类型 --> <association property="user" javaType="com.yang.domain.User"> <id column="uid" property="id"></id> <result column="username" property="username"></result> <result column="birthday" property="birthday"></result> <result column="sex" property="sex"></result> <result column="address" property="address"></result> </association> </resultMap> |
3.一对多联合查询
一个用户有多个订单
一对多查询语句:
SELECT *,o.id oid FROM USER u LEFT JOIN orders o ON u.`id` = o.`uid`;
|
User实体
public class User { private Integer id; private String username; private Date birthday; private String sex; private String address; // 代表当前用户具备的订单列表 private List<Order> orderList; } |
UserMapper接口
public interface UserMapper { public List<User> findAllWithOrder(); } |
UserMapper.xml映射
<resultMap id="userMap" type="com.yang.domain.User"> <id column="id" property="id"></id> <result column="username" property="username"></result> <result column="birthday" property="birthday"></result> <result column="sex" property="sex"></result> <result column="address" property="address"></result> <!-- 一对多使用collection标签关联 property="orderList" 封装到集合的属性名 ofType="order" 封装集合的泛型类型 --> <collection property="orderList" ofType="com.yang.domain.Order"> <id column="oid" property="id"></id> <result column="ordertime" property="ordertime"></result> <result column="money" property="money"></result> </collection> </resultMap> <select id="findAllWithOrder" resultMap="userMap"> SELECT *,o.id oid FROM USER u LEFT JOIN orders o ON u.`id`=o.`uid`; </select> |
4.多对对联合查询
多对多联合查询跟一对多很想似,只是sql语句变得稍微复杂。
七.嵌套查询
1.嵌套查询多表配置方式
一对一配置:使用<resultMap>+<association>做配置,通过column条件,执行select查询 一对多配置:使用<resultMap>+<collection>做配置,通过column条件,执行select查询 多对多配置:使用<resultMap>+<collection>做配置,通过column条件,执行select查询 优点:简化多表查询操作 缺点:执行多次sql语句,浪费数据库性能 |
2.一对一代码嵌套查询
一个订单从属一个用户
一对一查询语句:
-- 先查询订单 SELECT * FROM orders; -- 再根据订单uid外键,查询用户 SELECT * FROM `user` WHERE id = #{订单的uid};
|
OrderMapper接口
public interface OrderMapper { public List<Order> findAllWithUser(); } |
OrderMapper.xml映射
<!--一对一嵌套查询--> <resultMap id="orderMap" type="order"> <id column="id" property="id"></id> <result column="ordertime" property="ordertime"></result> <result column="money" property="money"></result> <!--根据订单中uid外键,查询用户表--> <association property="user" javaType="user" column="uid" select="com.yang.mapper.UserMapper.findById"></association> </resultMap> <select id="findAllWithUser" resultMap="orderMap" > SELECT * FROM orders </select> |
UserMapper接口
public interface UserMapper { public User findById(Integer id); }
|
UserMapper.xml映射
<select id="findById" parameterType="int" resultType="user"> SELECT * FROM `user` where id = #{uid} </select>
|
3.一对多代码嵌套查询
查询所有用户,与此同时查询出该用户具有的订单
一对多查询语句:
-- 先查询用户 SELECT * FROM `user`; -- 再根据用户id主键,查询订单列表 SELECT * FROM orders where uid = #{用户id} |
UserMapper接口
public interface UserMapper { public List<User> findAllWithOrder(); }
|
UserMapper.xml映射
<!--一对多嵌套查询--> <resultMap id="userMap" type="user"> <id column="id" property="id"></id> <result column="username" property="username"></result> <result column="birthday" property="birthday"></result> <result column="sex" property="sex"></result> <result column="address" property="address"></result> <!--根据用户id,查询订单表--> <collection property="orderList" column="id" ofType="order" select="com.yang.mapper.OrderMapper.findByUid"></collection> </resultMap> <select id="findAllWithOrder" resultMap="userMap"> SELECT * FROM `user` </select> |
OrderMapper接口
public interface OrderMapper { public List<Order> findByUid(Integer uid); }
|
OrderMapper.xml映射
<select id="findByUid" parameterType="int" resultType="order"> SELECT * FROM orders where uid = #{uid} </select> |
4。多对多嵌套查询
多对多嵌套查询和一对多很想,只是sql语句有很大差别
-- 先查询用户 SELECT * FROM `user`; -- 再根据用户id主键,查询角色列表 SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid` WHERE ur.`uid` = #{用户id}; |
八. MyBatis延迟加载
1.概念
延迟加载就是在需要用到数据时才进行加载,不需要用到数据时就不加载数据。延迟加载也称懒加载。
* 优点: 先从单表查询,需要时再从关联表去关联查询,大大提高数据库性能,因为查询单表要比关联查询多张表速度要快。 * 缺点: 因为只有当需要用到数据时,才会进行数据库查询,这样在大批量数据查询时,因为查询工作也要消耗时间,所以可能造成用户等待时间变长,造成用户体验下降。 * 在多表中: 一对多,多对多:通常情况下采用延迟加载 一对一(多对一):通常情况下采用立即加载
|
2.实现
局部延迟加载
在association和collection标签中都有一个fetchType属性,通过修改它的值,可以修改局部的加载策略。
<!-- 开启一对多延迟加载--> <resultMap id="userMap" type="user"> <id column="id" property="id"></id> <result column="username" property="username"></result> <result column="password" property="password"></result> <result column="birthday" property="birthday"></result> <!-- fetchType="lazy" 懒加载策略 fetchType="eager" 立即加载策略 --> <collection property="orderList" ofType="order" column="id" select="com.yang.dao.OrderMapper.findByUid" fetchType="lazy"> </collection> </resultMap> <select id="findAll" resultMap="userMap"> SELECT * FROM `user` </select> |
设置触发延迟加载的方法
大家在配置了延迟加载策略后,发现即使没有调用关联对象的任何方法,但是在你调用当前对象的equals、clone、hashCode、toString方法时也会触发关联对象的查询。
我们可以在配置文件中使用lazyLoadTriggerMethods配置项覆盖掉上面四个方法。
<settings> <!--所有方法都会延迟加载--> <setting name="lazyLoadTriggerMethods" value="toString()"/> </settings>
|
全局延迟加载
在Mybatis的核心配置文件中可以使用setting标签修改全局的加载策略。
<settings> <!--开启全局延迟加载功能--> <setting name="lazyLoadingEnabled" value="true"/> </settings> |
注意 局部的加载策略优先级高于全局的加载策略。
<!-- 关闭一对一延迟加载--> <resultMap id="orderMap" type="order"> <id column="id" property="id"></id> <result column="ordertime" property="ordertime"></result> <result column="total" property="total"></result> <!-- fetchType="lazy" 懒加载策略 fetchType="eager" 立即加载策略 --> <association property="user" column="uid" javaType="user" select="com.yang.dao.UserMapper.findById" fetchType="eager"> </association> </resultMap> <select id="findAll" resultMap="orderMap"> SELECT * from orders </select> |
九.MyBatis缓存
1.为什么使用缓存?
当用户频繁查询某些固定的数据时,第一次将这些数据从数据库中查询出来,保存在缓存中。当用户再 次查询这些数据时,不用再通过数据库查询,而是去缓存里面查询。减少网络连接和数据库查询带来的损 耗,从而提高我们的查询效率,减少高并发访问带来的系统性能问题。
一句话概括:经常查询一些不经常发生变化的数据,使用缓存来提高查询效率。
像大多数的持久化框架一样,Mybatis也提供了缓存策略,通过缓存策略来减少数据库的查询次数, 从而提高性能。 Mybatis中缓存分为一级缓存,二级缓存。
2.一级缓存
一级缓存是SqlSession级别的缓存,是默认开启的。
所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往 只执行一次SQL,因为使用SelSession第一次查询后,MyBatis会将其放在缓存中,以后再查询的时 候,如果没有声明需要刷新,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不 会再次发送SQL到数据库。
注意事项
一级缓存是SqlSession范围的缓存,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调 用clearCache()、commit()、close()方法,都会清空缓存。
3.二级缓存
二级缓存是namspace级别(跨sqlSession)的缓存,是默认不开启的。
二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO必须是可序列化的。 也就是要求实现Serializable接口,配置方法很简单,只需要在映射XML文件配置 就可以开启 二级缓存了。
配置核心配置文件:
<settings> <!-- 因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。 为true代表开启二级缓存;为false代表不开启二级缓存。 --> <setting name="cacheEnabled" value="true"/> </settings> |
配置UserMapper.xml映射
<mapper namespace="com.yang.dao.UserMapper"> <!--当前映射文件开启二级缓存--> <cache></cache> <!-- <select>标签中设置useCache=”true”代表当前这个statement要使用二级缓存。 如果不使用二级缓存可以设置为false 注意: 针对每次查询都需要最新的数据sql,要设置成useCache="false",禁用二级缓存。 --> <select id="findById" parameterType="int" resultType="user" useCache="true" > SELECT * FROM `user` where id = #{id} </select> </mapper> |
4.注意问题(脏读)
mybatis的二级缓存因为是namespace级别,所以在进行多表查询时会产生脏读问题
5.总结
1. mybatis的缓存,都不需要我们手动存储和获取数据。mybatis自动维护的。
2. mybatis开启了二级缓存后,那么查询顺序:二级缓存--》一级缓存--》数据库
3. 注意:mybatis的二级缓存会存在脏读问题,需要使用第三方的缓存技术解决问题。
十.Mybatis使用注解开发
一.介绍
这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写 Mapper映射文件了。
* @Insert:实现新增,代替了<insert></insert> * @Delete:实现删除,代替了<delete></delete> * @Update:实现更新,代替了<update></update> * @Select:实现查询,代替了<select></select> * @Result:实现结果集封装,代替了<result></result> * @Results:可以与@Result 一起使用,封装多个结果集,代替了<resultMap></resultMap> * @One:实现一对一结果集封装,代替了<association></association> * @Many:实现一对多结果集封装,代替了<collection></collection> |
二. MyBatis注解的增删改查
创建UserMapper接口
public interface UserMapper { @Select("SELECT * FROM `user`") public List<User> findAll(); @Insert("INSERT INTO `user`(username,birthday,sex,address) VALUES(# {username},#{birthday},#{sex},#{address})") public void save(User user); @Update("UPDATE `user` SET username = #{username},birthday = #{birthday},sex = #{sex},address = #{address} WHERE id = #{id}") public void update(User user); @Delete("DELETE FROM `user` where id = #{id}") public void delete(Integer id); }
|
三.编写核心配置文件
两种用法选择一个
第一种用法: <!--我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可--> <mappers> <!--扫描使用注解的Mapper类--> <mapper class="com.yang.mapper.UserMapper"></mapper> </mappers> 第二种用法: <!--或者指定扫描包含映射关系的接口所在的包也可以--> <mappers> <!--扫描使用注解的Mapper类所在的包--> <package name="com.yang.mapper"></package> </mappers> |
四. 使用注解实现复杂映射开发
4.1.我们在映射文件中通过配置来实现复杂关系映射。
使用注解开发后,我们可以使用 @Results、@Result,@One、@Many 注解组合完成复杂关系的配置。
注解 | 说明 |
@Results | 代替的是标签<resultMap>该注解种可以使用单个@Result注解,也可以使用@Result集合。 使用格式:@Results({@Result(),@Result()})或Results (@Result()) |
@Result | 代替了<id>标签和<result>标签 @Result中属性介绍: column:数据库列名 property:需要装配的属性名 one:需要使用的@One注解(@Result(one=@One)())) many:需要使用的@Many注解(@Result(many=@many)())) |
@One(一对一) | 代替了<assocation>标签,使多表查询的关键,在注解种用来指定自查询返回单一对象。 @One注解属性介绍 Select:指定用来多表查询的sqlmapper 使用格式:@Result(column="",property="",one=@One(select="")) |
@Many(一对多) | 代替了<collection>标签,使多表查询的关键,在注解种用来指定自查询返回对象集合。 |
4.2. 一对一查询
一对一查询语句
SELECT * FROM orders; SELECT * FROM `user` WHERE id = #{订单的uid}; |
OrderMapper接口
public interface OrderMapper { @Select("SELECT * FROM orders") @Results({ @Result(id = true, column = "id", property = "id"), @Result(column = "ordertime", property = "ordertime"), @Result(column = "money", property = "money"), @Result(property = "user", javaType = User.class, column = "uid", one = @One(select = "com.yang.mapper.UserMapper.findById", fetchType = FetchType.EAGER)) }) public List<Order> findAllWithUser(); }
|
UserMapper接口
public interface UserMapper { @Select("SELECT * FROM `user` WHERE id = #{id}") public User findById(Integer id); }
|
4.3. 一对多查询
一对多查询语句
SELECT * FROM `user`; SELECT * FROM orders where uid = #{用户id}; |
UserMapper接口
public interface UserMapper { @Select("SELECT * FROM `user`") @Results({ @Result(id = true, column = "id", property = "id"), @Result(column = "brithday", property = "brithday"), @Result(column = "sex", property = "sex"), @Result(column = "address", property = "address"), @Result(property = "orderList", javaType = List.class, column = "id" , many = @Many(select = "com.yang.mapper.OrderMapper.findByUid")) }) public List<User> findAllWithOrder(); } |
OrderMapper接口
public interface OrderMapper { @Select("SELECT * FROM orders WHERE uid = #{uid}") public List<Order> findByUid(Integer uid); } |
4.4.多对多查询
多对多跟一对多很相似就是sql语句有些差别
多对多查询语句::
SELECT * FROM `user`; SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid` WHERE ur.`uid` = #{用户id}; |
UserMapper接口
public interface UserMapper { @Select("SELECT * FROM `user`") @Results({ @Result(id = true, column = "id", property = "id"), @Result(column = "brithday", property = "brithday"), @Result(column = "sex", property = "sex"), @Result(column = "address", property = "address"), @Result(property = "roleList", javaType = List.class, column = "id" , many = @Many(select = "com.yang.mapper.RoleMapper.findByUid")) }) public List<User> findAllWithRole(); } |
RoleMapper接口
public interface RoleMapper { @Select("SELECT * FROM role r INNER JOIN user_role ur ON r.`id` = ur.`rid` WHERE ur.`uid` = #{uid}") public List<Role> findByUid(Integer uid); }
|
4.5. 基于注解的二级缓存
配置SqlMapConfig.xml文件开启二级缓存的支持
<settings> <!-- 因为cacheEnabled的取值默认就为true,所以这一步可以省略不配置。 为true代表开启二级缓存;为false代表不开启二级缓存。 --> <setting name="cacheEnabled" value="true"/> </settings>
|
在Mapper接口中使用注解配置二级缓存
@CacheNamespace public interface UserMapper {...}
|
注解延迟加载不管是一对一还是一对多 ,在注解配置中都有fetchType的属性
* fetchType = FetchType.LAZY 表示懒加载 * fetchType = FetchType.EAGER 表示立即加载 * fetchType = FetchType.DEFAULT 表示使用全局配置 |
4.6.xml方式和注解优劣
注解开发和xml配置优劣分析
1.注解开发和xml配置相比,从开发效率来说,注解编写更简单,效率更高。
2.从可维护性来说,注解如果要修改,必须修改源码,会导致维护成本增加。xml维护性更强。