• 2022-6学习笔记


    最近忙里偷闲又看了一遍《Mybatis深入浅出》

    这里大多数是mybatis内容,当然也涉及到别的

    1.springMvc和经典三层架构的关系

    作为两大流行框架,所以Mybatis里边多少也要介绍下springMvc

    三层架构和SpringMVC概述_swadian2008的博客-CSDN博客_springmvc三层架构目录一、关于三层架构和MVC1、三层架构(1)表现层(2)业务层(3)持久层2、MVC 模型3、经典三层架构和MVC的关系二、SpringMVC 概述1、SpringMVC的优势2、SpringMVC 和 Struts2 的优略分析一、关于三层架构和MVC1、三层架构 我们的开发架构一般都是基于两种形式,一种是 C/S 架构,也就是客户端/服务器,另一种是 B/S 架构,也就是浏览器服务器。在 JavaEE 开发中,几乎全都是基于 B/S架构的开发。.https://blog.csdn.net/swadian2008/article/details/113474146

    先说结论,mvc和经典三层架构其实没什么太大关系

    1.1经典三层架构是什么

    表现层,业务层,持久层

     1.2mvc是什么

    MVC 全名是 Model View Controller,是模型(model)-视图(view)-控制器(controller) 的缩写, 是一种用于设计创建 Web 应用程序表现层的模式。

    MVC 中每个部分各司其职:

    Model(模型): 通常指的就是我们的数据模型。作用一般情况下用于封装数据。

    View(视图): 通常指的就是我们的 jsp 或者 html。作用一般就是展示数据的。 通常视图是依据模型数据创建的。

    Controller(控制器): 是应用程序中处理用户交互的部分。作用一般就是处理程序逻辑的。

    1.3mvc的关系

    顶多是都有分层解耦的思想,或者说mvc只能算三层架构中的展现层

    2.slf4j和log4j

    看mybatis日志正好看到了log4j,又一想我们写代码的时候都有@Slf4j,他们到底什么关系?

    接口和实现

    log4j与slf4j的区别_你可拉倒吧的博客-CSDN博客_slf4j和log4j
    为什么叫4j,原来是for java的意思

    log4j : 即 log for java;Java的日志4英文名 four 与for同音
    slf4j : simple log facade for java :简单日志门面

    区别:
    log4j是真正实现日志功能的产品,像这样的产品有很多

    slf4j 是一个适配器,我们通过调用slf4j的日志方法统一打印我们的日志,而可以忽略其他日志的具体方法,这样,当我们的系统换了一个日志源后,不需要更改代码:

    所以不管我们实现用的是Logback还是log4j,在代码中直接用@Slf4j注解就好了,就算更改了日志实现,那代码里打印日志的部分也不用动

    3.blob和text

    blob和text区别_王奕然的博客-CSDN博客_blob text区别

    1.blob用来存文件的二进制字节,而text用来存文本

    2.但是一般情况下我们是要有一个文件服务器的,不建议把文件的字节存到数据库,如果文件过大容易引起内存溢出

    3.text可以看作varchar长度不足时的扩展

     4.事务

    以前看面试题的时候,一直不知道我们spring的@Transactional注解和数据库事务的几个隔离级别到底什么关系,其实我们操作事务不就是数据库事务嘛!

    1.@Transactional需要看底层数据库是否支持事务,比如mysql的myisam是不支持事务的,所以这时候加了@Transactional也不生效

    2.@Transactional的隔离级别也要看底层数据库所支持的隔离级别,比如@Transactional有默认隔离级别,这默认的就是底层数据库的默认隔离级别,比如oracle默认为读已提交,mysql默认为可重复读。而且隔离级别也要看底层数据库支持什么,比如oracle不支持脏读这个隔离级别。

    3.@Transactional的几个禁忌,不能try catch,不能非public,不能自调用

    5.隔离级别

    读未提交,读已提交,可重复读,序列化

    这是数据库的隔离级别,当时你在@Transactional注解的Isolation属性里边也都能找到对应的

    四个隔离级别分别会产生怎样的问题

    读未提交---脏读,事务A读到了事务B未提交的数据,拿着这个数据进行逻辑处理,后来事务B发生了异常回滚了,那事务A就是拿着错误数据进行逻辑处理了

    读已提交---不可重复读,一对夫妻公用一个账号消费,先生看到卡里剩八百,就想买个500的西装,但是他付款之前,女士消费了500烫头,那先生付款时候就报约不足,尴尬了

    为了避免这种尴尬,可以把隔离级别提升未可重复读。可重复读我理解是把某一条数据在读取时候给锁上了,直到用完才解锁。

    可重复读---幻读,可重复读是针对一条记录,但是多条记录时就可能产生问题。女士要打印这个月的消费记录,她肯定先查询再打印,她查询时候发现这个月有十条消费记录总计1000,然后此时先生去消费了800,那女士点击打印打印出来的就是11条记录总计1800,这个时候女士以为自己看错了产生了幻觉所以叫幻读。

    解决幻读的办法就是再提升一个隔离级别---序列化,序列化就是把操作排好序,像队列一样一个操作执行完才能按顺序执行下一个操作。

    但是随着隔离级别的提升,效率也在降低,所以一般就用读已提交这种隔离级别

    6.分布式锁

    以前以为synchronized就完事大吉了,但是前几天才知道分布式情况下synchronized并不能保证安全性。因为synchronized只能锁自己jvm中的对象,本地锁,但是比如现在有两个服务,那我同时访问两个服务的同一个synchronized方法,此时就会产生并发问题。

    然后照同事抄了一个zk分布式锁才解决问题。

    7.Collections.singletonList()

    数组里只包含一个元素那可以直接用Collections.singletonList(),但是如果你之后还有增加,那就不行了。Collections.singletonList()返回的是不可变的集合,但是这个长度的集合只有1,可以减少内存空间。但是返回的值依然是Collections的内部实现类,同样没有add的方法,调用add,set方法会报错。

    8.Mybatis的无参构造方法

    2019-03-20 mybatis实体为什么要提供一个无参的构造函数 - 简书

    Class.forName("className").newInstance();

    有一点要注意:@Builder也会覆盖无参构造方法

     9.动态代理

    mybatis只有一个接口,但是它可以调用指定namespace中得sql,怎么做到的,就是动态代理。

    9.1首先我们要遵守几个开发规则

    1.xml中命名空间namespace要跟接口得全路径名对应,

    2.xml中的sql的id要和方法名对应,namespace+id在整个项目中要唯一,否则mybatis会报错,就像你controller中的requestMapping中的url在整个项目中不唯一的话,spring会给你报错一样

    3.在配置类上使用@Mapperscan配置接口包的路径,或者每个接口上都用@Mapper修饰。@MapperScan和@Mapper是Mybatis注解,用于把接口绑定动态代理

    9.2动态代理执行过程

    MyBatis进阶之接口代理方式_heromps的博客-CSDN博客_mybatis接口代理

     Mybatis源码-加载映射文件与动态代理 - SegmentFault 思否

    调用其MapperMethod的execute()方法,而通过上面的分析已经知道,MapperMethod中的SqlCommand关联着MappedStatement,而MappedStatement中包含着和被调用方法所关联的SQL信息,结合着SqlSession,就可以完成对数据库的操作。关于如何对数据库操作,将在后续的文章中介绍,本篇文章对于Mybatis中的动态代理的分析就到此为止。最后以一张图归纳一下Mybatis中的动态代理执行流程,如下所示。

     10.主键回填

    这个用的比较少,一般都是代码里设置好Id再存入数据库,就算是用sequence也是先读出来sequence再拼接到id里边去,这个功能还是实习时候用过

    MyBatis中主键回填的两种实现方式-蒲公英云

    10.1自增主键

    1. <insert id="insertBook" useGeneratedKeys="true" keyProperty="id">
    2. insert into t_book (b_name,author) values (#{name},#{author});
    3. </insert>

    其中keyProperty实体中的属性名,如果你实体中要用userId接回写的主键,那

    1. <insert id="insertBook" useGeneratedKeys="true" keyProperty="userId">
    2. insert into t_book (b_name,author) values (#{name},#{author});
    3. </insert>

    关于Mybatis中keyProperty属性_m0_67401920的博客-CSDN博客_mybatis 的keyproperty

     10.2非自增主键

    selectKey标签

    1. <insert id="insertBook">
    2. <selectKey keyProperty="id" resultType="java.lang.Integer">
    3. SELECT LAST_INSERT_ID()
    4. </selectKey>
    5. insert into t_book (b_name,author) values (#{ name},#{ author});
    6. </insert>

    11.mybatis的xml之间的继承

    我一般什么情况下用到:mybatis-generate插件自动生成的xml我肯定不能手动去改的,但是我自定义的xml还想用自动生成xml中的信息,比如BaseResultMap

    11.1、首先dao层mapper.java需要继承原来的接口

    1. public interface TagExtendMapper extends TagMapper {
    2. ...
    3. }

    11.2、继承原始mapper.xml的结果映射

    1. <mapper namespace="com.xxx.dao.TagExtendMapper">
    2. <resultMap id="ExtBaseResultMap" type="com.xxx.dao.Tag" extends="com.xxx.dao.mapper.TagMapper.BaseResultMap">
    3. ...
    4. </resultMap>
    5. </mapper>

    12.on后边加条件和where后边加条件的区别

    on条件与where条件的区别_游子心的博客-CSDN博客_on和where的区别

     13.pg函数

    13.1.array_agg 的返回

    mybatis没有现成的TypeHandler,需要自定义一个TypeHandler,所以一般都会用array_to_string转成字符串返回。

    array_to_string(demandOrderItem.orderCode,',') 

    13.2array_remove排除某些元素

    排除空元素

    array_remove(array_agg(distinct order_item.ORDER_STATUS),null) order_status_list

    14.@Builder和@SuperBuilder存在时,不会默认创建空构造函数

  • 相关阅读:
    如何理解 dlopen 的 RTLD_LOCAL flag?
    数据结构-链表的简单操作实现
    NOIP2023模拟14联测35 charlotte
    内网隧道代理技术(二十四)之 ICMP隧道介绍
    Spring Boot
    HCIE-Cloud题库
    C#写入Datetime到SQL server
    MES系统成为工业4.0首选,制造业真正数字化车间你看过吗?
    php+mysql羽毛球场地租赁管理系统
    【图像处理】基于双目视觉的物体体积测量算法研究(Matlab代码实现)
  • 原文地址:https://blog.csdn.net/qq_35653822/article/details/125535380