mybatis映射器的配置与使用

99 阅读4分钟

主要记录一下mybatis的增删改查操作,如何传递参数并返回指定的数据类型,查询一对一、一对多的级联查询。并且简单记录mybatis一级缓存和二级缓存的用法以及mybatis如何调用存储过程。

mybatis增删改查操作

  1. select
    简单select元素应用(查询某一姓氏的数据行总数)

    <!--
    paramterType-传入参数类型
    resultType-返回值类型
    id-对应mapper接口名
    -->
    <select id="xxx" parameterType="string" resultType="int">
            select count(*) total from xxx where xxx.name like concat(#{firstName},'%')
    </select>
    

    提示

    • 使用map传递参数导致业务可读性丧失,导致后续扩展和维护的困难,在实际的应用中要果断废弃这种方式
    • 使用@param注解传递多个参数,收到参数个数影响,当n<=5时,这是最佳方式,比javabean更好,更直观;当n>5时,不推荐此方式
    • 参数个数大于5个时,建议使用java bean方式
    • 对于使用混合参数,要明确参数的合理性

    resultMap映射结果集

    <!--
    resultmap元素定义一个map
    type="user"user是类的别名
    -->
    <mapper namespace="xxx.xxx.userMapper">
            <resultMap id="userMap" type="user">
            <id property="id" column="id"/>
        <result property="name" column="name"/>
      </resultMap>
      <select id="getRoleUserMap" parameterType="long" resultMap="userMap">
            select id,name from user where id = #{id}
      </select>
    </mapper>
    

    分页(RowBounds)

    java代码(映射器接口mapper)

    public List<user> findByRowBounds(@Param('name') String name,RowBounds rowBounds);
    

    xml配置(映射器配置文件)

    <select id="findByRowBounds" resultType="user">
          select id,name from user where name like concat('%',#{name},'%')
    </select>
    

    java代码(测试RowBounds)

    sqlSession sqlsession=null;
          try{
        sqlsession=SqlsessionFactoryUtil.openSqlSession();
        userMapper u=sqlsession.getMapper(usermapper.class);
        RowBounds rowbounds=new RowBounds(0,20);
        List<user> list=u.findByRowBounds("张三",rowbounds);
        System.out.println(list.size());
      }catch(Exception e){
        e.printStackTrace();
      }finally{
        if(sqlsession!=null){
          sqlsession.close();
        }
      }
    

    提示
    返回至多20条数据,RowBounds分页的原理是执行sql的查询后,按照偏移量和限制条数返回查询结果。对于大量的数据查询,性能不佳。

  2. insert
    简单insert语句

    <insert id="insertuser" parameterType="user">
      insert into user(id,name) values(#{id},#{user})
    </insert>
    

    添加数据成功之后返回主键

    <!--
    useGeneratedKeys-代表用jdbc的statement对象的getGeneratedKeys方法返回主键
    keyProperty-代表用哪个属性去匹配这个主键
    -->
    <insert id="insertuser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
      insert into user(id,name) values(#{id},#{user})
    </insert>
    
  3. update、delete

    简单修改删除语句

    <update id="updateuser" parameterType="user">
    	update user set name = #{name} where id = #{id}
    </update>
    <delete id="deleteuser" parameterType="long">
    	delete from user where id = #{id}
    </delete>
    

    提示
    mybatis提供了对控制数值的精度支持:
    #{width,javaType=double,jdbcType=NUMERIC,numericScale=2}

resultMap、级联介绍

  1. 构成

    <resultMap>
            <constructor><!--配置构造方法-->
            <idArg/>
        <arg/>
      </constructor>
      <id/>
      <result/>
      <association/><!--一对一级联-->
      <collection/><!--一对多级联-->
      <discriminator><!--鉴别器 类似于switch...case...语句-->
            <case/>
      </discriminator>
    </resultMap>
    
  2. 级联

    • N+1
      • 解决办法:延迟加载
    • 延迟加载
      • lazyLoadingEnabled
      • aggressiveLazyLoading
        • 启用时,对任意延迟属性的调用会使带有延迟加载属性的对象完整加载,否则按需加载
  3. 缓存
    暂时存在内存中的数据为缓存数据

    • 一级缓存

      • 在sqlsession上的缓存,默认开启;不需要pojo对象可序列化
      • 对于不同的sqlsession对象,数据不共享;如果想要实现共享,需开启二级缓存
    • 二级缓存

      开启二级缓存

      <!--第一步在映射配置文件中加入代码->
      <cache/>
      
      //第二部pojo实现序列化接口
      public class user implements Serializable{
        public static final long serialVersionUID=.....;
      }
      

      提示
      需要在查询后进行commit,如果是1级缓存,mybatis才会缓存对象到sqlsessionfactory层面

存储过程

  1. IN|OUT参数存储过程
    代码示例:在myabtis映射文件中定义一个带有输入和输出参数的存储过程,并使用java代码调用这个存储过程

    --IN|OUT存储过程(oracle)
    create or replace procedure count_user(
            name in varchar,
            count_total out int,
            exec_date out date
    )
    is
    begin
            select count(*) into count_total from user where name like '%' ||name|| '%';
            select sysdate into exec_date from dual;
    end;
    

    创建一个实体类userparam

    //pojo
    public class userparam{
      private String name;
      private int total;
      private Date execdate;
      /**setter and getter*/
    }
    

    在mybatis中定义存储过程的调用

    <!--userMapper-->
    <select id="countuser" parameterType="xxx.xxx.user" statementType="CALLABLE">
            {call count_user(
            #{name,mode=IN,jdbcType=VAECHAR},
            #{total,mode=OUT,jdbcType=INTEGER},
            #{execdate,mode=OUT,jdbcType=DATE}
      )}
    </select>
    

    使用java代码调用这个存储过程

    //测试接口调用
    userparam user=new userparam();
    SqlSession sqlsession=null;
    try{
      sqlsession = SqlSessionFactoryUtils.openSqlSession();
      userMapper usermapper=sqlsession.getMapper(userMapper.class);
      user.setName("张三");
      usermapper.countuser(user);
    }catch(Excetion e){
      e.printStackTrace();
    }finally{
      if(sqlsession!=null){
        sqlsession.close();
      }
    }
    

    提示
    mybatis会将输出参数会填到传递的pojo中

  2. 游标

    <!--userMapper-->
    <select id="countuser" parameterType="xxx.xxx.user" statementType="CALLABLE">
            {call count_user(
            #{name,mode=IN,jdbcType=VAECHAR},
            #{total,mode=OUT,jdbcType=INTEGER},
            #{execdate,mode=OUT,jdbcType=DATE},
            <!--游标映射-->
            #{roleList,mode=OUT,jdbcType=CURSOR,javaType=ResultSet,resultMap=roleMap}
      )}
    </select>
    

    提示
    先定义了resultMap元素,它定义了映射规则,rolelist的数据库类型为cursor,这样就会把结果使用resultset处理。为了使resultset能够映射到pojo,设置resultmap为rolemap,这样mybatis就会采用配置的映射规则将其映射为pojo了。

本篇mybatis映射器的配置与使用就介绍完了,感谢支持~~