首页 > 其他分享 >day46 6-14 mybatis#{}与$的区别、一二级缓存 & 6-15 事务管理 & SSM三大框架简单回顾

day46 6-14 mybatis#{}与$的区别、一二级缓存 & 6-15 事务管理 & SSM三大框架简单回顾

时间:2022-12-08 19:56:21浏览次数:67  
标签:事务管理 缓存 15 14 SqlSession 二级缓存 SQL id name

mybatis—— OGNL表达式

(mapper xml文件内if标签内)
OGNL 全称 Object-Graph Navigation Language,是 Java 中的一个开源的表达式语言,用于访问对象数据。也是mybatis实现动态sql的基础。

常见的OGNL表达式

表达式 说明 表达式 说明
A or B 或关系 A and B 与关系
A == B; A eq B 相等 A != B; A neq B 不等
A lt B; A < B 小于 A gt B; A > B 大于
A lte B; A <= B 小于等于 A gte B; A >= B 大于等于
!A 或者 not A 非,取反 A.method(args) 调用对象方法
A.property 访问属性值 A[k] 访问数组、链表(k为序号)或者 Map(k为键值)

2.2 #{}与${}的区别

${}与#{}都是从参数列表中取值
#{} 是编译好SQL语句再取值,是经过预编译的,是安全的。
#{}引用参数的时候,Mybatis会把这个参数认为是一个字符串,并自动加上单引号''
示例:

SELECT * FROM p1_staff_info WHERE id = #{id}

执行时会转换为
SELECT * FROM p1_staff_info WHERE id = 'p0051 or 1 = 1'
${}是取值以后再去编译SQL语句;
${}是未经过预编译的,仅仅是取变量的值,是不安全的,存在SQL注入风险;
示例:
SELECT * FROM stu_info WHERE id = ${id}
假如传入的参数id = "'p0051' or 1 = 1";
则执行时会转换为
SELECT * FROM p1_staff_info WHERE id = 'p0051' or 1 = 1;

3 映射文件mapper.XML语法

3.1 映射关系resultMap

<!--orm 对象和数据表之间的映射关系-->
<resultMap id="baseMap" type="com.st.pojo.User">
<result column="id" property="id" jdbcType="INTEGER"/>
    <result column="u_name" property="name" jdbcType="VARCHAR"/>
    <result column="time" property="createTime" jdbcType="TIMESTAMP"/>
    <result column="u_money" property="money" jdbcType="DECIMAL"/>
</resultMap>

column:数据表字段名
property:pojo类属性名
jdbcType:数据类型

3.2 查询select

parameterType:接收参数的数据类型
resultMap:查询数据库返回结果的映射关系,关联baseMap的id属性
resultType:查询数据返回结果的数据类型,如:java.lang.String

<select id="queryUser" parameterType="_User" resultMap="baseMap">
  SELECT * FROM p2_user
  <where>
    <if test="name != null">AND u_name = #{name}</if>
    <if test="phone != null">AND u_phone = #{phone}</if>
    <if test="pass != null">AND u_pass = #{pass}</if>
  </where>
</select>

2.3 添加insert

insert语句默认返回值是int类型,表示insert执行成功几条记录

<!--
添加用户,并返回用户主键,
useGeneratedKeys 设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置属性中
keyProperty 实体类主键属性
需要sqlsession开始事务自动提交openSession(true);
-->
<insert id="add" parameterType="_User" useGeneratedKeys="true" keyProperty="id">
INSERT INTO p2_user
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="name  != null">u_name,</if>
      <if test="pass  != null">u_pass,</if>
      <if test="phone != null">u_phone,</if>
    </trim>
    <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
      <if test="name  != null">#{name},</if>
      <if test="pass  != null">#{pass},</if>
      <if test="phone != null">#{phone},</if>
</trim>
</insert>

3.4 批量插入

<insert id="addAll" parameterType="java.util.List">
<!--
        使用批量插入需要在jdbc:url中添加allowMultiQueries=true
        作用:
        1.可以在sql语句后携带分号,实现多语句执行。
        2.可以执行批处理,同时发出多个SQL语句。

        collection 被遍历的结果集
        item 本次遍历获取的元素
        index 当前迭代的次数
separator:每次一遍历之后,语句末尾拼接指定字符
-->
<foreach collection="list" item="sf" index="index" separator=";">
      INSERT INTO p1_staff_info
      <trim prefix="(" suffix=")" suffixOverrides=",">
         <if test="sf.id != null">id,</if>
         <if test="sf.name != null">s_name,</if>
      </trim>
      <trim prefix="VALUES(" suffix=")" suffixOverrides=",">
         <if test="sf.id != null">#{sf.id, jdbcType=INTEGER},</if>
         <if test="sf.name != null">#{sf.name, jdbcType=VARCHAR},</if>
      </trim>
</foreach>
</insert>

3.5 更新update

<update id="update" parameterType="_User">
UPDATE p2_user
<set>
    	<if test="name != null">u_name = #{name, jdbcType=VARCHAR},</if>
        <if test="pass != null">u_pass = #{pass, jdbcType=VARCHAR},</if>
        <if test="phone != null">u_phone = #{phone, jdbcType=VARCHAR},</if>
</set>
    <where>
    	<if test="id != null">and id = #{id, jdbcType=INTEGER}</if>
    </where>
</update>

3.6 封装sql

<!-- 封装sql语句 -->
<sql id="cs">id,s_name,s_sex </sql>
<!-- include标签引入封装的sql语句,refid关联一个sql标签的id属性-->
select <include refid="cs"/> from student

4 settings

设置名 描述 可选值 默认值
cacheEnabled 全局地开启或关闭所有 mapper 中的缓存(二级缓存) true,false false
lazyLoadingEnabled 延迟加载的全局开关,当开启时,所有关联对象都会延迟加载 true,false false
defaultStatementTimeout 设置数据库查询超时时间 任意正整数 null
mapUnderscoreToCamelCase 是否开启自动驼峰命名规则(camel case)映射 true,false false
localCacheScope MyBatis会默认缓存会话中的查询,即 SESSION,若无需缓存则设置为 STATEMENT SESSION,STATEMENT SESSION
logPrefix 指定 MyBatis 日志名称前缀 任何字符串 未设置
logImpl 指定 MyBatis 日志的实现类,未指定时将自动查找 SLF4J,LOG4J,LOG4J2,JDK_LOGGING,COMMONS_LOGGING,STDOUT_LOGGING,NO_LOGGING 未设置
proxyFactory 指定创建具有延迟加载能力的对象所用到的代理工具 CGLIB,JAVASSIST JAVASSIST

eg:

<settings>
<!--日志打印sql语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!-- 开启下划线转驼峰的配置 -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>

4.2 typeAliases

<typeAliases> 
<typeAlias type="com.model.User" alias="User"/>
</typeAliases>
或
<typeAliases>
<!-- 扫描该包下所有类,每个类的别名是其类名首字母小写,如 User类的别名为 user -->
<package name="com.model"/>
</typeAliases>

4.3 事务管理器transactionManager

在 xml 文件中对应 ,其中 type 属性对应了事务管理器的两种类型,分别是JDBC和MANAGED。
JDBC:直接使用了 JDBC 的提交和回滚机制。
MANAGED:让容器来管理事务的整个生命周期,例如 spring 容器。

5 加载配置文件,创建SqlSession对象

//加载mybatis.xml文件
InputStream in = Resources.getResourceAsStream("mybatis.xml");
//创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(in);
//使用工厂生产SqlSession对象
SqlSession sqlSession = factory.openSession();
//使用SqlSession创建Mapper接口的代理对象
StuDao stuDao = sqlSession.getMapper(StuDao.class);

6常用注解

@Param
参数标签,在Mapper的方法签名上标注参数,为SQL语句中参数赋值而服务,指定参数名称
public int delete(@Param("id") Integer id);

7 缓存

缓存的作用
在参数和SQL完全一样的情况下,多次调用mapper方法,只会执行一次SQL,第一次执行sql查询到的结果集会被保存在缓存中,后面重复调用mapper方法返回的是缓存中的结果集;
缓存的目的
提高对数据库查询的效率,提高应用程序的性能;

一级缓存

Mybatis对缓存提供支持,但是在没有配置的默认情况下,它只开启一级缓存,一级缓存只是相对于同一个SqlSession而言。
所以在参数和SQL完全一样的情况下,我们使用同一个SqlSession对象调用一个Mapper方法,往往只执行一次SQL。
因为使用SelSession第一次查询后,MyBatis会将查询出来的结果集放在缓存中,以后再查询的时候,如果没有声明需要刷新缓存,并且缓存没有超时的情况下,SqlSession都会取出当前缓存的数据,而不会再次发送SQL到数据库。
特征:
1 一级缓存是默认开启的;
2 一级缓存只是相对于同一个SqlSession而言;
3 在一个会话中,调用 insert、update、delete 语句时,会话中的缓存会被刷新;

关闭一级缓存

通过 flushCache 属性来关闭 select 查询的一级缓存
<select id="" flushCache="true">

二级缓存

MyBatis的二级缓存是Application(应用程序)级别的缓存,二级缓存默认是不开启的,二级缓存的有效范围为一个 SqlSessionFactory 生命周期,绝大多数情况下,应用都会只有一个 SqlSessionFactory,因此我们可以把二级缓存理解为全局缓存。
二级缓存的开启需要进行配置,实现二级缓存的时候,MyBatis要求返回的POJO(简单java类)必须是可序列化的,也就是要求实现Serializable接口。
特征:
1 二级缓存默认是关闭的;
2 二级缓存是Application(应用程序)级别的缓存;
3 二级缓存要求返回的POJO(简单java类)必须是可序列化的;

开启二级缓存

mybtis.xml配置文件中开启二级缓存

<settings> 
<setting name="cacheEnabled" value="true"/> 
</settings>

<!--开启本mapper的namespace下的二级缓存-->
<!--
	eviction:代表的是缓存回收策略,目前MyBatis提供以下策略。
    (1) LRU,最近最少使用的,即最长时间不用的对象
    (2) FIFO,先进先出,按对象进入缓存的顺序来移除他们
    (3) SOFT,软引用,移除基于垃圾回收器状态和软引用规则的对象
    (4) WEAK,弱引用,更积极的移除基于垃圾收集器状态和弱引用规则的对象。这里采用的是LRU,移除最长时间不用的对象

flushInterval:刷新间隔时间,单位为毫秒,这里配置的是60秒刷新,如果你不配置它,那么当新SQL被执行的时候才会去刷新缓存。

size:引用数目,一个正整数,代表缓存最多可以存储多少个对象,不宜设置过大。设置过大会导致内存溢出。最大缓存1024个对象

	readOnly:只读,意味着缓存数据只能读取而不能修改,这样设置的好处是我们可以快速读取缓存,缺点是我们没有办法修改缓存,他的默认值是true,不允许我们修改
-->
<cache eviction="LRU" flushInterval="60000" size="1024" readOnly="true"/>
<!--可以通过设置useCache来规定这个sql是否开启二级缓存,
ture是开启,false是关闭-->
<select id="selectAllStudents" resultMap="studentMap" useCache="true">
	SELECT id, name, age FROM student
</select>

标签:事务管理,缓存,15,14,SqlSession,二级缓存,SQL,id,name
From: https://www.cnblogs.com/xiaoto9426/p/16967114.html

相关文章