1 spring mybatis 配置事务管理:
<bean id="datasource" class="com.movikr.svc.order.core.spring.MyDruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="#{jdbc_properties[‘jdbc.order.url‘]}" />
<property name="username" value="#{jdbc_properties[‘jdbc.order.username‘]}" />
<property name="password" >
<bean class="com.movikr.v2.core.utils.EncyptorUtils"
factory-method="decrypt">
<constructor-arg value="#{jdbc_properties[‘jdbc.order.password‘]}"/>
</bean>
</property>
<property name="defaultAutoCommit" value="false" />
<property name="driverClassName" value="#{jdbc_properties[‘jdbc.driver‘]}" /><!-- 数据源驱动类可不写,Druid默认会自动根据URL识别DriverClass -->
<property name="initialSize" value="10" /><!-- 配置初始化大小、最小、最大 -->
<property name="minIdle" value="10" />
<property name="maxActive" value="100" />
<property name="maxWait" value="60000" /><!-- 配置获取连接等待超时的时间 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" /><!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" /><!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="validationQuery" value="SELECT ‘x‘" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
</bean>
<bean name="sqlSessionFactory" id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:mapper/**/*.xml"/>
<property name="plugins">
<array>
<bean class="com.github.pagehelper.PageHelper">
<property name="properties">
<value>
dialect=mysql
pageSizeZero=true
reasonable=true
</value>
</property>
</bean>
</array>
</property>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.movikr.svc.order.dao" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
<qualifier value="java"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
<context:annotation-config />
<context:component-scan base-package="com.movikr.svc.order.service" />
<context:component-scan base-package="com.movikr.svc.order.dao" />
<context:component-scan base-package="com.movikr.svc.order.util" />
<context:component-scan base-package="com.movikr.svc.order.task" />
java dao 层:
@Repository("mapperOrderActivity")
public interface MapperEntityOrderActivity {
public void addList(List<EntityOrderActivity> list);
public List<EntityOrderActivity> getByOrderId(String orderId);
}
mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.movikr.svc.order.dao.order.MapperEntityOrderActivity">
<resultMap type="com.movikr.v2.core.entitys.order.EntityOrderActivity"
id="EntityOrderActivityMap">
<result column="id" property="id" />
<result column="order_id" property="orderId" />
<result column="activity_id" property="activityId" />
<result column="relation_id" property="activityResourceRelationId" />
<result column="create_date" property="createDate" />
</resultMap>
<sql id="template">
id,
order_id,
activity_id,
relation_id,
create_date
</sql>
<insert id="addList" parameterType="java.util.List">
<selectKey resultType ="java.lang.Long" keyProperty= "id"
order= "AFTER">
SELECT LAST_INSERT_ID()
</selectKey >
insert into `t_entity_order_activity`(
<include refid="template" />
)values
<foreach collection ="list" item="activity" index= "index" separator =",">
(
#{activity.id},
#{activity.orderId},
#{activity.activityId},
#{activity.activityResourceRelationId},
#{activity.createDate}
)
</foreach >
</insert>
<update id="update" parameterType="Map">
update `t_entity_order_activity` set
id = #{id},
order_id = #{orderId},
activity_id = #{activityId},
relation_id = #{activityResourceRelationId},
create_date = #{createDate}
</update>
<select id="get" parameterType="Map"
resultMap="EntityOrderActivityMap">
select
<include refid="template" />
from
`t_entity_order_activity`
</select>
<select id="getByOrderId" parameterType="Map"
resultMap="EntityOrderActivityMap">
select
<include refid="template" />
from
`t_entity_order_activity`
where order_id=#{orderId}
</select>
</mapper>
2 spring hibernate 配置:
- <!-- 配置数据源 -->
- <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource" >
- <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
- <property name="url" value="jdbc:mysql://localhost/test_ssh"></property>
- <property name="username" value="root"></property>
- <property name="password" value="1"></property>
- </bean>
- <!-- 配置一个事务管理器 -->
- <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <property name="sessionFactory" ref="sessionFactory" /> </bean>
- <tx:annotation-driven transaction-manager="transactionManager"></tx:annotation-driven>
<context:annotation-config />
<context:component-scan base-package="com.movikr.svc.order.service" />
<context:component-scan base-package="com.movikr.svc.order.dao" />
<context:component-scan base-package="com.movikr.svc.order.util" />
<context:component-scan base-package="com.movikr.svc.order.task" />
spring 和hibernate 结合,如果使用hibernateTemplate 和session factory
http://azrael6619.iteye.com/blog/411215
3 spring 和 jdbc 配置
- <!-- 配置数据源 -->
- <bean class="org.apache.commons.dbcp.BasicDataSource"
- destroy-method="close"
- name="MydataSource">
- <property name="driverClassName">
- <value>oracle.jdbc.driver.OracleDriver</value>
- </property>
- <property name="url">
- <value>jdbc:oracle:thin:@localhost:1521:xe</value>
- </property>
- <property name="username">
- <value>abcuser</value>
- </property>
- <property name="password">
- <value>123456</value>
- </property>
- </bean>
- <!-- 在jdbcTemplate模板中注入数据源 -->
- <bean name="jdbcTemelate" class="org.springframework.jdbc.core.JdbcTemplate">
- <property name="dataSource" ref="MydataSource"></property>
- </bean>
- <!-- 配置事务管理器 -->
- <bean name="tranManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
- <property name="dataSource" ref="MydataSource"></property>
- </bean>
- <!-- 配置事务拦截器 -->
- <bean name="tranInterceptor" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
- <property name="transactionManager" ref="tranManager"></property>
- <property name="transactionAttributes">
- <props>
- <!-- 事务传播属性,事务隔离级别, 方法属性值,控制提交回滚操作 (+Exception强制提交,-Exception回滚)-->
- <!-- <prop key="*">PROPAGATION_REQUIRED,,,</prop> -->
- <prop key="*">PROPAGATION_REQUIRED</prop>
- </props>
- </property>
- <property name="target" ref="service"></property>
- </bean>
- <!-- 配置dao层 -->
- <bean name="jdbcDao" class="com.sjdbc.dao.impl.JdbcTemplateDaoImpl">
- <property name="jdbcTemplate" ref="jdbcTemelate"></property>
- </bean>
- <!-- 配置service层 -->
- <bean name="service" class="com.sjdbc.service.impl.UserServiceImpl">
- <property name="dao" ref="jdbcDao"></property>
- </bean>
- </beans>
- public class JdbcTemplateDaoImpl implements UserDao{
- private JdbcTemplate jdbcTemplate;
- public JdbcTemplate getJdbcTemplate() {
- return jdbcTemplate;
- }
- public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
- this.jdbcTemplate = jdbcTemplate;
- }
- public void saveOrUpdate(User user) throws Exception {
- // TODO Auto-generated method stub
- // String sql="insert into user values("+user.getId()+",‘"+user.getName()+"‘)";
- // jdbcTemplate.execute(sql);
- String sql="insert into users values(?,?)";
- jdbcTemplate.update(sql,new Object[]{user.getId(),user.getName()});
- }
- public User findByName(String name) throws Exception {
- // TODO Auto-generated method stub
- return null;
- }
- public void deleteUser(User user) throws Exception {
- // TODO Auto-generated method stub
- String sql="delete from users where id="+user.getId();
- throw new RuntimeException("删除失败");
- // jdbcTemplate.execute(sql);
- }
- }
4 spring 和jpa
JPA全称Java Persistence API,即Java持久化API,它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据,结合其他ORM的使用,能达到简化开发流程的目的,使开发者能够专注于实现自己的业务逻辑上。
Spring Jpa 能够简化创建 JPA 数据访问层和跨存储的持久层功能,用户的持久层Dao接口只需要继承他自己定义好的(仓库)接口,无需再写实现类,就可以实现对象的CRUD操作,还有分页排序等功能。
spring-jpa.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:task="http://www.springframework.org/schema/task"
xmlns:aop="http://www.springframework.org/schema/aop"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"
default-lazy-init="true">
<description>SpringJpa配置</description>
<!-- 如果spring用了jpa,并且类型为LocalContainerEntityManagerFactoryBean,则组件注册在此配置文件出现即可,其余配置文件可忽略
使用component来替代annotation 自动注册bean, 并保证@Required、@Autowired的属性被注入\ -->
<context:component-scan base-package="com.spring.jpa"/>
<!-- spring启动时扫描项目路径下的properties文件,后续用${key }方式取出对应值,这样可以代码解耦和,后续只需修改properties文件即可 -->
<bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- dataSourse连接池相关属性,代码不在此贴出,会放在打包好的项目里面 -->
<value>classpath:db.properties</value>
</list>
</property>
</bean>
<!-- 定义实体管理器工厂
Jpa配置 LocalContainerEntityManagerFactoryBean这个选项Spring扮演了容器的角色。完全掌管JPA -->
点我查看 spring生成EntityManagerFactory的三种方式
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!-- 指定数据源 -->
<property name="dataSource" ref="dataSource"/>
<!-- 指定Jpa持久化实现厂商类,这里以Hibernate为例 -->
<property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
<!-- 指定Entity实体类包路径 -->
<property name="packagesToScan" >
<array>
<value>com.spring.jpa</value>
</array>
</property>
<!-- 指定JPA属性;如Hibernate中指定是否显示SQL的是否显示、方言等 -->
<property name="jpaProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">validate</prop>
</props>
</property>
</bean>
<!-- 重要配置:启用扫描并自动创建代理的功能 -->
<jpa:repositories base-package="com.spring.jpa" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
<!-- Hibernate对Jpa的实现 -->
<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
<!-- Jpa 事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<!-- 开启注解事务 -->
<tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />
<!-- 数据源配置,使用应用内的DBCP数据库连接池 -->
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<!--property name="driverClassName" value="${db.driverClass}"/-->
<property name="url" value="${db.jdbcUrl}" />
<property name="username" value="${db.user}" />
<property name="password" value="${db.password}" />
<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="${db.initialSize}" />
<property name="minIdle" value="${db.minIdle}" />
<property name="maxActive" value="${db.maxActive}" />
<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="${db.maxWait}" />
<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="${db.timeBetweenEvictionRunsMillis}" />
<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="${db.minEvictableIdleTimeMillis}" />
<property name="validationQuery" value="SELECT ‘x‘ from dual" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />
<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="${db.poolPreparedStatements}" />
<property name="maxPoolPreparedStatementPerConnectionSize" value="${db.maxPoolPreparedStatementPerConnectionSize}" />
</bean>
<!-- 启动对@AspectJ(面向切面)注解的支持 -->
<aop:aspectj-autoproxy />
</beans>
配置好了配置文件后,我们该来写对应的实体类,Dao,和service了,下面给出简单的3个类:
User 实体类
package com.spring.jpa.user;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;
/**
* User实体类
* @author liuyt
* @date 2014-10-30 下午2:27:37
*/
@Entity
@Table(name="T_SPRINGJPA_USER")
public class User {
/**
* 主键序列:DEFAULT_SUQUENCE 是我在oracle数据库中创建的一个序列
* MY_SUQUENCE 是给自定义的序列创建一个引用名称
* 指我的主键生成策略 MY_SUQUENCE 使用的是 DEFAULT_SUQUENCE 这个序列。
*/
@SequenceGenerator(name = "MY_SUQUENCE", sequenceName = "DEFAULT_SUQUENCE")
@Id
@GeneratedValue(generator="MY_SUQUENCE")
private Long id;
@Column(name="USER_NAME")
private String userName;
@Column(name="USER_PASSWORD")
private String passWord;
/*************GET****************SET***************/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
@Override
public String toString() {
return "User [id=" + id + ", userName=" + userName + ", passWord="
+ passWord + "]";
}
}
IUserDao 持久层(jpa对持久层简化的核心基础)
package com.spring.jpa.user;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
/**
* 持久层接口
* @author liuyt
* @date 2014-10-30 下午2:09:48
*/
@Repository
public interface IUserDao extends PagingAndSortingRepository<User, Long>{
/**
* 通过前面的配置可以看出,Spring 对 JPA 的支持已经非常强大,开发者无需过多关注 EntityManager 的创建、事务处理等 JPA 相关的处理
* ***********************************************************************
* 然而spring对Jpa的支持不止于此,它要从根本上来简化我们的业务代码 **
* 在没用使用jpa支持的时候,我们的代码应该是这样的: **
* 1、IUserDao 持久层接口 **
* 2、IUserDaoImpl 持久层实现类 **
* 3、IUserService 业务层接口.....后面不在列举 **
* 每写一个实体类,都要衍生出5、6个类来对他进行操作,即使有了注解,我们可以依赖注入方式来拿到实现类, **
* 但是通用的CRUD等操作却不免在每个实现类里声明,你又说,我可以定义一个父类,利用泛型反射原理就可以了, **
* 但那样你还需要为每个Dao声明自己的实现类来继承你的父类 **
* ***********************************************************************
* 那么问题来了...(不是挖掘机技术)对持久层的简化技术哪家强? Spring Data Jpa **
* 你唯一要做的就只是声明持久层的接口,来继承他自身已经封装好的持久层接口,正如本类IUserDao一样 **
* 可使用的接口有: **********
* Repository:是 Spring Data的一个核心接口,它不提供任何方法,开发者需要在自己定义的接口中声明需要的方法。**
* CrudRepository:继承Repository,提供增删改查方法,可以直接调用。 **
* PagingAndSortingRepository:继承CrudRepository,具有分页查询和排序功能(本类实例) **
* JpaRepository: 继承PagingAndSortingRepository,针对JPA技术提供的接口 **
* JpaSpecificationExecutor: 可以执行原生SQL查询 **
* 继承不同的接口,有两个不同的泛型参数,他们是该持久层操作的类对象和主键类型。 **
*********************************************************************************
*/
}
这里为了方便演示,就不写业务层接口了,直接上业务层service代码
UserService 业务层
package com.spring.jpa.user;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
/**
* User业务层,依赖持久层 IUserDao
* @author liuyt
* @date 2014-10-30 下午2:37:21
*/
@Service
public class UserService {
// 推荐用Resource来替代AutoWrite注解
@Resource
private IUserDao userDao;
// 新增用户
public void saveUser(User user) {
userDao.save(user);
}
// 删除用户,参数也可以为一个含有id的User对象
public void deleteUser(Long id) {
userDao.delete(id);
}
// 查询所有user对象,findOne为查询单个
public List<User> findAllUsers() {
return (List<User>) userDao.findAll();
}
/**
* 根据一个分页对象查询user集合(还可以添加一个Store排序属性)
* PageRequest 是spring自己封装的请求分页类,实现了Pageable接口,包涵从请求中获得的分页属性(当前页和大小)和获取方法
* 通过调用分页方法,返回一个Page<>一个泛型集合的分页对象,里面包涵了通过查询计算出的各个属性和结果集
* 详细类结构和属性请参阅源码
* @param page
* @return
*/
public Page<User> findAllUserByPage(PageRequest page) {
return (Page<User>) userDao.findAll(page);
}
}
比较持久化技术
现在你已经分析了三种不同的持久化机制及其运作方式。这些框架中的每一种都有自己的优点和缺点。让我们来考虑几个参数,这些参数可帮助你确定其中满足你需求的最佳可行方案。
简易性
在许多应用的开发中,时间是主要的制约因素,特别是当团队成员需要经培训来使用某种特定框架的时候。在这类情形中,iBATIS是最好的选择,该框架是三种框架中最简单的,因为它仅需SQL方面的知识就够了。
完整的ORM解决方案
像Hibernate和JPA一类的传统的ORM解决方案应该用来作为一种完全的对象-关系映射手段。Hibernate和JPA直接把Java对象映射到数据库表上,而iBATIS则是把Java对象映射到SQL查询的结果上。在某些应用中,领域模型中的对象是根据业务逻辑来设计的,可能不完全与数据模型匹配,在这种情况下,iBATIS是合适的选择。
对SQL的依赖
总是会存在精通Java的人和更信任SQL的人这样的一种划分,对于一个熟练的Java程序员来说,他想使用一个无需与SQL有太多交互的持久性框架,那么Hibernate是最好的选择,因为它会在运行时生成高效率的SQL查询。但是,如果你想要使用存储过程来对数据库查询做各方面的控制的话,则iBATIS是推荐的解决方案。JPA还可通过EntityManager的createNativeQuery()方法来支持SQL。
支持的查询语言
iBATIS大力支持SQL,而Hibernate和JPA则是使用它们自己的查询语言(分别是HQL和JPQL),这些语言与SQL类似。
性能
一个应用要成功的话需要具备良好的性能。Hibernate通过提供缓存设施来提高性能,这些缓存设施有助于更快地从数据库中检索数据。iBATIS使用SQL查询,这些查询可通过微调来获得更佳性能。JPA的性能则取决于供应商的实现,根据每个应用的特有情况做选择。
跨不同数据库的移植性
有时候,你需要改变应用使用的关系数据库,如果你使用Hibernate来作为持久化解决方案的话,那么这一问题很容易解决,因为Hibernate在配置文件中使用了一个数据库方言属性。从一个数据库移植到另一个数据库上仅是把dialect属性修改成适当值的事。Hibernate使用这一属性来作为生成特定于某种给定数据库的SQL代码的指南。
如前所述,iBATIS要求你编写自己的SQL代码,因此,iBATIS应用的可移植性取决于这些SQL。如果查询是使用可移植的SQL编写的话,那么iBATIS也是可在不同的关系数据库之间做移植的。另一方面,JPA的移植性则取决于其正在使用的供应商实现。JPA是可在不同的实现之间做移植的,比如Hibernate和TopLink
Essentials之间。因此,如果应用没有用到某些提供商特有的功能特性的话,那么移植性就不是什么大问题。
社区支持和文档
在这方面,Hibernate明显是个赢家。存在许多以Hibernate为焦点的论坛,在这些论坛中社区成员都会积极地回答各种问题。关于这一点,iBATIS和JPA正慢慢赶上。
跨非Java平台的移植性
iBATIS支持.Net和Ruby on Rails。Hibernate以NHibernate的形式为.Net提供了一个持久性解决方案。JPA,作为特定于Java的API,显然并不支持任何的非Java平台。
表1给出了这一比较的一个总结。
表1. 持久性解决方案比较
特性 |
iBATIS |
Hibernate |
JPA |
简易性 |
优 |
良 |
良 |
完整的ORM解决方案 |
一般 |
优 |
优 |
对数据模型改变的适应性 |
良 |
一般 |
一般 |
复杂性 |
优 |
一般 |
一般 |
对SQL的依赖 |
良 |
一般 |
一般 |
性能 |
优 |
优 |
不适用* |
跨不同关系数据库的移植性 |
一般 |
优 |
不适用* |
非Java平台的移植性 |
优 |
良 |
不支持 |
社区支持和文档 |
一般 |
良 |
良 |
*JPA对这些特性的支持取决于持久性提供程序,最终的结果可能会视情况各异。
结论
iBATIS、Hibernate和JPA是用于把数据持久到关系数据库中的三种不同的机制,每种都有着自己的优势和局限性。iBATIS不提供完整的ORM解决方案,也不提供任何的对象和关系模型的直接映射。不过,iBATIS给你提供了对查询的全面控制权。Hibernate提供了一个完整的ORM解决方案,但不提供对查询的控制权。Hibernate非常的受欢迎,有一个庞大而活跃的社区为新用户提供支持。JPA也提供一个完整的ORM解决方案,并提供对诸如继承和多态一类的面向对象编程特性的支持,不过它的性能则取决于持久性提供程序。
某个特定持久性机制的选择事关所有功能特性的权衡,这些特性在本文的比较章节中都做了讨论。对于大部分的开发者来说,需要根据是否要求对应用的SQL做全面控制、是否需要自动生成SQL,或仅是想要一个易于编程的完整的ORM解决方案等各方面的考虑来做决定