01.Spring Data 初相識

在這裏插入圖片描述

1.概述(瞭解)

Spring Data JPA旨在通過減少實際需要的工作量來顯着改善數據訪問層的實現。作爲開發人員,您編寫存儲庫接口,包括自定義查找器方法,Spring將自動提供實現。

特性概述

  • 基於Spring和JPA構建存儲庫的複雜支持
  • 支持Querydsl謂詞,從而支持類型安全的JPA查詢
  • 透明審覈域類
  • 分頁支持,動態查詢執行,集成自定義數據訪問代碼的能力
  • @Query在引導時驗證註釋查詢
  • 支持基於XML的實體映射
  • 通過引入基於JavaConfig的存儲庫配置@EnableJpaRepositories

Spring Data : Spring 的一個子項目。用於簡化數據庫訪問,支持NoSQL 和 關係數據存儲。其 主要目標是使數據庫的訪問變得方便快捷。

SpringData 項目所支持 NoSQL 存儲:

  • MongoDB (文檔數據庫)

  • Neo4j(圖形數據庫)

  • Redis(鍵/值存儲)

  • Hbase(列族數據庫)

SpringData 項目所支持的關係數據存儲技術:

  • JDBC

  • JPA

核心思想:JPA Spring Data : 致力於減少數據訪問層 (DAO) 的開發量,開發者唯一要做的,就只是聲明持久層的接口,其他都交給 Spring Data JPA 來幫你完成。

框架怎麼可能代替開發者實現業務邏輯呢?
比如:當有一個 UserDao.findUserById() 這樣一個方法聲明,大致應該能判斷出這是根據給定條件的 ID 查詢出滿足條件的 User 對象。Spring Data JPA 做的便是規範方法的名字,根據符合規範的名字來確定方法需要實現什麼樣的邏輯。

技術的再怎麼進化,多少都需要有人的維護?約定優於配置的思想,簡化了我們很多的操作。

2.Spring Data JPA 配置

使用 Spring Data JPA 進行持久層開發需要的四個步驟:

  • 配置 Spring 整合 JPA
  • 在 Spring 配置文件中配置 Spring Data,讓 Spring 爲聲明的接口創建代理對象。配置了<jpa:repositories> 後,Spring 初始化容器時將會掃描 base-package 指定的包目錄及其子目錄(這步我出現了問題,後面告知解決方式),爲繼承 Repository 或其子接口的接口創建代理對象,並將代理對象註冊爲 Spring Bean,業務層便可以通過 Spring 自動封裝的特性來直接使用該對象。
  • 聲明持久層的接口,該接口繼承 Repository 接口,Repository 是一個標記型接口,它不包含任何方法,如必要,Spring Data 可實現 Repository 其他子接口,其中定義了一些常用的增刪改查,以及分頁相關的方法。
  • 在接口中聲明需要的方法。Spring Data 將根據給定的策略(具體策略稍後講解)來爲其生成實現代碼。

(1)配置pom.xml文件

<dependencies>
    <!-- Spring Data和Spring相關的下載 -->
    <dependency>
        <groupId>org.springframework.data</groupId>
        <artifactId>spring-data-jpa</artifactId>
        <version>2.2.4.RELEASE</version>
    </dependency>
	<!-- JPA相關的配置 -->
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.4.10.Final</version>
    </dependency>
    <!-- 數據源 -->
    <dependency>
        <groupId>c3p0</groupId>
        <artifactId>c3p0</artifactId>
        <version>0.9.1.2</version>
    </dependency>
	<!-- 驅動包 -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.47</version>
    </dependency>
</dependencies>

(2)建立持久化類

package com.os.model;

import javax.persistence.*;
import java.util.Date;

@Entity
@Table(name = "jpa_book")
public class Book {

    private Integer bookId;
    private String bookName;
    private Double price;
    private String author;
    private Date createDate;

    public Book() {
    }

    public Book(String bookName, Double price) {
        this.bookName = bookName;
        this.price = price;
    }
    public Book(String bookName, Double price, String author, Date createDate) {
        this.bookName = bookName;
        this.price = price;
        this.author = author;
        this.createDate = createDate;
    }

    @Id
    @Column(name = "book_id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Integer getBookId() {
        return bookId;
    }

    public void setBookId(Integer bookId) {
        this.bookId = bookId;
    }
    @Column(name = "book_name")
    public String getBookName() {
        return bookName;
    }

    public void setBookName(String bookName) {
        this.bookName = bookName;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getAuthor() {
        return author;
    }

    public void setAuthor(String author) {
        this.author = author;
    }
    @Column(name = "create_date")
    public Date getCreateDate() {
        return createDate;
    }

    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bookId=" + bookId +
                ", bookName='" + bookName + '\'' +
                ", price=" + price +
                ", author='" + author + '\'' +
                ", createDate=" + createDate +
                '}';
    }
}

(3)新建持久化接口

package com.os.dao;

import com.os.model.Book;
import org.springframework.data.repository.Repository;

public interface BookDao extends Repository<Book,Integer> {
    Book getByBookName(String bookName);//BookName爲Book類中的屬性
}

(4)配置Spring核心文件

beans.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:p="http://www.springframework.org/schema/p"
       xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd http://www.springframework.org/schema/data/jpa https://www.springframework.org/schema/data/jpa/spring-jpa.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd">
    <!-- 這個配置,因爲我後面報錯誤了! -->
    <context:component-scan base-package="com.os.**.dao"></context:component-scan>
    <!-- 配置數據源 -->
    <bean class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close" id="dataSource">
        <property name="driverClass" value="com.mysql.jdbc.Driver"/>
        <property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/yf01_mybatis"/>
        <property name="user" value="root"/>
        <property name="password" value=""/>

        <!-- 配置其他屬性 -->
    </bean>

    <!-- 2. 配置 JPA 的 EntityManagerFactory -->
    <bean class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean" id="entityManagerFactory">
        <property name="dataSource" ref="dataSource"/>
        <property name="jpaVendorAdapter">
            <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
        </property>
        <property name="packagesToScan" value="com.os.**.model"/>
        <property name="jpaProperties">
            <props>
                <!-- 生成的數據表的列的映射策略 -->
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <!-- hibernate 基本屬性 -->
                <prop key="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">update</prop>
            </props>

        </property>
    </bean>
    <!-- 3.配置事務管理器 -->
    <bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"
    p:entityManagerFactory-ref="entityManagerFactory"
    />
    <!-- 4.啓動事務註解 -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    <!-- 5.配置Spring Data -->
    <!-- 注意加入JPA的命名空間 -->
    <!-- base-package: 掃描 Repository Bean 所在的 package -->
    <jpa:repositories base-package="com.os.**.dao" entity-manager-factory-ref="entityManagerFactory"/>
</beans>

(5)進行測試

package com.os.test;

import com.os.dao.BookDao;
import com.os.model.Book;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class SpringDataTest {

    private ApplicationContext applicationContext = new ClassPathXmlApplicationContext("beans.xml");
    @Test
    public void test01(){
        BookDao bookDao = applicationContext.getBean(BookDao.class);
        
        Book book = bookDao.getByBookName("西遊記");

        System.out.println("book = " + book);
    }
}

在進行測試的時候,我們報錯:EntityPathResolver must not be null!
要配置包掃描,使掃描到repository

<!--掃描spring 組件-->
<context:component-scan base-package="com.os.**.dao"></context:component-scan>

(6)運行結果

Hibernate: 
    select
        book0_.book_id as book_id1_0_,
        book0_.author as author2_0_,
        book0_.book_name as book_nam3_0_,
        book0_.create_date as create_d4_0_,
        book0_.price as price5_0_ 
    from
        spring_data_book book0_ 
    where
        book0_.book_name=?
book = Book{bookId=1, bookName='西遊記', price=100.0, author='吳承恩', createDate=2020-02-22 14:53:36.0}

基本上入門的示例就這樣了,大家就是先熟悉一下!後面會對接口進行詳細的說明!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章