学习链接:https://www.liaoxuefeng.com/wiki/1252599548343744/1266265125480448
大部分内容来自此教程,以下只是我的学习笔记。
JdbcTemplate
Spring提供了一个JdbcTemplate,可以方便地让我们操作JDBC。
总结一下
JdbcTemplate的用法,那就是:
- 针对简单查询,优选
query()和queryForObject(),因为只需提供SQL语句、参数和RowMapper;- 针对更新操作,优选
update(),因为只需提供SQL语句和参数;- 任何复杂的操作,最终也可以通过
execute(ConnectionCallback)实现,因为拿到Connection就可以做任何JDBC操作。
声明式事务
声明式事务无需手动写事务代码,实现步骤一般包括:
- 在
AppConfig中追加一个上述定义的PlatformTransactionManager外,再加一个@EnableTransactionManagement就可以启用声明式事务 - 在需要事务的类或方法上,加
@Transactional注解
实现原理:AOP代理
关于回滚
默认情况下:
- RuntimeException 默认触发回滚
- Checked Exception 需要在
@Transactional注解中标注才会触发
为了简化代码,我们强烈建议业务异常体系从
RuntimeException派生,这样就不必声明任何特殊异常即可让Spring的声明式事务正常工作
事务边界 和 事务传播
一个方法定义了事务注解后,一般事务的边界就是此方法的开始和结束之间。然而,若涉及到事务方法A嵌套调用事务方法B的情况,事务边界的定义就比较复杂了。此时需要引入事务传播的概念:事务传播定义了事务如何被传播和处理。一般有以下几种类型:
- REQUIRED(默认):如果当前存在事务,那么加入这个事务,否则创建一个新的事务。
- SUPPORTS:如果当前存在事务,那么加入这个事务,否则以非事务的方式执行。
- MANDATORY:如果当前存在事务,那么加入这个事务,否则抛出异常。
- REQUIRES_NEW:总是创建一个新的事务,如果当前存在事务,暂停当前事务。
- NOT_SUPPORTED:总是以非事务的方式执行操作,如果当前存在事务,就将其暂停。
- NEVER:总是以非事务方式执行,如果当前存在事务,则抛出异常。
- NESTED:如果当前存在事务,则在嵌套事务内执行。如果当前没有事务,则其行为与 REQUIRED 一样。
以默认的REQUIRED类型为例,上面的例子中,事务B的事务会自动加入到事务A的事务中。
事务传播的原理:使用ThreadLocal。因此,事务能正确传播的前提是,方法调用是在一个线程内才行。
DAO
DAO:data access object
集成Hibernate
ORM (Object-Relational Mapping)
定义:关系数据库的表记录映射为Java对象的过程。Hibernate是一个成熟的ORM框架。
Hibernate定义
在Hibernate中,
Session是封装了一个JDBCConnection的实例,而SessionFactory是封装了JDBCDataSource的实例,即SessionFactory持有连接池,每次需要操作数据库的时候,SessionFactory创建一个新的Session,相当于从连接池获取到一个新的Connection。SessionFactory就是Hibernate提供的最核心的一个对象,但LocalSessionFactoryBean是Spring提供的为了让我们方便创建SessionFactory的类。
使用的注解
@Entity表示该类用于被映射@Table(name="users")指定映射的表名,若和类名一致,也可以不指定@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类型,对应的核心是SqlSessionFactory和SqlSession。特点是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语句中使用别名。
代码示例:
|
|
其中,占位符#{id}和参数定义@Param("id")是对应的。