spring data jpa 了解以及环境搭建
2016-03-28 20:46
661 查看
什么是JPA
JPA是sun提出的一个对象持久化规范,各JavaEE应用服务器自主选择具体实现,JPA的设计者是Hibernate框架的作者,因此Hibernate作为Jboss服务器中JPA的默认实现,Oracle的Weblogic使用EclipseLink(以前叫TopLink)作为默认的JPA实现,IBM的Websphere和Sun的Glassfish默认使用OpenJPA(Apache的一个开源项目)作为其默认的JPA实现。
JPA的底层实现是一些流行的开源ORM(对象关系映射)框架,因此JPA其实也就是java实体对象和关系型数据库建立起映射关系,通过面向对象编程的思想操作关系型数据库的规范。
spring data jpa 、hibernate以及JPA的关系
JPA是一种规范,而hibernate是实现这种规范的底层实现,spring data jpa对持久化接口JPA再抽象一层,针对持久层业务再进一步简化,这样子开发者就连持久层的业务逻辑也不用写了,只要按照spring data jpa的命名规范,写好接口继承,一切就交给spring吧。
搭建spring data jpa
根据JPA规范要求,配置persistence.xml,并存在于类路径下的 META-INF 目录中,这里我们配置如下
这里我们可以把数据库的一些配置放到application.properties的配置文件中
配置spring的applicationContext.xml文件,配置数据源,事务管理器,以及spring data jpa 的扫描目录
弄好配置文件之后,我们来看看平时的CRUD和分页怎么操作?
1.在Spring Data JPA扫描目录下,也就是持久层下新建一个接口继承于JpaRepository
在JpaRepository接口中,spring data jpa已经帮我定义好一些crud和分页操作接口,我们直接用就可以了
2.在service新建TaskService bean,并把TaskDao 注入到该bean中
3.接下来,就写crud和分页操作
这些的实现,接口taskDao也是一行代码也没写。那如果发现这些方法不够,想通过具体的属性来查询某个实体类呢,那就在taskDao接口上写上方法吧
只需在service调用这个方法就可以完成需求,不需要你写一点逻辑代码,当然你还可以利用@Query直接在方法名上自定义查询
你还可以写原生的sql语句
上面的例子中,我们是通过继承spring data jpa的JpaRepository接口,其他spring data jpa还定义了其他几个核心接口
1.CrudRepository 添加一些增删改查操作
2.PagingAndSortingRepository 增加分页接口
3.JpaRepository 添加一些批量操作
4.JpaSpecificationExecutor 用来做动态查询
6.Specification spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可
7.Repository,接口什么都不做
扫描包内的接口只要继承Repository ,spring都会帮其生成实现类,如果你不需要spring帮你生成实现类,那就@NoRepositoryBean吧
4.支持事务,根据事务的传播性,我们一般在service通过添加 @Transactional来处理事务
spring data jpa 大概了解到这里,后面会详细讲。
JPA是sun提出的一个对象持久化规范,各JavaEE应用服务器自主选择具体实现,JPA的设计者是Hibernate框架的作者,因此Hibernate作为Jboss服务器中JPA的默认实现,Oracle的Weblogic使用EclipseLink(以前叫TopLink)作为默认的JPA实现,IBM的Websphere和Sun的Glassfish默认使用OpenJPA(Apache的一个开源项目)作为其默认的JPA实现。
JPA的底层实现是一些流行的开源ORM(对象关系映射)框架,因此JPA其实也就是java实体对象和关系型数据库建立起映射关系,通过面向对象编程的思想操作关系型数据库的规范。
spring data jpa 、hibernate以及JPA的关系
JPA是一种规范,而hibernate是实现这种规范的底层实现,spring data jpa对持久化接口JPA再抽象一层,针对持久层业务再进一步简化,这样子开发者就连持久层的业务逻辑也不用写了,只要按照spring data jpa的命名规范,写好接口继承,一切就交给spring吧。
搭建spring data jpa
根据JPA规范要求,配置persistence.xml,并存在于类路径下的 META-INF 目录中,这里我们配置如下
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="springJpa" transaction-type="RESOURCE_LOCAL"> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <!-- <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <property name="hibernate.connection.url" value="com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="1qaz2wsx"/> <property name="hibernate.dialect" value="org.hibernate.dialect.OracleDialect"/> --> <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="none"/> <!-- 配置hibernate缓存 --> <property name="hibernate.cache.use_second_level_cache" value="true"/> <property name="hibernate.cache.use_query_cache" value="true"/> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/> <property name="hibernate.generate_statistics" value="true"/> </properties> </persistence-unit> </persistence>
这里我们可以把数据库的一些配置放到application.properties的配置文件中
hibernate.dialect=org.hibernate.dialect.MySQLDialect jdbc.driverClassName=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/xxx?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull jdbc.username=root jdbc.password=root
配置spring的applicationContext.xml文件,配置数据源,事务管理器,以及spring data jpa 的扫描目录
<!-- 数据源配置 --> <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close"> <property name="url" value="${jdbc.url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <property name="filters" value="stat" /> <property name="maxActive" value="20" /> <property name="initialSize" value="1" /> <property name="maxWait" value="60000" /> <property name="minIdle" value="1" /> <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" /> <property name="poolPreparedStatements" value="false" /> <property name="maxPoolPreparedStatementPerConnectionSize" value="20" /> </bean> <!-- 配置事务管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> <qualifier value="jpaEM" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="persistenceUnitName" value="springJpa" /> </bean> <!-- 启用 annotation事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <!-- 配置Spring Data JPA扫描目录 --> <jpa:repositories base-package="com.xxx.**.dao" repository-impl-postfix="Impl" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager" />
弄好配置文件之后,我们来看看平时的CRUD和分页怎么操作?
1.在Spring Data JPA扫描目录下,也就是持久层下新建一个接口继承于JpaRepository
public interface TaskDao extends JpaRepository<Task,Long>{ }
在JpaRepository接口中,spring data jpa已经帮我定义好一些crud和分页操作接口,我们直接用就可以了
2.在service新建TaskService bean,并把TaskDao 注入到该bean中
@Service public class TaskService { @Autowired TaskDao taskDao ; }
3.接下来,就写crud和分页操作
@Service public class TaskService { @Autowired TaskDao taskDao ; /** * 保存更新实体类 * @param task * @return */ @Transactional public Task saveOrUpdateTask(Task task){ if(task.getId() > 0){ //更新操作 task.setTaskName("newTaskName"); }else{ //保存操作 task.setCreateTime(new Date()); } return this.taskDao.save(task); //save会根据实体类是否有id进行保存或者更新操作 } /** * 根据id删除一个实体 * @param id */ @Transactional public void deleteTask(Long id){ this.taskDao.delete(id); } /** * 获取分页数据 * @param page * @param size * @return */ public Page<Task> findPageTask(int page ,int size){ //直接分页不排序 Page<Task> list1 = this.taskDao.findAll(new PageRequest(page, size)); //如果需要分页和排序 Sort sort = new Sort(new Order("createTime")); Page<Task> list2 = this.taskDao.findAll(new PageRequest(page, size,sort)); return list1 ; } /** * 根据id获取一个实体 * @param id * @return */ public Task findOne(Long id){ return this.taskDao.findOne(id); } }
这些的实现,接口taskDao也是一行代码也没写。那如果发现这些方法不够,想通过具体的属性来查询某个实体类呢,那就在taskDao接口上写上方法吧
public interface TaskDao extends JpaRepository<Task,Long>{ /** * 根据任务名获取任务列表 * @param taskName * @return */ List<Task> findByTaskName(String taskName); }
只需在service调用这个方法就可以完成需求,不需要你写一点逻辑代码,当然你还可以利用@Query直接在方法名上自定义查询
public interface TaskDao extends JpaRepository<Task,Long>{ /** * 根据任务名获取任务列表 * @param taskName * @return */ @Query("select * from Task t where t.taskName = ?1") List<Task> findByTaskName(String taskName); }
你还可以写原生的sql语句
public interface TaskDao extends JpaRepository<Task,Long>{ /** * 根据任务名获取任务列表 * @param taskName * @return */ @Query(value = "select * from tb_task t where t.task_name = ?1",nativeQuery = true) List<Task> findByTaskName(String taskName); }
上面的例子中,我们是通过继承spring data jpa的JpaRepository接口,其他spring data jpa还定义了其他几个核心接口
1.CrudRepository 添加一些增删改查操作
@NoRepositoryBean public interface CrudRepository<T, ID extends Serializable> extends Repository<T, ID> { <S extends T> S save(S entity); T findOne(ID primaryKey); Iterable<T> findAll(); Long count(); void delete(T entity); boolean exists(ID primaryKey); // … more functionality omitted. }
2.PagingAndSortingRepository 增加分页接口
@NoRepositoryBean public interface PagingAndSortingRepository<T, ID extends Serializable> extends CrudRepository<T, ID> { Iterable<T> findAll(Sort sort); Page<T> findAll(Pageable pageable); }
3.JpaRepository 添加一些批量操作
@NoRepositoryBean public interface JpaRepository<T, ID extends Serializable> extends PagingAndSortingRepository<T, ID> { List<T> findAll(); List<T> findAll(Sort sort); List<T> findAll(Iterable<ID> ids); <S extends T> List<S> save(Iterable<S> entities); void flush(); <S extends T> S saveAndFlush(S entity); void deleteInBatch(Iterable<T> entities); void deleteAllInBatch(); T getOne(ID id); }
4.JpaSpecificationExecutor 用来做动态查询
public interface JpaSpecificationExecutor<T> { T findOne(Specification<T> spec); List<T> findAll(Specification<T> spec); Page<T> findAll(Specification<T> spec, Pageable pageable); List<T> findAll(Specification<T> spec, Sort sort); long count(Specification<T> spec); }
6.Specification spring Data JPA提供的一个查询规范,要做复杂的查询,只需围绕这个规范来设置查询条件即可
public interface Specification<T> { Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb); }
7.Repository,接口什么都不做
public interface Repository<T, ID extends Serializable> { }
扫描包内的接口只要继承Repository ,spring都会帮其生成实现类,如果你不需要spring帮你生成实现类,那就@NoRepositoryBean吧
4.支持事务,根据事务的传播性,我们一般在service通过添加 @Transactional来处理事务
@Service public class TaskService { @Autowired TaskDao taskDao ; //注入接口 /** * 保存任务 */ @Transactional public void saveTask(Task t) { this.taskDao.save(t); } }
spring data jpa 大概了解到这里,后面会详细讲。
相关文章推荐
- java就业指导
- 第三周JAVA学习
- JavaSE入门学习32:Java常用类之时间日期相关类
- 学习javaEE每一天2016.3.28
- JAVAEE学习笔记
- 深入理解Java虚拟机之垃圾收集器内存分配策略
- java第三周作业
- java中io操作的注意事项
- Mac系统java环境搭建
- spring和hibernate整合使用getCurrentSession方法
- 【转】 java web开发之安全事项
- java设计模式之工厂模式
- java第三次作业
- Spring 源码分析(四) ——MVC(四)核心逻辑
- 关于JAVA的Annotation(注解的实现过程)
- Struts2拦截器运作
- Spring 源码分析(四) ——MVC(三)源码入口
- java Stack 类 (栈)
- 第三周JAVA学习笔记(三)
- Java学习笔记(三)