学习链接:https://www.liaoxuefeng.com/wiki/1252599548343744/1266265125480448

大部分内容来自此教程,以下只是我的学习笔记。

JdbcTemplate

Spring提供了一个JdbcTemplate,可以方便地让我们操作JDBC。

总结一下JdbcTemplate的用法,那就是:

  • 针对简单查询,优选query()queryForObject(),因为只需提供SQL语句、参数和RowMapper
  • 针对更新操作,优选update(),因为只需提供SQL语句和参数;
  • 任何复杂的操作,最终也可以通过execute(ConnectionCallback)实现,因为拿到Connection就可以做任何JDBC操作。

声明式事务

声明式事务无需手动写事务代码,实现步骤一般包括:

  1. AppConfig中追加一个上述定义的PlatformTransactionManager外,再加一个@EnableTransactionManagement就可以启用声明式事务
  2. 在需要事务的类或方法上,加@Transactional注解

实现原理:AOP代理

关于回滚

默认情况下:

  1. RuntimeException 默认触发回滚
  2. Checked Exception 需要在@Transactional注解中标注才会触发

为了简化代码,我们强烈建议业务异常体系从RuntimeException派生,这样就不必声明任何特殊异常即可让Spring的声明式事务正常工作

事务边界 和 事务传播

一个方法定义了事务注解后,一般事务的边界就是此方法的开始和结束之间。然而,若涉及到事务方法A嵌套调用事务方法B的情况,事务边界的定义就比较复杂了。此时需要引入事务传播的概念:事务传播定义了事务如何被传播和处理。一般有以下几种类型:

  1. REQUIRED(默认):如果当前存在事务,那么加入这个事务,否则创建一个新的事务。
  2. SUPPORTS:如果当前存在事务,那么加入这个事务,否则以非事务的方式执行。
  3. MANDATORY:如果当前存在事务,那么加入这个事务,否则抛出异常。
  4. REQUIRES_NEW:总是创建一个新的事务,如果当前存在事务,暂停当前事务。
  5. NOT_SUPPORTED:总是以非事务的方式执行操作,如果当前存在事务,就将其暂停。
  6. NEVER:总是以非事务方式执行,如果当前存在事务,则抛出异常。
  7. NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则其行为与 REQUIRED 一样。

以默认的REQUIRED类型为例,上面的例子中,事务B的事务会自动加入到事务A的事务中。

事务传播的原理:使用ThreadLocal。因此,事务能正确传播的前提是,方法调用是在一个线程内才行。

DAO

DAO:data access object

集成Hibernate

ORM (Object-Relational Mapping)

定义:关系数据库的表记录映射为Java对象的过程。Hibernate是一个成熟的ORM框架。

Hibernate定义

在Hibernate中,Session是封装了一个JDBC Connection的实例,而SessionFactory是封装了JDBC DataSource的实例,即SessionFactory持有连接池,每次需要操作数据库的时候,SessionFactory创建一个新的Session,相当于从连接池获取到一个新的ConnectionSessionFactory就是Hibernate提供的最核心的一个对象,但LocalSessionFactoryBean是Spring提供的为了让我们方便创建SessionFactory的类。

使用的注解

  1. @Entity 表示该类用于被映射
  2. @Table(name="users") 指定映射的表名,若和类名一致,也可以不指定
  3. @Id 标明是id字段 等等

使用

注意:使用Hibernate时,不要使用基本类型的属性,总是使用包装类型,如Long或Integer。

集成JPA(Java Persistence API)

JPA就是JavaEE的一个ORM标准,因为JPA只是接口,所以,还需要选择一个实现产品,跟JDBC接口和MySQL驱动一个道理。可以使用Hibernate,或者其他JPA提供方。

JDBC Hibernate JPA
DataSource SessionFactory EntityManagerFactory
Connection Session EntityManager

使用方法类似,不赘述

集成MyBatis

上面已经介绍了两种ORM实现方法,分别代表着两种ORM类型:

  • JdbcTemplate:非自动型
  • Hibernate:全自动型

其中,非自动型优势在于确定性,编写sql来实现,但是代码繁琐。全自动型最大限度地减少手动编写SQL语句的需要,同时自动处理对象与数据库记录之间的映射和同步。但在某些方面更加复杂,如理解JavaBean的生命周期、缓存的影响。

本小节引入了Mybatis的概念,它是属于半自动型的ORM方法。设计套路和其他ORM类型,对应的核心是SqlSessionFactorySqlSession。特点是sql需要手写,但是ORM转换是自动进行的。这样实现复杂的sql以及优化sql就更加灵活。

JDBC Hibernate JPA MyBatis
DataSource SessionFactory EntityManagerFactory SqlSessionFactory
Connection Session EntityManager SqlSession

实现细节:

  • 使用Mapper接口实现映射,可在Mapper类中通过注解写入sql
  • 也可在xml中写sql,可实现动态sql
  • 查询后,Mybatis会自动将ResultSet的每一行转换为User实例。转换的规则是匹配相同的变量名,如果对应的变量名不同的话,最简单的方法就是在select语句中使用别名。

代码示例:

1
2
3
4
public interface UserMapper {
	@Select("SELECT * FROM users WHERE id = #{id}")
	User getById(@Param("id") long id);
}

其中,占位符#{id}和参数定义@Param("id")是对应的。