zoukankan      html  css  js  c++  java
  • mybatis复习笔记----关于一些需记忆的点

    POINT-一些点

    一、sql插入后,返回自增主键值
    mybatis也是利用statement.getGenreatedKeys()。

    属性:
    useGeneratedKeys="true"----使用自增主键获取主键值策略
    keyProperty----指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性-->
    例如:
    <insert id="addEmp" parameterType="com.atguigy.mybatis.bean.Employee" useGeneratedKeys="true" keyProperty="id">
        insert into tbl_employee(last_name,email,gender)values(#{lastName} ,#{emai1} ,#{gender})
    </insert>
    

    oracle不支持自增,但使用序列来模拟自增。

    每次插入的数据的主键是从序列中拿到的值;如何获取到这个值;
    <insert id="addEmp" databaseId="oracle">
          <!- -
                keyProperty:查出的主键值封装给javaBean的哪个属性order="BEFORE":当前s.ql在插入sgl之前运行
                resultType:查出的数据的返回值类型
          -->
          <selectKey keyProperty="id" order="BEFORE"resultType="Integer">
                <! --编写查询主键的s.gl语句-->
                select EMPLOYEES_SEQ.nextval from dual
          </selectkey>
          <!--插入时的主键是从序列中拿到的   其实也可以直接在sql里写从序列里取值,即#{id}替换为employees_seq.nextval –->
          insert into employees(EMPLOYEE_ID,LAST_NAME ,EMAIL)values(#{id} ,#{lastName} ,#{email})
    </insert>
    

    二、对于接口方法中传递参数处理

    • @Param("")来指定参数对应的值
      当接口方法传递多个参数时,对应mapper.xml默认使用map存储,key=param1...paramn表示,value=参数值,所以在sql中通过#{}取值时要通过param1...paramn来取
      若想指定参数的key需要在接口参数前添加@Param("xxx")来指定。
      即接口中传递过来的参数可以是pojo也可以是一个map,因为最后都是转为一个map

    To: 如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO (Transfer object)数据传输对象

    明确即接口对应.xml配置sql文件可传递:pojo、map、To(数据传输对象)

    • 参数封装
      对于传过来的collectio类型,或数组,若没有@Param注解表示,需要用list来取值,因为也是封装成一个map,但是key=list
    例如:
    public Employee getEmpById(List<Integer> ids);
    取值:取出第一个id的值:错误:#{param1[0]},#{ids[0]}都是错的  正确:#{list[0]},
    

    三、关于#{}与${}取值时的预编译与拼接
    #{}:是以预编译的形式,将参数设置到sql语句中;Preparedstatement:防止sql注入
    ${}:取出的值直接拼装在sql语句中;会有安全问题;
    大多情况下,我们去参数的值都应该去使用#{};
    原生jdbc不支持占位符的地方我们就可以使用${}进行取值,比如按照年份分表拆分,分表、排序等;

    select *from ${year}_salary where XXX3
    select * from tbl_employee order by $if_name} ${order}
    

    四、#{}更丰富的用法:
    规定参数的一些规则:

    javaType、jdbcType. mode(存储过程)、numericScale、
    resultMap、typeHandler、jdbcTypeName、expression(未来准备支持的功能)
    

    jdbcType通常需要在某种特定的条件下被设置:
    在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错)﹔
    JdbcType OTHER=无效的类型,因为mybatis对所有的nul1都映射的是原生Jdbc的OTHER类型,oracle不能处理。
    由于全局配置中:jdbcTypeForNull=OTHER; oracle不支持;可通过以下两种方法解决。

    1、#{emai1,jdbcType=OTHER];
    2、jdbc TlypeForNu11=NULLl
    

    五、resultType:如果返回的是一个集合,要写集合中存储元素的类型,而不是list类型

    六、可以在接口方法中通过@MapKey("xxx")来指定接口对应.xml配置文件对应方法的sql语句返回类型为map时用什么来作为map的键

    七、多个数据一起插入,mysql支持values后面跟‘,’分割的多个‘()’。如:insert into student values(101,"xhangsan"),(102,"lisi"),而oracle则不支持。
    ----解决oracle多数据插入:
    1--多个insert语句放在begin ... end 里面

    begin
        insert into employees(employee_id,last_name , email)
        values(employees_seq.nextval, 'test_001' , 'test_001@xiaoai.com');
        insert into employees (employee_id,last_name , email)
        values(employees_seq.nextval, 'test_002' , 'test_0e02@xiaoai.com');
    end;
    例如mabatis使用:
    <insert id="addEmps" databaseId="oracLe">
        <!-- oracle第一种批量方式-->
        <foreach collection="emps" item= "emp" open="begin" close="end">
            insert into employees(employee_id,1ast_name, email)
            values(employees_seq.nextval,#{emp. lastName},#{emp.emai1}
        </foreach>
    </insert>
    

    2--利用中间表

    例如sql语句:
    insert into employees(employee_id, last_name, email)
          select employees_seq.nextval, lastName , email from(
                select 'test_a_01', lastName, 'test_a_eO1’ email from dual
                union
                select 'test_a_02', lastName, 'test_a_e02' email from dual
                union
                select 'test_a_03', lastName, 'test_a_e03' email from dual
          )
    例如mabatis使用:
    <insert id="addEmps" databaseId="oracLe">
        <! -- oracle第二种批量方式-->
        insert into employees(employee_id,last_name, email)
            <foreach collection="emps " item="emp" separator="union"
            open=" select employees_seq.nextva1,lastName , email from("
            close=")">
                select #{emp.lastName} lastName, #{emp.email} email from dual
            </foreach>
    </insert>
    

    八、两个默认内置参数

    _parameter:代表整个参数
        单个参数:_parameter就是这个参数
        多个参数:参数会被封装为一个map:_parameter就是代表这个map
    _databaseId:如果配置了databaseIdProvider标签。
        _databaseId就是代表当前数据库的别名|
    
    例如使用:
    当相同数据在不同数据库时,判断当前使用什么数据库对应查询什么表
    <select id="getEmpsTestInnerParameter" resultType="com.xiaoai.employee">
        <if test="_databaseId=='mysqL'">
            select * from tbl_employee
        </if>
        <if test="_databaseld=='oracle'">
            select * from employees
        </if>
    </ select>
    

    缓存

    一、一级缓存(本地缓存)
    一级缓存是一直开启的,缓存即SqlSession级别的一个map

    一级缓存失效情况:(即没有使用到当前一级缓存的情况,需要再向数据库发出查询)
    1--sqlsession不同
    2--sqlsession相同,查询条件不同(即当前一级缓存中还没有要查询的数据>
    3--sqlsession相同,查询条件相同,但是两次查询之间进行过增删改操作(怕增删改对数据进行了更改)。
    4--手动清除了一级缓存,即通过sqlsession.clearCache()清除缓存;  .clearCache()只清除一级缓存,增删改时一、二级缓存都会清除。
    

    二、二级缓存(全局缓存)
    常用数据放到二级缓存中,基于namespace级别的缓存,一个namespace对应一个二级缓存。

    工作机制
    1、一个会话,查询一条数据,这个数据就会被放在当前会话的一级缓存中;
    2、如果会话关闭;一级缓存中的数据会被保存到二级缓存中;新的会话查询信息,就可以参照二级缓存中的内容。
    

    三、缓存设置
    在接口对应.xml配置文件中通过【cache】标签设置

    <cache eviction="" flushInterval="" readOnly="" size="" type=""></cache>
    属性说明:
    1--eviction:缓仔的回收策略:当缓存慢了以后,需要删除一些数据,会根据设置的策略进行删除 默认的是LRU。
          LRU 最近最少使用的:移除最长时间不被使用的对象。
          FIFO 先进先出:按对象进入缓存的顺序来移除它们。
          SOFT 软引用:移除基于垃圾回收器状态和软引用规则的对象。
          WEAK 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
    2--flushInterval:缓存刷新间隔 缓存多长时间清空一次,默认不清空,设置一个毫秒值
    3--readOnly:是否只读:
          true:只读; mybatis认为所有从缓存中获取数据的操作都是只读操作,不会修改数据。 mybatis为了加快获取速度,直接就会将数据在缓存中的引用交给用户。不安全,速度快
          false:非只读:mybatis觉得获取的数据可能会被修改。 mybatis会利用序列化&反序列的技术克隆一份新的数据给你。安全,速席慢|
    4--size:缓存存放多少元素;
    5--type="":指定自定义缓存的全类名;实现Cache接口即可;
    

    四、二级缓存使用
    查出的数据默认放在一级缓存中,只有当sqlsession会话提交或者关闭后数据才会转移到二级缓存中。但前提是二级缓存开启了。

    二级缓存的使用:
    1--让Mybatis框架支持二级缓存(在主配置文件中配置)
        <settings> 
            <!-- 开启二级缓存的支持 -->  
            <setting name="cacheEnabled" value="true"/> 
        </settings> 
    2--让当前接口方法的.xml映射文件支持二级缓存(在接口对应配置文件中配置)
        <mapper namespace="com.itheima.dao.IUserDao">  
            <!-- 开启二级缓存的支持 -->  
            <cache></cache> 
        </mapper>
    3--让当前操作支持二级缓存(在select等操作标签中配置)
        <select id="findById" resultType="user" parameterType="int" useCache="true">  
            select * from user where id = #{uid} 
        </select>
    
  • 相关阅读:
    项目编译
    sqlserver查列名
    list<>初始化赋值两种方式
    看到一句很不错的话
    typescript
    vscode里div等html标签代码补全
    JavaScript 基于原型链的继承
    大数据系列01:大数据离线计算平台hadoop集群搭建和本地环境配置实践
    java数据类型
    计算机基础及java基础
  • 原文地址:https://www.cnblogs.com/xiaoaiying/p/14056188.html
Copyright © 2011-2022 走看看