zoukankan      html  css  js  c++  java
  • JPA && Spring Data && Spring Data JPA

    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的时候就不报错了。

  • 相关阅读:
    java 命令
    测试事件响应修改界面内容
    ASP.NET MVC 解决账号重复登录问题
    Redis 安装
    js返回页面顶部
    Brackets 前端编辑器推荐
    一点点............
    响应式——em,rem,px
    新知识——响应式
    面试心得
  • 原文地址:https://www.cnblogs.com/mingziday/p/4769988.html
Copyright © 2011-2022 走看看