Day2 Mybatis初识(二)详解编程语言

mapper接口开发

传统dao的开发问题(ibatis)

方法调用:字符串易错,硬编码

mapper代理开发

a) 编写全局配置

b) 编写接口(自动根据接口和映射文件创建实现类)

c) 编写映射文件

  规范:

  A. 映射文件和mapper接口同包同名(批量加载映射文件)

  B. 接口的全限定名称必须和mapper映射文件的namespace保持一致

  C. 接口中方法名称和mapper中的标签id保持一致

  D. 方法的参数类型和mapper的paramerType保持一致

  E. 方法的返回值类型和mapper的resultType和resultMap保持一致

<mapper namespace="mapper.BookMapper"> 
    <select id="queryAll" resultType="book"> 
      select * from book 
    </select> 
</mapper>

d) 测试

SqlSession session = MybatisUtils.getSession(); 
        //根据mapper接口生成实现类对象 
        BookMapper mapper = session.getMapper(BookMapper.class); 
        System.out.println(mapper.queryAll()); 
        MybatisUtils.closeSession(); 
 
//junit:单元测试 
        //1.加入junit的jar 
        //2.使用junit实现测试(@test:作为单元直接运行   @[email protected]:在test之前运行  )

输入参数和输出结果

输出结果

a) resultType:

如果结果集中所有的字段和对象中属性名称一一对应则映射成功;

如果结果集中字段的名称和属性名称部分一致,则一致的部分映射成功。

如果结果集中字段的名称和属性名称都不一致,则不会创建对象。

b) 字段和属性不一致实现封装

A. 起别名

B. resultMap(实现字段和属性之间的映射)

<!-- 实现结果集和对象的映射 
        id:唯一标识 
        type:封装的对象类型 
     --> 
    <resultMap type="book" id="bookMap"> 
        <!-- id:描述主键字段和属性之间的映射关系  
            column:字段 
            property:属性 
        --> 
        <id column="bi" property="bid"/> 
        <!-- result:非主键字段的映射 --> 
        <result column="bnam" property="bname"/> 
        <result column="autho" property="author"/> 
        <result column="pric" property="price"/> 
    </resultMap> 
     
    <select id="queryAll" resultMap="bookMap"> 
      select * from book 
    </select>

动态sql

if: 
<select id="queryCombo" parameterType="book" resultType="book"> 
        select * from book where 1 = 1 
        <if test="bid != 0"> 
            and bid = #{bid} 
        </if> 
        <if test="bname != null"> 
            and bname = #{bname} 
        </if> 
    </select> 
 
choose: 
<choose> 
            <when test="bid != 0"> 
                and bid = #{bid} 
            </when> 
            <otherwise> 
                and bname = #{bname} 
            </otherwise> 
</choose> 
 
where 
<where> 
            <if test="bid != 0"> 
                and bid = #{bid} 
            </if>  
            <if test="bname != null"> 
                and bname = #{bname} 
            </if>  
</where> 
 
 
foreach: 
select * from book where bid in 
        <!-- collection:遍历的集合 
            item:每一项值 
            open:开始 
            close:结束 
            separator:分隔符 
         --> 
        <foreach collection="list" item="bid" open="(" close=")" separator=","> 
            #{bid} 
        </foreach>

高级结果映射

1) 查询的结果集分布于多张表

2) 一对多:Role和User(查询role级联查询所有的员工信息)

<resultMap type="role" id="RoleMap"> 
        <id column="rid" property="rid"/> 
        <result column="rname" property="rname"/> 
        <!-- collection:将结果集数据封装到集合中 
                property:属性 
                ofType:单个对象的类型 
                column:关联的键 
         --> 
        <collection property="users" ofType="user" column="rid"> 
            <id column="uid" property="uid"/> 
            <result column="uname" property="uname"/> 
            <result column="rid" property="rid"/> 
        </collection> 
    </resultMap> 
    <select id="queryRoleAndUser" resultMap="RoleMap"> 
        select * from role r left join `user` u on r.rid = u.rid 
    </select> 
 
 
Rolemapper.xml 
<resultMap type="role" id="RoleMap2"> 
        <id column="rid" property="rid"/> 
        <result column="rname" property="rname"/> 
        <!-- collection:将结果集数据封装到集合中 
                property:属性 
                ofType:单个对象的类型 
                column:关联的键 
         --> 
        <collection property="users" ofType="user" column="rid"  
          select="mapper.UserMapper.selectUser"> 
        </collection> 
    </resultMap> 
    <select id="queryRoleAndUser2" resultMap="RoleMap2"> 
        select * from role 
    </select> 
UserMapper.xml 
<select id="selectUser" resultType="user"> 
        select * from user where rid = #{rid} 
    </select>

3) 一对一:查询user及其角色(user)

<resultMap type="user" id="userMap"> 
        <id column="uid" property="uid"/> 
        <result column="uname" property="uname"/> 
        <!-- 将结果集数据封装到对象中 
            property:对象的属性名称 
            column:外键 
            javaType:对象的类型 
         --> 
        <association property="role" column="rid" javaType="role"> 
            <id column="rid" property="rid"/> 
            <result column="rname" property="rname"/> 
        </association> 
    </resultMap> 
   <select id="queryUserAndRole" resultMap="userMap"> 
       select * from user u 
        left join role r 
        on u.rid = r.rid; 
   </select> 
 
UserMapper: 
<resultMap type="user" id="userMap2"> 
        <id column="uid" property="uid"/> 
        <result column="uname" property="uname"/> 
        <!-- 将结果集数据封装到对象中 
            property:对象的属性名称 
            column:外键 
            javaType:对象的类型 
         --> 
        <association property="role" column="rid" javaType="role"  
            select="mapper.RoleMapper.selectRole"> 
        </association> 
    </resultMap> 
   <select id="queryUserAndRole2" resultMap="userMap2"> 
          select * from user 
   </select> 
 
RoleMapper 
<select id="selectRole" resultType="role"> 
        select * from role where rid = #{rid} 
</select>

延迟加载

1)  延迟加载:按需加载(懒加载),只加载主查询,需要用到子查询信息时才去查询。

2)  <collection><association>都具有延迟加载功能。但是默认关闭。

3)  需要打开延迟加载:

<settings> 
    <!-- 延迟加载全局开关 --> 
    <setting name="lazyLoadingEnabled" value="true"/> 
    <!-- 3.4.1以上为false,否则为true --> 
    <setting name="aggressiveLazyLoading" value="false"/> 
</settings>

缓存

一级缓存

Mybatis中的一级缓存时默认开启的。

在内存中一块区域,以类似于map方式进行数据管理。

当用户第一次查询时,会根据sql,参数,rowbounds以及statement的id生成cacheKey,先从二级缓存中获取数据,如果为空,将从一级缓存中根据生成key获取value值,如果也为空,就从数据库进行查询,然后将key和查询的结果放置到一级缓存中。

当用户再次查询时,仍旧生成cacheKey,通过key从一级缓存中获取值,如果有值此时将直接返回不再查询数据库。

        一级缓存是session级别的缓存。

                   如果执行增删改会清空一级缓存。

二级缓存

在内存中一块区域,以类似于map方式进行数据管理。

当用户第一次查询时,会根据sql,参数,rowbounds以及statement的id生成cacheKey,先从二级缓存中获取数据,如果为空,将从一级缓存中根据生成key获取value值,如果也为空,就从数据库进行查询,然后将key和查询的结果放置到一级缓存中。

当用户再次查询时,仍旧生成cacheKey,通过key从一级缓存中获取值,如果有值此时将直接返回不再查询数据库。

如果执行增删改会清空二级缓存

二级缓存是跨session的缓存。

默认二级缓存关闭。

实体类必须序列化。

<cache>

//读取配置文件转换为流 
        InputStream is = Resources.getResourceAsStream("Mybatis.xml"); 
        //创建ssf对象 
        SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is); 
         
        SqlSession session = ssf.openSession(true); 
        SqlSession session2 = ssf.openSession(true); 
        SqlSession session3 = ssf.openSession(true); 
         
        //根据mapper接口生成实现类对象 
        BookMapper mapper = session.getMapper(BookMapper.class); 
        BookMapper mapper2 = session2.getMapper(BookMapper.class); 
        BookMapper mapper3 = session3.getMapper(BookMapper.class); 
         
        System.out.println(mapper.queryAll()); 
        session.close(); 
         
        System.out.println(mapper2.queryAll()); 
        session2.close(); 
         
        System.out.println(mapper3.queryAll()); 
        session3.close();

 

原创文章,作者:奋斗,如若转载,请注明出处:https://blog.ytso.com/tech/pnotes/11140.html

(0)
上一篇 2021年7月19日 10:42
下一篇 2021年7月19日 10:42

相关推荐

发表回复

登录后才能评论