spring 数据库访问 学习笔记

数据库访问

spring为我们做了什么

  1. 把SQLException封装为DataAccessException,这个异常是一个RuntimeException,并且让我们能区分SQL异常的原因,例如,DuplicateKeyException表示违反了一个唯一约束;

    • 我们可以针对这些特殊的异常做特殊的处理
  2. 申明式事务,@Transactional,spring默认在RuntimeException的情况下回滚

    • rollbackFor指定会回滚事务的类型,因为java的注释只能用Class<?> 所以Xxx.class的写法在注释中很常见

    • 推荐,自定义业务异常继承Runtime,这样的异常处理不要指定回滚类型,而且语义化更明显,我们可以在这些异常中封装自己属性,最好提供一个方法,产生出一个统一返回类,而不是在统一返回类中修改我们的代码。而且这种异常不需要我们在方法层面抛出,直接交给spring来管理即可,但是注意会产生事务回滚的

    • 默认事务传递级别

      • 什么是事务传递,如果两个方法都有事务,一个方法调用另一个方法,他们在一个事务中吗,里面的方法如果出错了,外面的方法需要回滚吗,或者说,我们怎么控制他们是否回滚

      • 默认传播级别就是REQUIRED,它的意思是,如果当前没有事务,就创建一个新事务,如果当前有事务,就加入到当前事务中执行

        • 这样相当于把不断调用的方法写在了一个方法之中,要么同时成功,要么同时失败

        • SUPPORTS:表示如果有事务就加入到当前事务,如果没有,那也不开启事务执行。这种传播级别可用于查询方法,因为SELECT语句既可以在事务内执行,也可以不需要事务;

          MANDATORY:表示必须要存在当前事务并加入执行,否则将抛出异常。这种传播级别可用于核心更新逻辑,比如用户余额变更,它总是被其他事务方法调用,不能直接由非事务方法调用;

          ​ 这个其实可以由我们通过逻辑来把控

          REQUIRES_NEW:表示不管当前有没有事务,都必须开启一个新的事务执行。如果当前已经有事务,那么当前事务会挂起,等新事务完成后,再恢复执行;

          NOT_SUPPORTED:表示不支持事务,如果当前有事务,那么当前事务会挂起,等这个方法执行完成后,再恢复执行;

          NEVER:和NOT_SUPPORTED相比,它不但不支持事务,而且在监测到当前有事务时,会抛出异常拒绝执行;

          NESTED:表示如果当前有事务,则开启一个嵌套级别事务,如果当前没有事务,则开启一个新事务。

          上面这么多种事务的传播级别,其实默认的REQUIRED已经满足绝大部分需求,SUPPORTSREQUIRES_NEW在少数情况下会用到,其他基本不会用到,因为把事务搞得越复杂,不仅逻辑跟着复杂,而且速度也会越慢。

        • 实现原理

          • ThreadLocal,一个线程内,保存着一个事务,说明一个问题,如果不在一个线程内,是无法保证事务的,我们必须想办法把这个传递给其他线程,这样其他的线程才能加入到我们的事务中
  3. Dao

    • 很像mybatis plus 可以学习一下实现的方法
    • 使用DAO简化crud
    • 自己总结一下一些思想
      • 如果我们的要继承的类,每次都要实现一些方法,即使这样方法的类型不同,比如泛型,都最好抽象出一层,这一层负责完成公共的部分(抽象类,实现层)
      • curd这些固定的,再加上count,page等,我们完全可以用统一的模板去实现
    • dao层要建立起数据和对象的对应关系,这里要注意一点,对象的字段必须全部包装类型,包装类型的好处就是可以支持null字段,而且在对象的序列号与反序列化中,那些不能为null的基本类型,只能用0或""代替,在很多情况下,这是不合理的

其他ORM框架

  1. JPA和Hibernate

    • JPA是java实现数据库操作的一种规范,就像JDBC,而Hibernate是它的一种实现,就行MySQL驱动,但是Hibernate扩展了自己的方法,我们对比这些会方法,即使强大如spring,设计的接口也不一定是最好的,对比mp对条件查询的构造,我们会发现,接口的设计真的是一门艺术。
  2. 二级缓存,跨session缓存,这个建议最好自己实现,因为很容易导致数据不一致的问题,而且自己实现的更好一些,比如可以实现分布式共享缓存

  3. Mybatis

    JDBCMyBatis
    DataSourceSqlSessionFactory
    ConnectionSqlSession
    • 提一下以前没有用过的获取插入后数据库自增主键值
      • @Options(useGeneratedKeys = true, keyProperty = “id”, keyColumn = “id”)
    • 廖老师对mybatis的使用不是很好,建议自己反复研读官网的文档
    • mybatis让我们定义接口和xml,帮助我们实现这些接口,它最强大的地方在于,它的ResultMap和动态SQL
    • 如果我们的动态SQL存在很复杂的or和()嵌套的情况,动态SQL和mp的条件构造器哪个更好用,我不是很清楚,但是我觉得mp的可读性更好,或许我们应该学习一下,这些复杂的条件是如何构造的
  4. 自定义orm框架

    • 自己实现的orm
    • 廖老师的设计还是相当厉害的,有兴趣和时间的话,可以自己实现一下
      • 这里提一些自己的感悟
        • 链式编程能让你的代码更简单,更优雅
        • 其实SQL都是一个关键字,跟上几个关键字,比如where,比如limit,我们完全可以借助这个思想,弄一个支持多表查询的orm框架
        • 还是那句话,接口的设计,真的是一门艺术
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值