加入收藏 | 设为首页 | 会员中心 | 我要投稿 安卓应用网 (https://www.0791zz.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

spring data简化jpa开发_动力节点Java学院整理

发布时间:2020-05-29 14:07:36 所属栏目:Java 来源:互联网
导读:从一个简单的JPA示例开始本文主要讲述SpringDataJPA,但是为了不至于给JPA和Spring的初学者造成较大的学习曲线,我们首先从JPA开始,简单介绍一个JPA示例;接着重构该示例,并引入Spring框架,这两部分不会涉及过多

从一个简单的 JPA 示例开始

本文主要讲述 Spring Data JPA,但是为了不至于给 JPA 和 Spring 的初学者造成较大的学习曲线,我们首先从 JPA 开始,简单介绍一个 JPA 示例;接着重构该示例,并引入 Spring 框架,这两部分不会涉及过多的篇幅,如果希望能够深入学习 Spring 和 JPA,可以根据本文最后提供的参考资料进一步学习。

自 JPA 伴随 Java EE 5 发布以来,受到了各大厂商及开源社区的追捧,各种商用的和开源的 JPA 框架如雨后春笋般出现,为开发者提供了丰富的选择。它一改之前 EJB 2.x 中实体 Bean 笨重且难以使用的形象,充分吸收了在开源社区已经相对成熟的 ORM 思想。另外,它并不依赖于 EJB 容器,可以作为一个独立的持久层技术而存在。目前比较成熟的 JPA 框架主要包括 Jboss 的 Hibernate EntityManager、Oracle 捐献给 Eclipse 社区的 EclipseLink、Apache 的 OpenJPA 等。

本文的示例代码基于 Hibernate EntityManager 开发,但是读者几乎不用修改任何代码,便可以非常容易地切换到其他 JPA 框架,因为代码中使用到的都是 JPA 规范提供的接口 / 类,并没有使用到框架本身的私有特性。示例主要涉及七个文件,但是很清晰:业务层包含一个接口和一个实现;持久层包含一个接口、一个实现、一个实体类;另外加上一个 JPA 配置文件和一个测试类。相关类 / 接口代码如下:

清单 1. 实体类 AccountInfo.java

 @Entity 
 @Table(name = "t_accountinfo") 
 public class AccountInfo implements Serializable { 
 private Long accountId; 
 private Integer balance; 

 // 此处省略 getter 和 setter 方法。
 }

清单 2. 业务层接口 UserService.java

 public interface UserService { 
 public AccountInfo createNewAccount(String user,String pwd,Integer init); 
 }

清单 3. 业务层的实现类 UserServiceImpl.java

 public class UserServiceImpl implements UserService { 

 private UserDao userDao = new UserDaoImpl(); 

 public AccountInfo createNewAccount(String user,Integer init){ 
 // 封装域对象
 AccountInfo accountInfo = new AccountInfo(); 
 UserInfo userInfo = new UserInfo(); 
 userInfo.setUsername(username); 
 userInfo.setPassword(password); 
 accountInfo.setBalance(initBalance); 
 accountInfo.setUserInfo(userInfo); 
 // 调用持久层,完成数据的保存
 return userDao.save(accountInfo); 
  } 
 }

清单 4. 持久层接口

 public interface UserDao { 
 public AccountInfo save(AccountInfo accountInfo); 
 }

清单 5. 持久层的实现类

 public class UserDaoImpl implements UserDao { 
 public AccountInfo save(AccountInfo accountInfo) { 
 EntityManagerFactory emf = 
 Persistence.createEntityManagerFactory("SimplePU"); 
 EntityManager em = emf.createEntityManager(); 
 em.getTransaction().begin(); 
 em.persist(accountInfo); 
 em.getTransaction().commit(); 
 emf.close(); 
 return accountInfo; 
  } 
 }

清单 6. JPA 标准配置文件 persistence.xml 

<?xml version="1.0" encoding="UTF-8"?> 
 <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> 
 <persistence-unit name="SimplePU" transaction-type="RESOURCE_LOCAL"> 
 <provider>org.hibernate.ejb.HibernatePersistence</provider> 
 <class>footmark.springdata.jpa.domain.UserInfo</class> 
 <class>footmark.springdata.jpa.domain.AccountInfo</class> 
 <properties> 
 <property name="hibernate.connection.driver_class"
 value="com.mysql.jdbc.Driver"/> 
 <property name="hibernate.connection.url" 
 value="jdbc:mysql://10.40.74.197:3306/zhangjp"/> 
 <property name="hibernate.connection.username" value="root"/> 
 <property name="hibernate.connection.password" value="root"/> 
 <property name="hibernate.dialect"
 value="org.hibernate.dialect.MySQL5Dialect"/> 
 <property name="hibernate.show_sql" value="true"/> 
 <property name="hibernate.format_sql" value="true"/> 
 <property name="hibernate.use_sql_comments" value="false"/> 
 <property name="hibernate.hbm2ddl.auto" value="update"/> 
 </properties> 
 </persistence-unit> 
 </persistence>

清单 7. 本文使用如下的 main 方法进行开发者测试

 public class SimpleSpringJpaDemo { 
  public static void main(String[] args) { 
    new UserServiceImpl().createNewAccount("ZhangJianPing","123456",1); 
  } 
 }

简述 Spring 框架对 JPA 的支持

接下来我们引入 Spring,以展示 Spring 框架对 JPA 的支持。业务层接口 UserService 保持不变,UserServiceImpl 中增加了三个注解,以让 Spring 完成依赖注入,因此不再需要使用 new 操作符创建 UserDaoImpl 对象了。同时我们还使用了 Spring 的声明式事务:

清单 8. 配置为 Spring Bean 的业务层实现

 @Service("userService") 
 public class UserServiceImpl implements UserService { 
 @Autowired 
 private UserDao userDao; 

 @Transactional 
 public AccountInfo createNewAccount( 
 String name,Integer init) { …… } 
 }

对于持久层,UserDao 接口也不需要修改,只需修改 UserDaoImpl 实现,修改后的代码如下:

清单 9. 配置为 Spring Bean 的持久层实现

 @Repository("userDao") 
 public class UserDaoImpl implements UserDao { 

 @PersistenceContext 
 private EntityManager em; 

 @Transactional 
  public Long save(AccountInfo accountInfo) { 
 em.persist(accountInfo); 
 return accountInfo.getAccountId(); 
 } 
 }

清单 10. Spring 配置文件

 <?xml version="1.0" encoding="UTF-8"?> 
 <beans...> 
 <context:component-scan base-package="footmark.springdata.jpa"/> 
 <tx:annotation-driven transaction-manager="transactionManager"/> 
 <bean id="transactionManager" 
 class="org.springframework.orm.jpa.JpaTransactionManager"> 
 <property name="entityManagerFactory" ref="entityManagerFactory"/> 
 </bean> 
 <bean id="entityManagerFactory" class= 
"org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
  </bean> 
 </beans>

清单 11. 改造后的基于 Spring 的开发者测试代码

 public class SimpleSpringJpaDemo{ 
 public static void main(String[] args){ 
 ClassPathXmlApplicationContext ctx = 
 new ClassPathXmlApplicationContext("spring-demo-cfg.xml"); 
 UserDao userDao = ctx.getBean("userDao",UserDao.class); 
 userDao.createNewAccount("ZhangJianPing",1); 
 } 
 }

通过对比重构前后的代码,可以发现 Spring 对 JPA 的简化已经非常出色了,我们可以大致总结一下 Spring 框架对 JPA 提供的支持主要体现在如下几个方面:

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

其次,Spring 实现了部分在 EJB 容器环境下才具有的功能,比如对 @PersistenceContext、@PersistenceUnit 的容器注入支持。

第三,也是最具意义的,Spring 将 EntityManager 的创建与销毁、事务管理等代码抽取出来,并由其统一管理,开发者不需要关心这些,如前面的代码所示,业务方法中只剩下操作领域对象的代码,事务管理和 EntityManager 创建、销毁的代码都不再需要开发者关心了。

更进一步:Spring Data JPA 让一切近乎完美

通过前面的分析可以看出,Spring 对 JPA 的支持已经非常强大,开发者只需关心核心业务逻辑的实现代码,无需过多关注 EntityManager 的创建、事务处理等 JPA 相关的处理,这基本上也是作为一个开发框架而言所能做到的极限了。然而,Spring 开发小组并没有止步,他们再接再厉,于最近推出了 Spring Data JPA 框架,主要针对的就是 Spring 唯一没有简化到的业务逻辑代码,至此,开发者连仅剩的实现持久层业务逻辑的工作都省了,唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!

至此,读者可能会存在一个疑问,框架怎么可能代替开发者实现业务逻辑呢?毕竟,每一个应用的持久层业务甚至领域对象都不尽相同,框架是怎么做到的呢?其实这背后的思想并不复杂,比如,当你看到 UserDao.findUserById() 这样一个方法声明,大致应该能判断出这是根据给定条件的 ID 查询出满足条件的 User 对象。Spring Data JPA 做的便是规范方法的名字,根据符合规范的名字来确定方法需要实现什么样的逻辑。

(编辑:安卓应用网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读