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);
    }
posted @ 2020-04-13 14:48  幻竹  阅读(265)  评论(0)    收藏  举报