成人国产在线小视频_日韩寡妇人妻调教在线播放_色成人www永久在线观看_2018国产精品久久_亚洲欧美高清在线30p_亚洲少妇综合一区_黄色在线播放国产_亚洲另类技巧小说校园_国产主播xx日韩_a级毛片在线免费

資訊專欄INFORMATION COLUMN

Spring Boot [組件學(xué)習(xí)-Spring Data JPA]

andong777 / 2192人閱讀

摘要:與的關(guān)系是什么是官方提出的持久化規(guī)范。它為開發(fā)人員提供了一種對象關(guān)聯(lián)映射工具來管理應(yīng)用中的關(guān)系數(shù)據(jù)。他的出現(xiàn)主要是為了簡化現(xiàn)有的持久化開發(fā)工作和整合技術(shù),結(jié)束現(xiàn)在,,等框架各自為營的局面。定義了在對數(shù)據(jù)庫中的對象處理查詢和事務(wù)運行時的的。

導(dǎo)讀:

在上篇文章中對Spring MVC常用的一些注解做了簡要的說明,在這篇文章中主要對Spring Data JPA 做一個簡要的說明,并附有一個簡單的例子,可以體會到Spring Data JPA 的強大之處。

Spring Data JPA 與JPA的關(guān)系: JPA是什么?

JPA(Java Persistence API)是Sun官方提出的Java持久化規(guī)范。它為Java開發(fā)人員提供了一種對象/關(guān)聯(lián)映射工具來管理Java應(yīng)用中的關(guān)系數(shù)據(jù)。他的出現(xiàn)主要是為了簡化現(xiàn)有的持久化開發(fā)工作和整合ORM技術(shù),結(jié)束現(xiàn)在Hibernate,TopLink,JDO等ORM框架各自為營的局面。值得注意的是,JPA是在充分吸收了現(xiàn)有Hibernate,TopLink,JDO等ORM框架的基礎(chǔ)上發(fā)展而來的,具有易于使用,伸縮性強等優(yōu)點。
JPA定義了在對數(shù)據(jù)庫中的對象處理查詢和事務(wù)運行時的EntityManager的API。JPA定義一個對象級查詢語言,JPQL,如果學(xué)習(xí)過Hibernate的話你可以把它看做Hibernate中的Hql語句,以允許從所述數(shù)據(jù)庫中的對象的查詢。
下面是JPA常用的一些解決方案:

EclipseLink (Eclipse)
Hibernate (RedHat)
Open JPA (Apache)
DataNucleus
Ebean (SourceForge)
TopLink Essentials (Glassfish)
TopLink (Oracle)
Kodo (Oracle)
Spring Data JPA:

你可以把它做做事JPA的超集 類似于 C與C++的關(guān)系,Spring Data JPA可以極大的簡化JPA的寫法,可以在幾乎不用寫實現(xiàn)的情況下,實現(xiàn)對數(shù)據(jù)的訪問和操作。除了CRUD外,還包括如分頁、排序等一些常用的功能。

也就是說Spring Data JPA 在JPA的基礎(chǔ)上提供了更高層次的抽象,幫助我們實現(xiàn)了許多常用的對數(shù)據(jù)庫的操作,從而提高開發(fā)效率。

Spring Data JPA 的一些常用方法

在了解Spring Data JPA之前我們首先看一下它為我們提供了那些便利。

1.簡單查詢:

面對簡單的查詢時可以通過解析方法名創(chuàng)建查詢或使用使用 @Query 創(chuàng)建查詢語句

比如現(xiàn)在我們有個方法叫做 User findByName(String name),我們可以很清楚的明白它的意思,但有沒有辦法讓ORM框架根據(jù)方法名幫助我們推斷出Sql來呢?在Spring Data JPA中這是可以的,我們只要將我們的接口繼承 org.springframework.data.repository.Repository ,或者使用@RepositoryDefinition 注解進行修飾。

解析方法名創(chuàng)建查詢 示例:
public interface UserRepository extends Repository {
    User findByName(String name)
} 


@RepositoryDefinition(domainClass = User.class, idClass = Long.class) 
public interface UserRepository{
    User findByName(String name)
} 
@Query注解查詢 示例:
public interface UserRepository extends Repository {
    //對于更新操作需要添加@Modifying
    @Query("from User u where u.name=:name")
    User findUser(@Param("name") String name);
} 

當(dāng)然還不止這些Spring Data JPA 還未我們提供了幾個常用的Repository:

Repository: 僅僅是一個標(biāo)識,沒有任何方法,方便Spring自動掃描識別

CrudRepository: 繼承Repository,實現(xiàn)了一組CRUD相關(guān)的方法

PagingAndSortingRepository: 繼承CrudRepository,實現(xiàn)了一組分頁排序相關(guān)的方法

JpaRepository: 繼承PagingAndSortingRepository,實現(xiàn)一組JPA規(guī)范相關(guān)的方法

通過繼承它們可以獲得更強大的功能,當(dāng)然它們之所能夠運行是因為有了默認的實現(xiàn)類:

@Repository
@Transactional(readOnly = true)
public class SimpleJpaRepository implements JpaRepository,
        JpaSpecificationExecutor {
   
}

在查詢的時候,通常需要同時根據(jù)多個屬性進行查詢,Spring Data JPA 為此提供了一些表達條件查詢的關(guān)鍵字,大致如下:

And --- 等價于 SQL 中的 and 關(guān)鍵字,比如 findByUsernameAndPassword(String user, Striang pwd);

Or --- 等價于 SQL 中的 or 關(guān)鍵字,比如 findByUsernameOrAddress(String user, String addr);

Between --- 等價于 SQL 中的 between 關(guān)鍵字,比如 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 userList) ,方法的參數(shù)可以是 Collection 類型,也可以是數(shù)組或者不定長參數(shù);

NotIn --- 等價于 SQL 中的 "not in",比如 findByUsernameNotIn(Collection userList) ,方法的參數(shù)可以是 Collection 類型,也可以是數(shù)組或者不定長參數(shù);

當(dāng)然面對比較復(fù)雜的查詢時,它們就顯得無力了,如果在面對比較復(fù)雜的查詢時,想要有自己的實現(xiàn)方法,只需要通過一個XXXImpl結(jié)尾的實現(xiàn)類即可使用我們自己的實現(xiàn)方法(比如UserRepository接口的同一個包下面建立一個普通類UserRepositoryImpl來表示該類的實現(xiàn)類)。

了解更多:使用 Spring Data JPA 簡化 JPA 開發(fā) - IBM

2.復(fù)雜的查詢

面對復(fù)雜的查詢時可以使用本地查詢或JPQL或使用JPA的動態(tài)接口(JpaSpecificationExecutor)

在面對負責(zé)的條件查詢時,需要有條件判斷這個時候方法名推斷就顯得不夠強大了,比如當(dāng)這里有個簡單的例子:“我們要根據(jù)用戶的年齡,地址,性別 查詢用戶信息時”, 在考慮可能存在條件為空的情況下,在使用方法名推斷時我們需要提供8個相應(yīng)的方法,當(dāng)然如果使用流的話有一個findAll方法即可,但是這無疑增大了數(shù)據(jù)庫與發(fā)射生成對象壓力所以并不推薦這種方式,那么在這種情況下如果可以使用判斷進行條件拼接的話,便可以將查詢的方法縮減到一個 這便是以上三種方式的優(yōu)點(一般情況下不推薦 本地查詢)。

JPQL示例:

DO:

@Entity
public class User extends AbstractPersistable {

    private String name;

    private Integer age;

    private String AddressCode;

    @Enumerated(EnumType.ORDINAL)
    private Sex sex;
    
    /**省略get/set**/
}

DAO:

public interface UserCustomRepository {

    Page search(Integer age, String AddressCode, User.Sex sex, Pageable pageRequest);

}


public interface UserRepository extends CrudRepository, UserCustomRepository {

}


public class UserRepositoryImpl implements UserCustomRepository {

    @PersistenceContext
    private EntityManager em;

    @Override
    public Page search(Integer age, String AddressCode, User.Sex sex, Pageable pageRequest) {
        String querySql = "select t ";
        String countSql = "select count(t) ";
        StringBuffer sqlBuffer = new StringBuffer("from User t where 1=1");

        if (null != age) {
            sqlBuffer.append(" and t.age = :age");
        }
        if (null != AddressCode) {
            sqlBuffer.append(" and t.AddressCode = :address");
        }
        if (null != sex) {
            sqlBuffer.append(" and t.sex = :sex");
        }

        querySql += sqlBuffer.toString();
        countSql += sqlBuffer.toString();

        Query dataQuery = em.createQuery(querySql);
        Query countQuery = em.createQuery(countSql);

        if (null != age) {
            dataQuery.setParameter("age", age);
            countQuery.setParameter("age", age);
        }
        if (null != AddressCode) {
            dataQuery.setParameter("address", AddressCode);
            countQuery.setParameter("address", AddressCode);
        }
        if (null != sex) {
            dataQuery.setParameter("sex", sex);
            countQuery.setParameter("sex", sex);
        }
        // 本地查詢方式 
        // Query query = em.createNativeQuery(sql);
        // query.unwrap(NativeQueryImpl.class).setResultTransformer(Transformers.aliasToBean(User.class));
        Page page = (pageRequest == null ? new PageImpl(dataQuery.getResultList()) : this.readPage(dataQuery, countQuery, pageRequest));
        return page;
    }

    private Page readPage(Query dataQuery, Query countQuery, Pageable pageable) {
        dataQuery.setFirstResult(pageable.getOffset());
        dataQuery.setMaxResults(pageable.getPageSize());
        long totalSize = (long) countQuery.getSingleResult();
        List content = totalSize > (long) pageable.getOffset() ? dataQuery.getResultList() : Collections.emptyList();
        return new PageImpl(content, pageable, totalSize);
    }


}

Test:

@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SpringBootJpaApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void contextLoads() {
        List userList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            String name = "name" + i;
            Integer age = 19 + (i + 1) % 5;
            String addressCode = "address";
            User.Sex sex = i % 2 == 0 ? User.Sex.MAN : User.Sex.WOMAN;
            User user = new User(name, age, addressCode, sex);
            System.out.println(JSON.toJSON(user));
            userList.add(user);
        }
        userRepository.save(userList);
    }

    @Test
    public void search() {
        int page = 0;
        int size = 2;
        Pageable pageable = new PageRequest(page, size);
        Page pageUser = userRepository.search(null, null, null, pageable);
        pageUser = userRepository.search(19, null, User.Sex.WOMAN, pageable);
        System.out.println(JSON.toJSON(pageUser));
    }

}

JPA的動態(tài)接口(JpaSpecificationExecutor):

只做了簡單的修改
DO:

public interface UserRepository extends CrudRepository, UserCustomRepository, JpaSpecificationExecutor {

}

Test:

@RunWith(SpringRunner.class)
@SpringBootTest
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class SpringBootJpaApplicationTests {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void contextLoads() {
        List userList = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            String name = "name" + i;
            Integer age = 19 + (i + 1) % 5;
            String addressCode = "address";
            User.Sex sex = i % 2 == 0 ? User.Sex.MAN : User.Sex.WOMAN;
            User user = new User(name, age, addressCode, sex);
            System.out.println(JSON.toJSON(user));
            userList.add(user);
        }
        userRepository.save(userList);
    }

    @Test
    public void search() {
        int page = 0;
        int size = 2;
        Pageable pageable = new PageRequest(page, size);
        Page pageUser = userRepository.search(null, null, null, pageable);
//        System.out.println(JSON.toJSON(pageUser));
        pageUser = userRepository.search(19, null, User.Sex.WOMAN, pageable);
        System.out.println(JSON.toJSON(pageUser));
//        pageUser = userRepository.search(null, null, null, pageable);
//        System.out.println(JSON.toJSON(pageUser));
//        pageUser = userRepository.search(null, null, null, pageable);
//        System.out.println(JSON.toJSON(pageUser));
    }

    @Test
    public void findAll() {
        int page = 0;
        int size = 2;
        Pageable pageable = new PageRequest(page, size);
        Page pageUser = search(19, null, User.Sex.WOMAN, pageable);
        System.out.println(JSON.toJSON(pageUser));
    }

    public Page search(final Integer age, final String AddressCode, final User.Sex sex, Pageable pageRequest) {
/*      第一種查詢方式
        Specification specification = (Root root, CriteriaQuery query, CriteriaBuilder cb) -> {
            //創(chuàng)建查詢條件
            List predicates = new ArrayList<>();
            if (age != null) {
                predicates.add(cb.equal(root.get("age"), age));
            }
            if (AddressCode != null) {
                predicates.add(cb.equal(root.get("AddressCode").as(String.class), AddressCode));
            }
            if (sex != null) {
                predicates.add(cb.equal(root.get("sex").as(User.Sex.class), sex));
            }
            return cb.and(predicates.toArray(new Predicate[predicates.size()]));
        };

*/
        //第二種
        Specification specification = (Root root, CriteriaQuery query, CriteriaBuilder cb) -> {
            //創(chuàng)建查詢條件
            List predicates = new ArrayList<>();
            if (age != null) {
                predicates.add(cb.equal(root.get("age"), age));
            }
            if (AddressCode != null) {
                predicates.add(cb.equal(root.get("AddressCode").as(String.class), AddressCode));
            }
            if (sex != null) {
                predicates.add(cb.equal(root.get("sex").as(User.Sex.class), sex));
            }
            Predicate[] assetTradingArray = new Predicate[predicates.size()];
            predicates.toArray(assetTradingArray);
            query.where(assetTradingArray);//這種方式使用JPA的API設(shè)置了查詢條件,所以不需要再返回查詢條件Predicate給Spring Data Jpa,故最后return null;即可。
            return null;
        };
        return userRepository.findAll(specification, pageRequest);
    }

}

了解更多:純干貨,Spring-data-jpa詳解,全方位介紹。

Spring Data JPA 在Spring-Boot中的使用: 第一步將相關(guān)依賴導(dǎo)入POM文件:
    
        org.springframework.boot
        spring-boot-starter-parent
        1.5.2.RELEASE
         
    

    
        UTF-8
        UTF-8
        1.8
    

    
        
            org.springframework.boot
            spring-boot-starter-data-jpa
        
        
            org.springframework.boot
            spring-boot-starter-web
        

        
            com.h2database
            h2
            runtime
        
        
            org.springframework.boot
            spring-boot-starter-test
            test
        

        
        
            com.alibaba
            fastjson
            1.2.23
        
    

    
        
            
                org.springframework.boot
                spring-boot-maven-plugin
            
        
    

第二步配置yml文件(使用了內(nèi)存數(shù)據(jù)庫因此沒有配數(shù)據(jù)源):
spring:
  jpa:
    show-sql: true
    properties:
      hibernate:
        hbm2ddl:
          auto: update
第三步編寫main函數(shù):
@SpringBootApplication
public class SpringBootJpaApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringBootJpaApplication.class, args);
    }
}
第四步編寫相關(guān)的Repository:
public interface UserRepository extends CrudRepository, UserCustomRepository, JpaSpecificationExecutor {

}
相關(guān)邏輯編寫->運行->測試->發(fā)布 學(xué)習(xí)資料收集:

教程:

JPA 使用及介紹 (我起的名字>_<)

博客介紹:

Spring ORM+Hibernate?Out!換 Spring Data JPA 吧!

純干貨,Spring-data-jpa詳解,全方位介紹。 (推薦)

使用 Spring Data JPA 簡化 JPA 開發(fā)

視頻:

尚硅谷Spring Data視頻教程

結(jié)語:

Spring Data JPA 的解析方法名創(chuàng)建查詢非常強大,只是聲明持久層的接口,相關(guān)的查詢它就已經(jīng)幫你去做了,讓我想起一個問題框架的終點在哪?是人工智能嗎?

參考文檔:

全面闡釋和精彩總結(jié)JPA
Spring Data 系列(二) Spring+JPA入門(集成Hibernate)
Spring Data概念【從零開始學(xué)Spring Boot】

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://systransis.cn/yun/66782.html

相關(guān)文章

  • [直播視頻] 《Java 微服務(wù)實踐 - Spring Boot 系列》限時折扣

    摘要:作為微服務(wù)的基礎(chǔ)設(shè)施之一,背靠強大的生態(tài)社區(qū),支撐技術(shù)體系。微服務(wù)實踐為系列講座,專題直播節(jié),時長高達小時,包括目前最流行技術(shù),深入源碼分析,授人以漁的方式,幫助初學(xué)者深入淺出地掌握,為高階從業(yè)人員拋磚引玉。 簡介 目前業(yè)界最流行的微服務(wù)架構(gòu)正在或者已被各種規(guī)模的互聯(lián)網(wǎng)公司廣泛接受和認可,業(yè)已成為互聯(lián)網(wǎng)開發(fā)人員必備技術(shù)。無論是互聯(lián)網(wǎng)、云計算還是大數(shù)據(jù),Java平臺已成為全棧的生態(tài)體系,...

    Enlightenment 評論0 收藏0
  • 70 個 Spring 最常見面試題,Java 晉升必會

    摘要:容器自動完成裝載,默認的方式是這部分重點在常用模塊的使用以及的底層實現(xiàn)原理。 對于那些想面試高級 Java 崗位的同學(xué)來說,除了算法屬于比較「天方夜譚」的題目外,剩下針對實際工作的題目就屬于真正的本事了,熱門技術(shù)的細節(jié)和難點成為了主要考察的內(nèi)容。 這里說「天方夜譚」并不是說算法沒用,不切實際,而是想說算法平時其實很少用到,甚至面試官都對自己出的算法題一知半解。 這里總結(jié)打磨了 70 道...

    Ashin 評論0 收藏0
  • Spring Boot 的簡單教程(四)數(shù)據(jù)庫連接之Spring Data JPA的使用

    摘要:以前都是用進行數(shù)據(jù)庫的開發(fā),最近學(xué)習(xí)之后發(fā)現(xiàn)顯得更友好,所以我們就一起來了解一下的原理吧。簡單介紹持久性是的一個規(guī)范。它用于在對象和關(guān)系數(shù)據(jù)庫之間保存數(shù)據(jù)。充當(dāng)面向?qū)ο蟮念I(lǐng)域模型和關(guān)系數(shù)據(jù)庫系統(tǒng)之間的橋梁。是標(biāo)識出主鍵是指定主鍵的自增方式。 以前都是用Mybatis進行數(shù)據(jù)庫的開發(fā),最近學(xué)習(xí)Spring Boot之后發(fā)現(xiàn)JPA顯得更友好,所以我們就一起來了解一下JPA的原理吧。 Spr...

    yuxue 評論0 收藏0

發(fā)表評論

0條評論

andong777

|高級講師

TA的文章

閱讀更多
最新活動
閱讀需要支付1元查看
<