JPA的全稱是Java Persistence API, 即Java 持久化API,是SUN公司推出的一套基於ORM的規範,內部是由一系列的接口和抽象類構成。java
JPA與hibernate的關係
JPA規範本質上就是一種ORM規範,注意不是ORM框架——由於JPA並未提供ORM實現,它只是制訂了一些規範,提供了一些編程的API接口,但具體實現則由服務廠商來提供實現。JPA和Hibernate的關係就像JDBC和JDBC驅動的關係,JPA是規範,Hibernate除了做爲ORM框架以外,它也是一種JPA實現。JPA怎麼取代Hibernate呢?JDBC規範能夠驅動底層數據庫嗎?答案是否認的,也就是說,若是使用JPA規範進行數據庫操做,底層須要hibernate做爲其實現類完成數據持久化工做。
mysql
Spring Data JPA 是 Spring 基於 ORM 框架、JPA 規範的基礎上封裝的一套JPA應用框架,可以使開發者用極簡的代碼便可實現對數據庫的訪問和操做。它提供了包括增刪改查等在內的經常使用功能,且易於擴展!學習並使用 Spring Data JPA 能夠極大提升開發效率!redis
Spring Data JPA 與 JPA和hibernate之間的關係
JPA是一套規範,內部是有接口和抽象類組成的。hibernate是一套成熟的ORM框架,並且Hibernate實現了JPA規範,因此也能夠稱hibernate爲JPA的一種實現方式,咱們使用JPA的API編程,意味着站在更高的角度上看待問題(面向接口編程)spring
Spring Data JPA是Spring提供的一套對JPA操做更加高級的封裝,是在JPA規範下的專門用來進行數據持久化的解決方案。sql
Spring Data JPA 與 JPA和hibernate之間的關係
數據庫
Spring Data JPA 入門程序
pom.xmlexpress
springContext.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:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd"> <!--spring和spring data jpa的配置--> <!-- 1.dataSource 配置數據庫鏈接池--> <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/jpa"/> <property name="user" value="root"/> <property name="password" value="root"/> </bean> <!-- 2.配置entityManagerFactory --> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="packagesToScan" value="cn.guet.domain"/> <property name="persistenceProvider"> <bean class="org.hibernate.jpa.HibernatePersistenceProvider"/> </property> <!--JPA的供應商適配器--> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="generateDdl" value="false"/> <property name="database" value="MYSQL"/> <property name="databasePlatform" value="org.hibernate.dialect.MySQLDialect"/> <property name="showSql" value="true"/> </bean> </property> <property name="jpaDialect"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaDialect"/> </property> </bean> <!-- 3.事務管理器--> <!-- JPA事務管理器 --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!-- 整合spring data jpa--> <jpa:repositories base-package="cn.guet.dao" transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"></jpa:repositories> <!-- 4.txAdvice--> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="insert*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="get*" read-only="true"/> <tx:method name="find*" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <!-- 5.aop--> <aop:config> <aop:pointcut id="pointcut" expression="execution(* cn.guet.service.*.*(..))"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/> </aop:config> <context:component-scan base-package="cn.guet"></context:component-scan> <!--組裝其它 配置文件--> </beans>
Dao 接口,繼承 JpaRepository、JpaSpecificationExecutor緩存
//JpaRepository<操做的實體類型,實體類中主鍵的類型> //JpaSpecificationExecutor<操做的實體類型> public interface CustormerDao extends JpaRepository<Customer, Long> , JpaSpecificationExecutor<Customer> { }
測試代碼app
@RunWith(SpringJUnit4ClassRunner.class) //聲明spring提供的測試單元 @ContextConfiguration(locations = "classpath:applicationContext.xml") //指定spring容器的配置信息 public class DaoTest { @Autowired private CustormerDao custormerDao; /** * findOne:根據id查詢 */ @Test public void testFindOne() { Customer customer = custormerDao.findOne((long) 1); System.out.println(customer); } /** * save:保存或者更新 * 根據傳遞的對象是否存在主鍵 * 若是沒有主鍵id屬性,保存 * 存在主鍵id屬性,根據id查詢數據,並更新 */ @Test public void testSave() { Customer customer = new Customer(); customer.setCustName("zzy"); customer.setCustAddress("深圳"); customer.setCustIndustry("student"); custormerDao.save(customer); } /** * delete:刪除。先查詢,後刪除 */ @Test public void testDelete() { custormerDao.delete((long) 2); } /** * findAll:查詢全部 */ @Test public void testFindAll() { List<Customer> list = custormerDao.findAll(); System.out.println(list); } }
Spring Data JPA運行邏輯
long count();
void delete(ID var1);
void delete(T var1);
void delete(Iterable<? extends T> var1);
void deleteAll();
boolean exists(ID var1);
Iterable
List
List
List
void flush();
void deleteInBatch(Iterable
void deleteAllInBatch();
T getOne(ID var1);
方法名稱規則查詢
對jpql查詢,更加深刻的一層封裝,咱們只須要按照Spring Data JPA提供的方法名稱規則定義方法,不須要再去配置jpql語句,完成查詢。
/** * 方法名的約定 * findBy:查詢 + 對象中的屬性(首字母大寫):查詢的條件 * findByCustName:根據客戶名稱查詢 */ public Customer findByCustName(String custName);
/** * findBy+屬性名稱+查詢方式(like|isnull) */ public Customer findByCustNameLike(String custName);
/** * findBy+屬性名稱+查詢方式(like|isnull)+多條件鏈接符(and|or) +屬性名稱+查詢方式 */ public Customer findByCustNameLikeAndCustIndustry(String custName,String custIndustry);
T findOne(Specification
List
Page
List
long count(Specification
T findOne(Specification
//根據單個條件查詢單個對象 @Test public void testSpec() { Customer customer = custormerDao.findOne(new Specification<Customer>() { public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { //獲取比較的屬性 Path<Object> custName = root.get("custName"); //構造查詢條件 //equal 精準匹配,param1:須要比較的屬性,param2:當前須要比較的取值 Predicate predicate = cb.equal(custName, "yxf"); //返回查詢條件 return predicate; } }); System.out.println(customer); }
//根據多個條件查詢單個對象 @Test public void testSpec() { Customer customer = custormerDao.findOne(new Specification<Customer>() { //Root:獲取屬性,cb:構造查詢條件 public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { Path<Object> custName = root.get("custName"); //客戶名 Path<Object> custIndustry = root.get("custIndustry");//行業 //構造兩個查詢條件 Predicate predicate1 = cb.equal(custName, "yxf"); Predicate predicate2 = cb.equal(custIndustry, "student"); //將多個查詢條件組合到一塊兒 Predicate predicate = cb.and(predicate1, predicate2); return predicate; } }); System.out.println(customer); }
List
//根據多個條件查詢列表 @Test public void testSpec() { List<Customer> customers = custormerDao.findAll(new Specification<Customer>() { public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { Path<Object> custSource = root.get("custSource"); //gt,lt,ge,like:須要指定參數類型,Path.as(類型的字節碼對象) Predicate predicate = cb.like(custSource.as(String.class), "guet"); return predicate; } }); System.out.println(customers); }
List
//根據多個條件查詢列表,並排序 @Test public void testSpec() { //添加排序,須要調用構造方法實例化sort對象 //param1:正序、倒序;param2:排序的屬性名 Sort sort = new Sort(Sort.Direction.ASC, "custId"); List<Customer> customers = custormerDao.findAll(new Specification<Customer>() { public Predicate toPredicate(Root<Customer> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder cb) { Path<Object> custSource = root.get("custSource"); //gt,lt,ge,like:須要指定參數類型,Path.as(類型的字節碼對象) Predicate predicate = cb.like(custSource.as(String.class), "guet"); return predicate; } }, sort); System.out.println(customers); }
Page
//分頁查詢 @Test public void testSpec() { //建立PageRequest的過程當中,須要調用構造方法,傳入兩個參數 //param1:當前查詢的頁數,param2:每頁查詢的數量 PageRequest pageRequest = new PageRequest(0, 2); Page<Customer> page = custormerDao.findAll(null, pageRequest); System.out.println("查詢列表" + page.getContent()); System.out.println("總條數:" + page.getTotalElements()); System.out.println("總頁數:" + page.getTotalPages()); }