1、JPA 

Java Persistence API,用于对象持久化的一组API,JPA本身是一组规范,让开发者用同一种方式访问不同的ORM框架。其实也就是java实体对象和关系型数据库建立起映射关系,通过面向对象编程的思想操作关系型数据库的规范。因此各种ORM框架都会提供满足JPA要求的实现。在Spring项目中,ORM框架最常使用的就是Hibernate,Hibernate EntityManager就是JPA的一种provider。

2、Spring Data

尽管我们可以通过JPA规范访问不同的ORM框架了,但是开发过这种访问ORM的代码,需要资源获取、Statement创建、异常处理、资源释放等一套繁琐和重复的流程。Spring 框架对 JPA 提供的支持主要体现在如下几个方面:

  • 首先,它使得 JPA 配置变得更加灵活。JPA 规范要求,配置文件必须命名为 persistence.xml,并存在于类路径下的 META-INF 目录中。该文件通常包含了初始化 JPA 引擎所需的全部信息。Spring 提供的 LocalContainerEntityManagerFactoryBean 提供了非常灵活的配置,persistence.xml 中的信息都可以在此以属性注入的方式提供。

  • 其次,Spring 实现了部分在 EJB 容器环境下才具有的功能,比如对 @PersistenceContext、@PersistenceUnit 的容器注入支持。
  • 第三,也是最具意义的,Spring 将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,开发者不需要关心这些,业务方法中只剩下操作领域对象的代码,事务管理和 EntityManager 创建、销毁的代码都不再需要开发者关心了。

2、Spring Data JPA

Spring Data JPA 框架,主要针对的就是 Spring 唯一没有简化到的业务逻辑代码,至此,开发者连仅剩的实现持久层业务逻辑的工作都省了,唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成。

该项目的使用指导在这里http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/reference/html/

3.1 Spring Data JPA核心数据层接口

下面这张图来自http://blog.csdn.net/chszs/article/details/42737553,描述了核心接口的关系,其中Spring Data Commons是一个Spirng Data的基础组件,Spring Data JPA需要该组件提供的服务。

1:Repository:最顶层的接口,是一个空的接口,目的是为了统一所有Repository的类型,且能让组件扫描的时候自动识别。
2:CrudRepository :是Repository的子接口,提供CRUD的功能
3:PagingAndSortingRepository:是CrudRepository的子接口,添加分页和排序的功能
4:JpaRepository:是PagingAndSortingRepository的子接口,增加了一些实用的功能,比如:批量操作等。
5:JpaSpecificationExecutor:用来做负责查询的接口
6:Specification:是Spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可

这些接口提供的方法,在Spring Data JPA官方文档中描述的非常全面,地址在这里 http://docs.spring.io/spring-data/jpa/docs/1.9.0.RELEASE/api/

插播一下我遇到的一个问题

我用getOne(1)在获取单个实体的内容的时候,系统报错,org.hibernate.LazyInitializationException: could not initialize proxy - no Session

而我用findOne(1)替换getOne(1),就很正常,于是我上google搜了一下findOne和getOne的区别,大概是下面这样

The basic difference is that getOne is lazy loaded and findOne is not

据说可以用OpenEntityManagerInViewFilter过滤器来解决,我现在还没有试

3.2 JpaRepository的查询

直接在接口中定义查询方法,如果是符合规范的,可以不用写实现,目前支持的关键字如下:

  • And --- 等价于 SQL 中的 and 关键字,比如 findByUsernameAndPassword(String user, Striang pwd);
  • Or --- 等价于 SQL 中的 or 关键字,比如 findByUsernameOrAddress(String user, String addr);
  • Between --- 等价于 SQL 中的 between 关键字,比如 findBySalaryBetween(int max, int min);
  • LessThan --- 等价于 SQL 中的 "<",比如 findBySalaryLessThan(int max);
  • GreaterThan --- 等价于 SQL 中的">",比如 findBySalaryGreaterThan(int min);
  • IsNull --- 等价于 SQL 中的 "is null",比如 findByUsernameIsNull();
  • IsNotNull --- 等价于 SQL 中的 "is not null",比如 findByUsernameIsNotNull();
  • NotNull --- 与 IsNotNull 等价;
  • Like --- 等价于 SQL 中的 "like",比如 findByUsernameLike(String user);
  • NotLike --- 等价于 SQL 中的 "not like",比如 findByUsernameNotLike(String user);
  • OrderBy --- 等价于 SQL 中的 "order by",比如 findByUsernameOrderBySalaryAsc(String user);
  • Not --- 等价于 SQL 中的 "! =",比如 findByUsernameNot(String user);
  • In --- 等价于 SQL 中的 "in",比如 findByUsernameIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数;
  • NotIn --- 等价于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection<String> userList) ,方法的参数可以是 Collection 类型,也可以是数组或者不定长参数

3.3 JPA的NamedQueries

3.4 使用@Query

参考资料

http://sishu ok.com/forum/posts/list/7000.html

http://www.cnblogs.com/WangJinYang/p/4257383.html


1、对存储大数据的LOB类型,JPA只要在Entiry中注解@LOB即可

LOB 代表大对象数据,包括 BLOB 和 CLOB 两种类型,前者用于存储大块的二进制数据,如图片数据,视频数据等,而后者用于存储长文本数据,如论坛的帖子内容,产品的详细描述等。

值得注意的是:在不同的数据库中,大对象对应的字段类型是不尽相同的,如 DB2 对应 BLOB/CLOB,MySql 对应 BLOB/LONGTEXT,SqlServer 对应 IMAGE/TEXT。

需要指出的是,有些数据库的大对象类型可以象简单类型一样访问,如 MySql 的 LONGTEXT 的操作方式和 VARCHAR 类型一样。在一般情况下, LOB 类型数据的访问方式不同于其它简单类型的数据,我们经常会以流的方式操作 LOB 类型的数据。此外,LOB 类型数据的访问不是线程安全的,需要为其单独分配相应的数据库资源,并在操作完成后释放资源。

(参考:http://www.ibm.com/developerworks/cn/java/j-lo-spring-lob/)

2、我在save/update COB类型的数据时,c3p0连接池报错:

java.lang.AbstractMethodError: com.mchange.v2.c3p0.impl.NewProxyPreparedStatement.setCharacterStream(ILjava/io/Reader;J)V

上网查找资料,发现是0.9.1.2版本的c3p0中没有setCharacterStream方法,于是下载c3p0-0.9.5.1.jar,放到本地资源库,下次update/save的时候就不报错了。

最新文章

  1. ssh 使用
  2. jquery取值
  3. mysql replace
  4. sqlite创建表
  5. Android环境配置Sencha Touch
  6. 10 Best TV Series Based On Hacking And Technology
  7. 关于cocos2dx手游lua文件加密的解决方式
  8. mysql查询数据库中包含某字段(列名)的所有表
  9. 【日常】C++ 的那些“坑” —— delete 与 析构函数 与 virtual 的 9 个小例子
  10. Android 图片加载框架Picasso基本使用和源码完全解析(巨细无比)
  11. HDU2063-过山车-匈牙利算法
  12. Android常见Crash原因总结(二)
  13. linux中的网络通信指令
  14. css颜色,字体大小的设置
  15. python 基础知识点一
  16. python基础循环
  17. JSONObject基本内容(二)
  18. Alpha测试
  19. public class的类名必须跟文件名保持一致吗?
  20. Unreal Engine 4(虚幻UE4)GameplayAbilities 插件入门教程(二)

热门文章

  1. Android数据的四种存储方式之SQLite数据库
  2. 怎样破解邮箱password
  3. js中常用属性备忘
  4. 模式匹配运算符&ndash;Shell
  5. JavaScript与FileSystemObject
  6. 计算 MD5值
  7. LeetCode 278
  8. ip 子网掩码 网关 DNS
  9. 关于XShell的常见使用和设置以及Linux中的常见命令.
  10. sqlserver和oracle中对全半角的转换