zoukankan      html  css  js  c++  java
  • 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:作为单元直接运行   @before/@after:在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();
  • 相关阅读:
    python瓦登尔湖词频统计
    css规范思维导图(仅限于自己)
    html规范思维导图(仅限于自己)
    vue-cli配置跨域代理
    vue中的scoped分析以及在element-UI和vux中的应用
    yarn和npm的对比,以及项目中使用方式
    Promise对异步编程的贡献以及基本API了解
    跨域限制原因及常见跨域方法
    js中的逗号运算符
    JS中的浅拷贝与深拷贝
  • 原文地址:https://www.cnblogs.com/qingyunzong/p/8394806.html
Copyright © 2011-2022 走看看