Spring Data JPA แตกต่างจาก Hibernate สำหรับโครงการขนาดใหญ่อย่างไร


129

ฉันมีช่วงเวลาที่ยากลำบากในการตัดสินใจว่าควรใช้ Hibernate สำหรับโปรเจ็กต์ใหม่หรือไม่หรือทำให้เท้าเปียกด้วย JPA และการนำ Spring Data มาใช้

Spring Data framework มีไว้สำหรับโครงการขนาดใหญ่หรือโครงการขนาดเล็กที่มีข้อกำหนดการสืบค้นเพียงเล็กน้อยหรือไม่

ในขณะที่ฉันเห็นข้อได้เปรียบในการลดโค้ดโดยใช้@Queryคำอธิบายประกอบคุณจะทำอย่างไรสำหรับการสืบค้นแบบไดนามิก ถ้าคุณต้องการใช้เมธอด save () ที่ค่อนข้างซับซ้อนล่ะ?

เอกสารระบุว่าให้สร้างอินเทอร์เฟซแบบกำหนดเองและการใช้งานที่ที่เก็บหลักของคุณใช้ แต่ถ้าคุณต้องการเข้าถึงวิธีการขั้นสูงใด ๆ บนที่เก็บ crud เองล่ะ? ที่เก็บ crud ใช้ที่เก็บแบบกำหนดเองไม่ใช่ในทางอื่น ดูเหมือนเป็นการออกแบบที่แปลก

ฉันไม่แน่ใจมากว่าเฟรมเวิร์กนี้จะตอบสนองความท้าทายของแอพพลิเคชั่นที่ซับซ้อนและมีขนาดใหญ่ได้หรือไม่ ฉันไม่เคยประสบปัญหามากมายเกี่ยวกับ Hibernate และฉันกำลังพิจารณาที่จะยึดติดกับความน่าเชื่อถือแบบเก่ามากกว่าที่จะใช้ Spring Data JPA

ฉันควรทำอย่างไรดี? ฉันจะต้องเผชิญกับภาวะแทรกซ้อนและค่าใช้จ่ายที่คาดไม่ถึงอะไรบ้างหากใช้ Spring Data JPA


1
เท่าที่ฉันรู้มันสร้างความแตกต่างเพียงเล็กน้อย ไปกับคนที่คุณสบายใจกว่า ทำไมการอภิปราย?
duffymo

1
เห็นได้ชัดว่าฉันรู้สึกสบายใจกับ Hibernate มากขึ้น แต่ถ้าฉันสามารถทำสิ่งเดิม ๆ และมีประสิทธิผลมากขึ้นฉันควรใช้แนวทางใหม่กว่านี้ อย่างไรก็ตามหาก Hibernate ยังคงมีพลังมากกว่าและฉันจะพบปัญหาน้อยกว่ามากนั่นคือสิ่งที่ฉันอยากรู้
egervari

3
JPA เป็นลักษณะทั่วไปของ ORM ที่ใช้ Hibernate เป็นหนึ่งในการนำไปใช้งานมากมาย คุณมีอำนาจอะไรบ้างที่มีอำนาจเหนืออีกฝ่าย? JPA เป็นมาตรฐาน แต่ฉันเห็นความแตกต่างเล็กน้อยระหว่างสองอย่างนี้ เพื่อประโยชน์ของการเปิดเผยข้อมูลทั้งหมดฉันจะบอกว่าฉันไม่สนใจอย่างใดอย่างหนึ่ง ทั้งสองสร้าง SQL ให้คุณ ฉันอยากจะเขียนมันด้วยตัวเอง ORM ไม่ได้มีไว้สำหรับทุกปัญหาและผู้ใช้ทุกคน
duffymo

1
ฉันเห็นด้วย. เมื่อพูดถึง JPA หรือ Hibernate เท่านั้นฉันจะเลือก Hibernate ทุกครั้ง ฉันไม่ชอบการใช้งาน JPA ด้วยตัวเองโดยสุจริต การรองรับ IDE ใน IDEA นั้นเป็นสิ่งที่ไม่ดีจริงๆและมันจะบ่นหากการแมปไม่ถูกต้องเมื่อแอปพลิเคชันเริ่มทำงานแทนที่จะปล่อยให้การทดสอบหน่วยทำงาน มี nitpicks อื่น ๆ อีกมากมายที่ฉันมีกับ JPA ฉันชอบไฟล์การแมป XML Hibernate แบบเก่าจริงๆ มีข้อดีคือทำให้วัตถุของฉันดูรกน้อยลงด้วย Spring Data JPA มีคุณสมบัติใหม่มากมายดังนั้นในที่สุดฉันก็สงสัยว่ามันคุ้มค่าที่จะเปลี่ยนหรือไม่
egervari

3
"Spring Data" ไม่ใช่การนำ JPA มาใช้หรือสิ่งใด ๆ เพียงแค่ใช้การใช้งาน JPA ที่มีอยู่และลดความซับซ้อนของสิ่งที่คุณให้ไว้ การดำเนินการของ JPA ยังคงดำเนินการทั้งหมดภายใต้การคุ้มครอง
Neil Stockton

คำตอบ:


104

ดังนั้นspring-dataเวทมนตร์พิเศษบางอย่างที่ช่วยในการสืบค้นที่ซับซ้อน เป็นเรื่องแปลกในตอนแรกคุณข้ามมันไปในเอกสารโดยสิ้นเชิง แต่มันทรงพลังและมีประโยชน์จริงๆ

มันเกี่ยวข้องกับการสร้างRepositoryRepositoryImpl ที่กำหนดเองและกำหนดเองและบอก Spring ว่าจะหาได้ที่ไหน นี่คือตัวอย่าง:

คลาสคอนฟิกูเรชัน - ชี้ไปที่การกำหนดค่าxml ที่คุณยังต้องการพร้อมคำอธิบายประกอบที่ชี้ไปที่แพ็กเกจที่เก็บของคุณ ( *Implตอนนี้จะค้นหาคลาสโดยอัตโนมัติ):

@Configuration
@EnableJpaRepositories(basePackages = {"com.examples.repositories"})
@EnableTransactionManagement
public class MyConfiguration {
}

jpa-repositories.xml - บอกSpringตำแหน่งที่จะค้นหาที่เก็บของคุณ บอกSpringให้มองหาที่เก็บที่กำหนดเองด้วยCustomImplชื่อไฟล์:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
    http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">

<jpa:repositories base-package="com.example.repositories" repository-impl-postfix="CustomImpl" />

</beans>

MyObjectRepository- นี่คือที่ที่คุณสามารถใส่วิธีการค้นหาที่มีคำอธิบายประกอบและไม่มีคำอธิบายประกอบ สังเกตว่าอินเทอร์เฟซที่เก็บนี้ขยายส่วนต่อประสานอย่างไรCustom:

@Transactional
public interface MyObjectRepository extends JpaRepository<MyObject, Integer>, MyObjectRepositoryCustom {

    List<MyObject> findByName(String name);

    @Query("select * from my_object where name = ?0 or middle_name = ?0")
    List<MyObject> findByFirstNameOrMiddleName(String name);
}

MyObjectRepositoryCustom - วิธีการจัดเก็บที่ซับซ้อนกว่าและไม่สามารถจัดการได้ด้วยแบบสอบถามหรือคำอธิบายประกอบแบบธรรมดา:

public interface MyObjectRepositoryCustom {

    List<MyObject> findByNameWithWeirdOrdering(String name);
}

MyObjectRepositoryCustomImpl- ที่ที่คุณใช้วิธีการเหล่านั้นด้วยระบบอัตโนมัติEntityManager:

public class MyObjectRepositoryCustomImpl implements MyObjectRepositoryCustom {

    @Autowired
    private EntityManager entityManager;

    public final List<MyObject> findByNameWithWeirdOrdering(String name) {
        Query query = query(where("name").is(name));
        query.sort().on("whatever", Order.ASC);
        return entityManager.find(query, MyObject.class);
    }
}

น่าแปลกใจที่ทั้งหมดนี้มาพร้อมกันและวิธีการจากทั้งสองอินเทอร์เฟซ (และอินเทอร์เฟซ CRUD ที่คุณใช้) ทั้งหมดจะปรากฏขึ้นเมื่อคุณทำ:

myObjectRepository.

แล้วคุณจะได้เห็น:

myObjectRepository.save()
myObjectRepository.findAll()
myObjectRepository.findByName()
myObjectRepository.findByFirstNameOrMiddleName()
myObjectRepository.findByNameWithWeirdOrdering()

มันใช้งานได้จริง และคุณจะได้รับหนึ่งอินเทอร์เฟซสำหรับการสืบค้น spring-dataพร้อมสำหรับแอปพลิเคชันขนาดใหญ่จริงๆ และยิ่งคุณสามารถส่งข้อความค้นหาเป็นแบบธรรมดาหรือใส่คำอธิบายประกอบได้มากเท่าไหร่ก็ยิ่งดีเท่านั้น

ทั้งหมดนี้เป็นเอกสารที่เว็บไซต์ของฤดูใบไม้ผลิข้อมูล Jpa

โชคดี.


4
นี่คือสิ่งที่ฉันพยายามจริง ๆ และมันก็ได้ผลในระดับหนึ่ง ปัญหาที่ฉันมีคือถ้าคุณต้องการแทนที่บันทึก ()? ตัวอย่างเช่นสมมติว่าคุณกำลังบันทึกบล็อกและคุณต้องการประมวลผล / บันทึกแท็กที่เกี่ยวข้องในเมธอด save () เนื่องจากการใส่ไว้ในบริการไม่สมเหตุสมผล นี่เป็นเรื่องง่ายที่จะทำกับ Hibernate แบบดิบ แต่ฉันไม่เห็นวิธีที่ดีที่จะทำกับ Spring JPA ฉันจะทำเครื่องหมายคำตอบของคุณว่าถูกต้องเพราะถูกต้อง นั่นคือสิ่งที่คุณสามารถทำได้กับ Spring Data JPA ฉันคิดว่าฉันจะติดกับ Hibernate คำตอบนี้ช่วยคนอื่นได้แน่นอน
egervari

8
คุณสามารถใช้ของคุณเอง->JpaRepository MyJpaRepositoryคุณต้องสร้างด้วยMyJpaRepositoryFactoryBeanแต่ถ้าคุณตั้งค่าทั้งหมดอย่างถูกต้องคุณสามารถแทนที่เมธอด. save () ได้ นี่คือ Spring Data JPA Docs: static.springsource.org/spring-data/data-jpa/docs/current/…อย่าเพิ่งยอมแพ้!
sbzoom

@Picrochole คุณตีความ 'ระดับล่างของแอปพลิเคชัน' อย่างไร? บริการซึ่งเรียก DAO ต่ำกว่าในระดับหรือไม่?
Rumid

12

ฉันใช้ Spring Data JPA ในโปรเจ็กต์ขนาดเล็กและขนาดใหญ่ที่มีความต้องการในการสืบค้นง่ายๆ ข้อได้เปรียบหลักคือไม่ต้องใช้@Queryคำอธิบายประกอบ ไม่มีสิ่งใดใน Spring Data ที่ขัดขวางไม่ให้คุณใช้ในโครงการขนาดใหญ่และการQueryDSLสนับสนุนล่าสุดอาจช่วยคุณได้ นี่คือตัวอย่างของการใช้QueryDSLเพื่อกำหนดเป้าหมายไฮเบอร์เนต

หากคุณคาดการณ์ข้อความค้นหาที่ซับซ้อนและคุณรู้สึกสบายใจที่จะใช้วัตถุ Hibernate โดยไม่มี JPA ฉันคิดว่าการผสมผสานทางเลือกอาจเป็นการใช้ Spring Data แบบง่ายๆRepositoryถัดจากข้อมูลที่ใช้ Hibernate ที่ซับซ้อนด้วยวิธีการเฉพาะที่คุณอาจต้องการ อาจจะยุ่งยากน้อยกว่าที่การบิดการใช้งาน Hibernate เข้ากับโครงสร้าง Spring Data JPA


2
ฉันคิดว่าฉันควรใช้ api ที่สอดคล้องกันสำหรับการค้นหามากกว่าการผสมและจับคู่ในโครงการเดียวกัน ฉันยังไม่พบวิธีแก้ปัญหาที่ดีสำหรับข้อมูลสปริงที่ซับซ้อนของ jpa และเนื่องจากมี nitpicks กับ jpa ที่ฉันมีอยู่โดยทั่วไปฉันคิดว่าฉันอาจจะมีความสุขมากกว่าที่จะยอมรับการจำศีลเป็น orm ของฉัน ฉันจะมีคำถามที่ซับซ้อนมากมายและฉันไม่สามารถมีส่วนผสม 40/60 ได้ มันไม่คุ้มสำหรับฉัน :(
egervari

1
นอกจากนี้คุณยังสามารถใช้ Querydsl ได้โดยตรงโดยไม่ต้องใช้ Spring Data ซึ่งจะทำให้คุณมีชั้นแบบสอบถามที่มีประสิทธิภาพเพียงชั้นเดียวที่อยู่ด้านบนของ JPA
Timo Westkämper

4

Spring JPA จะช่วยให้คุณมีนามธรรมมากมายจากการเขียน SQL และแม้แต่ HQL บางส่วนโดยใช้การประกาศวิธีการสืบค้น Spring JPA เปล่งประกายด้วยการสร้างแบบสอบถาม แต่เมื่อคุณต้องการโซลูชันไฮเบอร์เนตอย่างหมดจดคุณสามารถปรับแต่งได้ตามต้องการเนื่องจาก JPA ฤดูใบไม้ผลิยังคงอิงตามโหมดไฮเบอร์เนต ตรวจสอบเอกสารhttp://static.springsource.org/spring-data/data-jpa/docs/current/reference/htmlสำหรับข้อมูลเพิ่มเติม

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.