Mybatis第二篇【Mybatis的映射配置文件】
映射配置文件
缓存
-
当为select语句时:flushCache默认为false,表示任何时候语句被调用,都不会去清空本地缓存和二级缓存。useCache默认为true,表示会将本条语句的结果进行二级缓存。
-
当为insert、update、delete语句时: flushCache默认为true,表示任何时候语句被调用,都会导致本地缓存和二级缓存被清空。useCache属性在该种情况下没有。update的时候如果 flushCache="false",则当你更新后,查询的数据数据还是老的数据。
一级缓存
一级缓存的原理?
答:先去缓存区里查找,如果没有找到,则去数据库查找
在mybatis中,一级缓存默认是开启的,并且无法关闭
一级缓存满足条件:
1、同一个sqlSession
2、相同的SQL和参数
强制清除缓存:
sqlSession.clearCache();
执行update、insert、delete的时候,会清空缓存
二级缓存
mybatis的二级缓存的作用域是一个mapper的namespace ,同一个namespace中查询sql可以从缓存中查找。
开启二级缓存,实体类必须序列化

<mapper namespace="com.example.demo.UserMapper">
<cache/>
</mapper>
二级缓存全局开关
<setting name="cacheEnabled" value="false"/> 默认值是true,(value="false"关闭全局二级缓存,二级缓存失效)
返回自增主键
方式一:
<insert id="insert" parameterType="User">
<selectKey keyProperty="id" order="AFTER" resultType="Integer">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,password,age,sex) values (#{username},#{password},#{age},#{sex})
</insert>
User user=new User("123456", "abcd", 18, "女");
int insert = mapper.insert(user);
sqlSession.commit();
System.out.println(user.getId());
方式二:
<!-- useGeneratedKeys: 是否开启返回自增主键
keyProperty: java实体类中主键属性
keyColumn: 数据库表中主键字段 -->
<insert id="insert" parameterType="User" useGeneratedKeys="true" keyProperty="id" keyColumn="id">
insert into user (username,password,age,sex) values (#{username},#{password},#{age},#{sex})
</insert>
User user=new User("123456", "abcd", 20, "男");
int insert = mapper.insert(user);
sqlSession.commit();
System.out.println(user.getId());
返回主键
<insert id="insert" parameterType="User">
<selectKey keyProperty="id" order="BEFORE" resultType="String">
select uuid()
</selectKey>
insert into user (id,username,password,age,sex) values (#{id},#{username},#{password},#{age},#{sex})
</insert>
User user=new User("abc", "123456", 18, "女");
int insert = mapper.insert(user);
sqlSession.commit();
System.out.println(user.getId());
延迟加载
延迟加载:在真正使用数据的时候才发起查询,不用的时候不查询关联的数据,延迟加载又叫按需查询(懒加载)
立即加载:不管用不用,只要一调用方法,马上发起查询。
| lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 | true | false | false |
| aggressiveLazyLoading | 当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载(参考lazyLoadTriggerMethods)。 | true | false | false (在 3.4.1 及之前的版本默认值为 true) |
mybatis-config.xml配置延迟加载
<settings>
<!--开启全局的懒加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--关闭立即加载,即按需加载,其实不用配置,默认为false-->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
案例:懒加载+Collection标签
<?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="com.example.demo.mapper.UserMapper">
<resultMap id="UserMap" type="User" >
<id column="id" property="id" jdbcType="INTEGER" />
<result column="username" property="username" jdbcType="VARCHAR" />
<result column="age" property="age" jdbcType="INTEGER" />
<result column="sex" property="sex" jdbcType="VARCHAR" />
<collection property="userAccount" javaType="ArrayList" ofType="com.example.demo.mapper.UserAccount"
select="com.example.demo.mapper.UserAccountMapper.selectList" column="{uid=id,uage=age}" /> <!-- 只有传递一个参数时,column="id" -->
<!-- uid/uage是定义的变量名,(类似于@Param注解,为了传递参数), id/age是主表的字段id/age,
先查出主表的结果, 然后主表记录数是几 就执行几次 collection 的select,
javaType和ofType:写不写都行,javaType是用来指定pojo中属性的类型,而ofType指定的是映射到list集合属性中pojo的类型。,
select的值: 对应xml的namespace + 对应xml中的代码片段的id,
column作为select语句的参数传入,如果只传一个参数id可以简写: column="id" -->
</resultMap>
<!-- 查询列表 -->
<select id="selectList" resultMap="UserMap">
SELECT
id, username,age,sex
FROM
user
<where>
</where>
</select>
</mapper>
<?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="com.example.demo.mapper.UserAccountMapper">
<resultMap id="UserAccountMap" type="com.example.demo.mapper.UserAccount">
<result property="consumption" column="consumption"></result>
<result property="consumptionTime" column="consumption_time"></result>
</resultMap>
<!-- 查询列表 -->
<select id="selectList" resultMap="UserAccountMap">
SELECT
consumption,consumption_time
FROM
user_account
<where>
uid = #{uid} <!-- 变量名 uid 对应上文的 uid -->
<!-- 如果上文中 collection只传一个参数column="id",只要类型匹配,在这里随便写个变量名就可以取到值 例如#{xyz} -->
</where>
</select>
</mapper>
测试:
UserMapper mapper = MybatisUtil.getMapper(UserMapper.class);
List<User> questions = mapper.selectList();
//注释for循环,即没用到数据,控制台不会打印数据;关闭for循序注释则用到数据,控制台打印查询到的数据
for (User question : questions) {
System.out.println(question);
}

浙公网安备 33010602011771号