Spring Data JPA 初體驗

来源:https://www.cnblogs.com/kias2004/archive/2018/05/16/9048170.html
-Advertisement-
Play Games

一,JPA相關的概念 1. JPA概述 全稱是:JavaPersistence API。是SUN公司推出的一套基於ORM的規範。 Hibernate框架中提供了JPA的實現。 JPA通過JDK 5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到資料庫中。 2.JPA優勢 標準 ...


一,JPA相關的概念

  1. JPA概述

    全稱是:JavaPersistence API。是SUN公司推出的一套基於ORM的規範。

    Hibernate框架中提供了JPA的實現。

    JPA通過JDK 5.0註解或XML描述對象-關係表的映射關係,並將運行期的實體對象持久化到資料庫中。

2.JPA優勢

標準化:

     JPA是 JCP 組織發佈的 Java EE 標準之一,因此任何聲稱符合 JPA 標準的框架都遵循同樣的架構,提供相同的訪問API,這保證了基於JPA開發的企業應用能夠經過少量的修改就能夠在不同的JPA框架下運行。

容器級特性的支持:

      JPA框架中支持大數據集、事務、併發等容器級事務,這使得 JPA 超越了簡單持久化框架的局限,在企業應用發揮更大的作用。

簡單方便:

     JPA的主要目標之一就是提供更加簡單的編程模型:在JPA框架下創建實體和創建Java 類一樣簡單,沒有任何的約束和限制,只需要使用javax.persistence.Entity進行註釋,JPA的框架和介面也都非常簡單,沒有太多特別的規則和設計模式的要求,開發者可以很容易的掌握。JPA基於非侵入式原則設計,因此可以很容易的和其它框架或者容器集成。

查詢能力:

     JPA的查詢語言是面向對象而非面向資料庫的,它以面向對象的自然語法構造查詢語句,可以看成是HibernateHQL的等價物。JPA定義了獨特的JPQL(Java Persistence Query Language),JPQL是EJB QL的一種擴展,它是針對實體的一種查詢語言,操作對象是實體,而不是關係資料庫的表,而且能夠支持批量更新和修改、JOIN、GROUP BY、HAVING 等通常只有 SQL 才能夠提供的高級查詢特性,甚至還能夠支持子查詢。

高級特性:

          JPA中能夠支持面向對象的高級特性,如類之間的繼承、多態和類之間的複雜關係,這樣的支持能夠讓開發者最大限度的使用面向對象的模型設計企業應用,而不需要自行處理這些特性在關係資料庫的持久化。

3.學習JPA要明確的

JPA是一套ORM規範,hibernate實現了JPA規範

hibernate中有自己的獨立ORM操作資料庫方式,也有JPA規範實現的操作資料庫方式。

在資料庫增刪改查操作中,我們hibernate和JPA的操作都要會。

二, JPA入門

1.需求介紹

    本章節我們實現基於JPA註解的對象關係映射,配置實體類和資料庫表的對應關係.  並且使用JPA規範中的方法實現CRUD操作。

2.JPA環境搭建

2.1 拷貝jar包到工程中

2.2 編寫實體類並使用註解配置

  • 使用註解代替配置文件

        @Entity
         @Table(name="t_user")
         public class User {
      @Id
      @GeneratedValue(strategy=GenerationType.IDENTITY)
      @Column(name="uid")
      private Integer uid;
    
    @Column(name="uname")
    private String uname;
    
    @Column(name="uage")
    private int uage;
    
    public Integer getUid() {
        return uid;
    }
    public void setUid(Integer uid) {
        this.uid = uid;
    }
    public String getUname() {
        return uname;
    }
    public void setUname(String uname) {
        this.uname = uname;
    }
    public int getUage() {
        return uage;
    }
    public void setUage(int uage) {
        this.uage = uage;
    }
    @Override
    public String toString() {
        return "User [uid=" + uid + ", uname=" + uname + ", uage=" + uage + "]";
    }

    }

2.3創建配置文件

  • 要求在src下麵的META-INF文件夾下麵創建一個名稱為persistence.xml的文件。

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence  
      http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
    version="1.0">
    <!--Name屬性用於定義持久化單元的名字 (name必選,空值也合法); transaction-type 指定事務類型(可選) 取值: JTA:預設值 
        RESOURCE_LOCAL -->
    <persistence-unit name="myPersistUnit" transaction-type="RESOURCE_LOCAL">
        <!-- 三引入映射 -->
        <class>com.itheima.bean.User</class>
        <properties>
            <!-- 一,連接資料庫的基本項 -->
            <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect" />
            <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" />
            <property name="hibernate.connection.url" value="jdbc:mysql:///jpa" />
            <property name="hibernate.connection.username" value="root" />
            <property name="hibernate.connection.password" value="123456" />
            <!-- 二,選配 -->
            <property name="hibernate.show_sql" value="true"/>
            <property name="hibernate.format_sql" value="true"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>
        </properties>
    </persistence-unit>

2.4編寫工具類

  • 用於獲取JPA的操作資料庫對象EntityManager

      public final class JPAUtil {
        //JPA的實體管理器工廠:相當於Hibernate的SessionFactory
    private static EntityManagerFactory em;
    //使用靜態代碼塊賦值
    static {
        //註意:該方法參數必須和persistence.xml中persistence-unit標簽name屬性取值一致
        em = Persistence.createEntityManagerFactory("myPersistUnit");
    }
    /**
    • 使用管理器工廠生產一個管理器對象
      • @return
        */
        public static EntityManager getEntityManager() {
        return em.createEntityManager();
        }
        }

2.5編寫單元測試

  • 保存用戶

          @Test
        public void fun01(){
        User user = new User();
        user.setUname("張三");
        user.setUage(18);
    
        EntityManager manager = JPAUtil.getEntityManager();
        EntityTransaction transaction = manager.getTransaction();
        transaction.begin();
        manager.persist(user);
        transaction.commit();
        manager.close();
          }

3.常用註解說明

  • @Entity
    作用:指定當前類是實體類。寫上此註解用於在創建SessionFactory/EntityManager時,載入映射配置。
  • @Table
    作用:指定實體類和表之間的對應關係。
    屬性:
    name:指定資料庫表的名稱
  • @Id
    作用:指定當前欄位是主鍵。
  • @GeneratedValue
    作用:指定主鍵的生成方式。JPA的主鍵生成方式詳解見2.4小節的說明。
    屬性:
    strategy :指定主鍵生成策略。JPA支持四種生成策略,具體介紹看4小節。
  • @Column
    作用:指定實體類屬性和資料庫表之間的對應關係
    屬性:
    name:指定資料庫表的列名稱。
    unique:是否唯一
    nullable:是否可以為空
    inserttable:是否可以插入
    updateable:是否可以更新
    columnDefinition: 定義建表時創建此列的DDL
    secondaryTable: 從表名。如果此列不建在主表上(預設建在主表),該屬性定義該列所在從表的名字。

4.主鍵生成策略

4.1JPA提供的類型

通過annotation(註解)來映射hibernate實體的,基於annotation的hibernate主鍵標識為@Id, 其生成規則由  @GeneratedValue設定的.這裡的@id和@GeneratedValue都是JPA的標準用法。JPA提供的四種標準用法為TABLE,SEQUENCE,IDENTITY,AUTO。具體說明如下:
  • IDENTITY:主鍵由資料庫自動生成(主要是自動增長型)
    用法:
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long uid;
  • SEQUENCE:根據底層資料庫的序列來生成主鍵,條件是資料庫支持序列。 (用在oracle)
    用法:

    @Id  
    @GeneratedValue(strategy = GenerationType.SEQUENCE,generator="payablemoney_seq")    
    @SequenceGenerator(name="payablemoney_seq", sequenceName="seq_payment")  

    說明:
    @SequenceGenerator源碼中的定義
    @Target({TYPE, METHOD, FIELD})
    @Retention(RUNTIME)
    public @interface SequenceGenerator {
    String name();
    String sequenceName() default "";
    int initialValue() default 0;
    int allocationSize() default 50;
    }
    name:表示該表主鍵生成策略的名稱,它被引用在@GeneratedValue中設置的“generator”值中。
    sequenceName:屬性表示生成策略用到的資料庫序列名稱。

  • AUTO:主鍵由程式控制. 自動創建一張表
    用法:

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
  • TABLE:使用一個特定的資料庫表格來保存主鍵(瞭解)
    用法:

    @Id
    @GeneratedValue(strategy = GenerationType.TABLE, generator="payablemoney_gen")
    @TableGenerator(name = "pk_gen",
    table="tb_generator",
    pkColumnName="gen_name",
    valueColumnName="gen_value",
    pkColumnValue="PAYABLEMOENY_PK",
    allocationSize=1
    )

    這裡應用表tb_generator,定義為 :

    CREATE TABLE tb_generator (
    id NUMBER NOT NULL,
    gen_name VARCHAR2(255) NOT NULL,
    gen_value NUMBER NOT NULL,
    PRIMARY KEY(id)
    )

    插入紀錄,供生成主鍵使用:
    INSERT INTO tb_generator(id, gen_name, gen_value)VALUES (1,PAYABLEMOENY_PK', 1);
    在主鍵生成後,這條紀錄的value值,按allocationSize遞增。

     @TableGenerator的定義:

    @Target({TYPE, METHOD, FIELD})
    @Retention(RUNTIME)
    public @interface TableGenerator {
    String name();
    String table() default "";
    String catalog() default "";
    String schema() default "";
    String pkColumnName() default "";
    String valueColumnName() default "";
    String pkColumnValue() default "";
    int initialValue() default 0;
    int allocationSize() default 50;
    UniqueConstraint[] uniqueConstraints() default {};
    }
    其中屬性說明:
    name:
    表示該表主鍵生成策略的名稱,它被引用在@GeneratedValue中設置的“generator”值中。
    table:
    表示表生成策略所持久化的表名,例如,這裡表使用的是資料庫中的“tb_generator”。
    catalog和schema:
    具體指定表所在的目錄名或是資料庫名。
    pkColumnName:
    屬性的值表示在持久化表中,該主鍵生成策略所對應鍵值的名稱。例如在“tb_generator”中將“gen_name”作為主鍵的鍵值
    valueColumnName:
    屬性的值表示在持久化表中,該主鍵當前所生成的值,它的值將會隨著每次創建累加。例如,在“tb_generator”中將“gen_value”作為主鍵的值
    pkColumnValue:
    屬性的值表示在持久化表中,該生成策略所對應的主鍵。例如在“tb_generator”表中,將“gen_name”的值為“CUSTOMER_PK”。
    initialValue:
    表示主鍵初識值,預設為0。
    allocationSize:
    表示每次主鍵值增加的大小,例如設置成1,則表示每次創建新記錄後自動加1,預設為50。
    UniqueConstraint:
    與@Table標記中的用法類似

4.2自定義類型

JPA提供了四種類型,有的情況下是不能滿足使用的. eg: 主鍵類型是字元串,需要uuid,這個時候就需要自定義類型.

5.JPA的CRUD操作

三,JPA一對多配置

1.註解詳解

  • OneToMany
    作用:
    建立一對多的關係映射
    屬性:
    targetEntityClass:指定多的多方的類的位元組碼
    mappedBy:指定從表實體類中引用主表對象的名稱。
    cascade:指定要使用的級聯操作
    fetch:指定是否採用延遲載入
    orphanRemoval:是否使用孤兒刪除
  • @ManyToOne
    作用:
    建立多對一的關係
    屬性:
    targetEntityClass:指定一的一方實體類位元組碼
    cascade:指定要使用的級聯操作
    fetch:指定是否採用延遲載入
    optional:關聯是否可選。如果設置為false,則必須始終存在非空關係。
  • @JoinColumn
    作用:
    用於定義主鍵欄位和外鍵欄位的對應關係。
    屬性:
    name:指定外鍵欄位的名稱
    referencedColumnName:指定引用主表的主鍵欄位名稱
    unique:是否唯一。預設值不唯一
    nullable:是否允許為空。預設值允許。
    insertable:是否允許插入。預設值允許。
    updatable:是否允許更新。預設值允許。
    columnDefinition:列的定義信息。

2.使用JPA配置一對多

  • 一的一方實體(Category)

      @Entity
      @Table(name="category")
      public class Category {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="cid")
    private Integer cid;
    
    @Column(name="cname")
    private String cname;
    
    //在一的一方,用一個集合表示和product的關係
    @OneToMany(targetEntity=Product.class,mappedBy="category")
    private Set<Product> products = new HashSet<Product>();
    
    public Integer getCid() {
        return cid;
    }
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    public String getCname() {
        return cname;
    }
    public void setCname(String cname) {
        this.cname = cname;
    }
    public Set<Product> getProducts() {
        return products;
    }
    public void setProducts(Set<Product> products) {
        this.products = products;
        }
      }
  • 多的一方實體(Product)

       @Entity
      @Table(name="product")
      public class Product {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Integer pid;
    
    @Column(name="pname")
    private String pname;
    
    @Column(name="price")
    private double price;
    //用一個對象表示,當前商品屬於哪個類別
    @ManyToOne(targetEntity=Category.class)
    @JoinColumn(name="cid",referencedColumnName="cid")
    private Category category;
    
    public Integer getPid() {
        return pid;
    }
    
    public void setPid(Integer pid) {
        this.pid = pid;
    }
    
    public String getPname() {
        return pname;
    }
    
    public void setPname(String pname) {
        this.pname = pname;
    }
    
    public double getPrice() {
        return price;
    }
    
    public void setPrice(double price) {
        this.price = price;
    }
    
    public Category getCategory() {
        return category;
    }
    
    public void setCategory(Category category) {
        this.category = category;
    }
    
      }

3.一對多關係的CRUD

四,JPA配置多對多

1,註解詳解

  • @ManyToMany
    作用:
    用於映射多對多關係
    屬性:
    cascade:配置級聯操作。
    fetch:配置是否採用延遲載入。
    targetEntity:配置目標的實體類。映射多對多的時候不用寫。
  • @JoinTable
    作用:
    針對中間表的配置
    屬性:
    name:配置中間表的名稱
    joinColumns:中間表的外鍵欄位關聯當前實體類所對應表的主鍵欄位
    inverseJoinColumn:中間表的外鍵欄位關聯對方表的主鍵欄位
  • @JoinColumn
    作用:
    用於定義主鍵欄位和外鍵欄位的對應關係。
    屬性:
    name:指定外鍵欄位的名稱
    referencedColumnName:指定引用主表的主鍵欄位名稱
    unique:是否唯一。預設值不唯一
    nullable:是否允許為空。預設值允許。
    insertable:是否允許插入。預設值允許。
    updatable:是否允許更新。預設值允許。
    columnDefinition:列的定義信息。

2,使用JPA配置多對多

  • Student.java

     @Entity
      @Table(name = "student")
      public class Student {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "sid")
    private Integer sid;
    
    @Column(name = "sname")
    private String sname;
    
    // 中間表s_c_table欄位關聯sid表的主鍵欄位sid,// 中間表s_c_table的欄位cid關聯表的主鍵cid
    @ManyToMany
    @JoinTable(name = "s_c_table", // 中間表的名稱
            joinColumns = { @JoinColumn(name = "sid", referencedColumnName = "sid") }, 
            inverseJoinColumns = {@JoinColumn(name = "cid", referencedColumnName = "cid") })
    private Set<Course> courses = new HashSet<Course>();
    
    public Integer getSid() {
        return sid;
    }
    
    public void setSid(Integer sid) {
        this.sid = sid;
    }
    
    public String getSname() {
        return sname;
    }
    
    public void setSname(String sname) {
        this.sname = sname;
    }
    
    public Set<Course> getCourses() {
        return courses;
    }
    
    public void setCourses(Set<Course> courses) {
        this.courses = courses;
    }

    }

  • Course.java

      @Entity
      @Table(name="course")
      public class Course {
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="cid")
    private Integer cid;
    
    @Column(name="cname")
    private String cname;
    
    @ManyToMany(mappedBy="courses")
    private Set<Student> students = new HashSet<Student>();
    
    public Integer getCid() {
        return cid;
    }
    
    public void setCid(Integer cid) {
        this.cid = cid;
    }
    
    public String getCname() {
        return cname;
    }
    
    public void setCname(String cname) {
        this.cname = cname;
    }
    
    public Set<Student> getStudents() {
        return students;
    }
    
    public void setStudents(Set<Student> students) {
        this.students = students;
    }

    }

五,Spring Data JPA

1.概述

1.1什麼是SpringDataJPA

Spring提供的一個用於簡化JPA開發的框架。可以極大的簡化JPA的寫法,可以在幾乎不用寫實現的情況下,實現對數據的訪問和操作。除了CRUD外,還包括如分頁、排序等一些常用的功能。下麵的示例代碼即可完成數據保存的操作,而無需具體實現類

1.2SpringDataJPA的核心介面

  • Repository:最頂層的介面,是一個空的介面,目的是為了統一所有Repository的類型,且能讓組件掃描的時候自動識別。
  • CrudRepository :是Repository的子介面,提供CRUD的功能
  • PagingAndSortingRepository:是CrudRepository的子介面,添加分頁和排序的功能
  • JpaRepository:是PagingAndSortingRepository的子介面,增加了一些實用的功能,比如:批量操作等。
  • JpaSpecificationExecutor:用來做負責查詢的介面,類似條件(QBC)查詢
  • Specification:是Spring Data JPA提供的一個查詢規範,要做複雜的查詢,只需圍繞這個規範來設置查詢條件即可

2.SpringDataJPA入門

2.1創建Java項目,導入jar包

  • spring相關的jar包
  • hibernate相關jar包
  • springDaataJpa相關的jar: spring-data-commons.jar 、 spring-data-jpa.jar 、 hibernate-entitymanager-5.0.7.Final.jar

2.2創建持久化類

  • BaseDict

     package com.itheima.crm.bean;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    
    import org.hibernate.annotations.GenericGenerator;
    
    @Entity
    @Table(name="base_dict")
    public class BaseDict {
    
    @Id
    @GeneratedValue(generator="sysuuid")
    @GenericGenerator(name = "sysuuid", strategy = "uuid")
    @Column(name="dict_id")
    private String dict_id;
    
    @Column(length=20)
    private String dict_type_code;
    @Column(length=40)
    private String dict_type_name;
    @Column(length=40)
    private String dict_item_name;
    @Column(length=40)
    private String dict_item_code;
    @Column
    private int dict_sort;
    @Column(length=40)
    private String dict_enable;
    @Column(length=40)
    private String dict_memo;
    
    public String getDict_id() {
        return dict_id;
    }
    public void setDict_id(String dict_id) {
        this.dict_id = dict_id;
    }
    public String getDict_type_code() {
        return dict_type_code;
    }
    public void setDict_type_code(String dict_type_code) {
        this.dict_type_code = dict_type_code;
    }
    public String getDict_type_name() {
        return dict_type_name;
    }
    public void setDict_type_name(String dict_type_name) {
        this.dict_type_name = dict_type_name;
    }
    public String getDict_item_name() {
        return dict_item_name;
    }
    public void setDict_item_name(String dict_item_name) {
        this.dict_item_name = dict_item_name;
    }
    public String getDict_item_code() {
        return dict_item_code;
    }
    public void setDict_item_code(String dict_item_code) {
        this.dict_item_code = dict_item_code;
    }
    public int getDict_sort() {
        return dict_sort;
    }
    public void setDict_sort(int dict_sort) {
        this.dict_sort = dict_sort;
    }
    public String getDict_enable() {
        return dict_enable;
    }
    public void setDict_enable(String dict_enable) {
        this.dict_enable = dict_enable;
    }
    public String getDict_memo() {
        return dict_memo;
    }
    public void setDict_memo(String dict_memo) {
        this.dict_memo = dict_memo;
    }
    @Override
    public String toString() {
        return "BaseDict [dict_id=" + dict_id + ", dict_type_code=" + dict_type_code + ", dict_type_name="
                + dict_type_name + ", dict_item_name=" + dict_item_name + ", dict_item_code=" + dict_item_code
                + ", dict_sort=" + dict_sort + ", dict_enable=" + dict_enable + ", dict_memo=" + dict_memo + "]";
    }
    
    }

2.3創建applicationContext.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:context="http://www.springframework.org/schema/context"
    xmlns:tx="http://www.springframework.org/schema/tx"
    xmlns:jpa="http://www.springframework.org/schema/data/jpa"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd
        http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd">
    <!--引入jdbc.properties  -->
    <context:property-placeholder location="classpath:jdbc.properties"/>
    
    <context:component-scan base-package="com.itheima"/>
    
    <!--配置數據源  -->
    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
        <property name="driverClass" value="${jdbc.driver}"></property>
        <property name="jdbcUrl" value="${jdbc.url}"></property>
        <property name="user" value="${jdbc.user}"></property>
        <property name="password" value="${jdbc.password}"></property>
    </bean>
    
    <!-- 配置entityManagerFactory -->
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
        <!--1.,配置數據源(代替四個基本項)  -->
        <property name="dataSource" ref="dataSource"></property>
        <!--2,配置選配項  -->
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
            </props>
        </property>
        <!--3配置包掃描路徑  -->
        <property name="packagesToScan" value="com.itheima.crm.bean"></property>
        <!-- 4.,配置JPA適配 -->
        <property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
    </bean>
    <!--註冊適配器  -->
    <bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
    
    <!--配置事務管理器  -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"></property>
    </bean>
    <!--配置註解事務  -->
    <tx:annotation-driven transaction-manager="transactionManager"/>
    
    <!--配置JPADao,生成代理對象 -->
    <jpa:repositories base-package="com.itheima.crm.dao"></jpa:repositories>
    
    
    <!--配置數據字典模塊  -->
    <bean id="baseDictService" class="com.itheima.crm.service.impl.BaseDictServiceImpl">
        <property name="baseDictDao" ref="baseDictDao"></property>
    </bean>
    
    </beans>

2.4創建Dao

  public interface BaseDictDao extends PagingAndSortingRepository<BaseDict, String>{
    }

3.查詢方法命名規則及JPQL語法生成

3.1概述

SpringDataJPA預設情況下, 提供了查詢的相關的方法, 基本上能滿足我們80%左右的需要. 但是還有一些是沒有滿足的,我們可以遵循它的命名規範來定義方法名. 如果沒有滿足命名規範的, 可以在方法上加@Query註解來寫語句

3.2 JPA命令規範

      關鍵字                               方法命名                                    sql where字句               
      And                           findByNameAndPwd                        where name= ? and pwd =?  
      Or                                findByNameOrSex                         where name= ? or sex=?    
      Is,Equals                 findById,findByIdEquals                 where id= ?               
      Between                   findByIdBetween                         where id between ? and ?  
      LessThan                      findByIdLessThan                            where id < ?              
      LessThanEquals            findByIdLessThanEquals                  where id <= ?             
      GreaterThan               findByIdGreaterThan                     where id > ?              
      GreaterThanEquals findByIdGreaterThanEquals       where id > = ?            
      After                             findByIdAfter                                   where id > ?              
      Before                        findByIdBefore                                  where id < ?              
      IsNull                        findByNameIsNull                            where name is null        
      isNotNull,NotNull         findByNameNotNull                       where name is not null    
       Like                             findByNameLike                          where name like ?         
      NotLike                       findByNameNotLike                       where name not like ?     
      StartingWith              findByNameStartingWith                  where name like '?%'      
      EndingWith                findByNameEndingWith                    where name like '%?'      
      Containing                findByNameContaining                    where name like '%?%'     
      OrderBy                   findByIdOrderByXDesc                    where id=? order by x desc
      Not                           findByNameNot                           where name <> ?           
      In                                findByIdIn(Collection<?> c)             where id in (?)           
      NotIn                         findByIdNotIn(Collection<?> c)          where id not  in (?)      
      True                          findByAaaTue                            where aaa = true          
      False                         findByAaaFalse                          where aaa = false         
      IgnoreCase                findByNameIgnoreCase                    where UPPER(name)=UPPER(?)
  • eg

         public interface StandardRepository extends JpaRepository<Standard, Long> {
    
    // JPA的命名規範
    List<Standard> findByName(String name);
    
    // 自定義查詢,沒有遵循命名規範
    @Query("from Standard where name = ?")
    Standard findByNamexxxx(String name);
    
    // 遵循命名規範,執行多條件查詢
    Standard findByNameAndMaxLength(String name, Integer maxLength);
    
    // 自定義多條件查詢
    @Query("from Standard where name = ?2 and maxLength = ?1")
    Standard findByNameAndMaxLengthxxx(Integer maxLength, String name);
    
    // 使用標準SQL查詢
    @Query(value = "select * from T_STANDARD where C_NAME = ? and C_MAX_LENGTH = ?",
            nativeQuery = true)
    Standard findByNameAndMaxLengthxx(String name, Integer maxLength);
    
    // 模糊查詢
    Standard findByNameLike(String name);
    
    @Modifying // 代表本操作是更新操作
    @Transactional // 事務註解
    @Query("delete from Standard where name = ?")
    void deleteByName(String name);
    
    @Modifying // 代表本操作是更新操作
    @Transactional // 事務註解
    @Query("update Standard set maxLength = ? where name = ?")
    void updateByName(Integer maxLength, String name);
    }

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 索引: 開源Spring解決方案--lm.solution 參看代碼 GitHub: pom.xml WebConfig.java index.jsp upload.jsp FileUploadController.java Files_Utils_DG.java 一、要點講解 1.引入文件上傳下載 ...
  • 在項目開發過程中或者是性能優化中,經常會有要查看執行sql的情況,然而Laravel日誌預設不記錄執行sql。好在留有相關介面,我們可以很方便的就是想SQl日誌功能。 2.創建SqlListener監聽器 1 > php artisan event:generate 在handle方法中編寫記錄sq ...
  • 爬蟲的原理 現在,讓我們踩下油門,開始飆車!!! 既然我們要基於面向對象的思想寫這個爬蟲,那麼我們就需要把這個爬蟲寫成一個類。 註意力不要放在妹子上!!! 我們定位到妹子的url,我們可以很容易的寫出妹子url的xpath。 調出開發者工具(註意力不要放在妹子上!!!) 兩種解決辦法: 下麵我們使用 ...
  • 筆者也是一個linux新手,最近在學習linux相關的東西,本人是一個node愛好者,想在linux上寫一個linux服務,我的環境是centeros7,用putty鏈接遠端的伺服器,要想讓服務在服務端運行 常用的方法是: 運用nohup命令將服務重定向到output.log文件中,這樣就可以實現l ...
  • __new__ : 這個方法的作用主要是創建一個實例,在創建實例時首先會調用 __new__方法 ,然後調用__init__對實例進行初始化, 如果想修改 __new__ 這個方法,那麼最後要 return 調用一下父類的 __new__ 方法,因為裡面有創建實例的過程,除非你在自定義的 __new ...
  • final final在Java中是一個保留的關鍵字,可以聲明成員變數、方法、類以及本地變數。一旦你將引用聲明作final,你將不能改變這個引用了,編譯器會檢查代碼,如果你試圖將變數再次初始化的話,編譯器會報編譯錯誤。 修飾變數(例如Math類的PI=3.1415926就是變數不可修改) 用fina ...
  • 1:/usr/lib/ruby/gems/1.8/gems/redis-3.0.7/lib/redis/client.rb:97:in `call': ERR Slot 16011 is already busy (Redis::CommandError)這是由於上一次配置集群失敗時留下的配置信息導 ...
  • 摘要: 考慮到VBA寫不好但是有對批量化處理數據的需求,所以推薦Python自帶的xlrd和xlwt庫對Excel表格數據進行讀寫操作。簡明的代碼風格很適合上手。 首先安裝對應的xlrd和xlwt 打開cmd命令視窗輸入pip install xlrd和pip install xlwt就可以安裝。之 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...