閱讀415 返回首頁    go 阿裏雲 go 技術社區[雲棲]


SpringBoot開發案例之整合Spring-data-jpa

即使你是天才,如果你不努力,你也會被其它人超越。

201509100645102367

扯淡

扯了那麼多篇SpringBoot的相關案例,基本每行代碼都是博主純手工編寫,附代碼案例,懂Maven和Git的小夥伴必須可以手到擒來。

SpringBoot使得開發變的更加簡潔,快速,當然被封裝的越來越深。此時你就要引入越來越多的第三方工具類,雖然你可以把搭建好的項目運行起來,卻無法理解是怎麼跑起來的。有些人帶著疑惑查閱文檔,閱讀源碼,多年以後便成了大牛;有些人不求甚解,能跑就行,就這樣幹了N年CURD。

俗話說的好,燕雀安知鴻鵠之誌哉?然子非魚又焉知魚之樂?curd並快樂著。每個人,都會有自己的成長軌跡,或平凡或精彩或或或或,快使用雙節棍,嘿嘿哈嘿。

簡介

好了,淡就扯這麼多,今天與大家分享一款"超薄"的數據訪問層框架Spring-data-jpa,依賴Hibernate,對Hibernate有一定的基礎,可以更好的理解。

什麼是spring-data

為了簡化程序與數據庫交互的代碼,spring提供了一個現成的dao層框架,spring家族提供的spring-data適用於關係型數據庫和nosql數據庫。比如之前我們講解的案例:
SpringBoot開發案例之整合mongoDB,當然還有Spring Data Solr,Spring Data Redis以及我們今天要分享的Spring Data JPA。

詳解的可以參考:官網

什麼是jpa

JPA全稱為Java持久性API(Java Persistence API),JPA是java EE 5標準之一,是一個ORM規範,由廠商來實現該規範,目前有hibernate、OpenJPA、TopLink、EclipseJPA等實現。

如何使用JPA

查詢

  • 查詢所有數據 findAll()
  • 分頁查詢 findAll(new PageRequest(0, 2))
  • 根據id查詢 findOne()
  • 根據實體類屬性查詢: findByProperty (type Property); 例如:findByAge(int age);
  • 排序: findAll(sort )
  • Sort sort = new Sort(Sort.Direction.DESC, "age").and (new Sort(Sort.Direction.DESC, "id"));
  • 條件查詢 and/or/findByAgeLessThan/LessThanEqual 等,
  • 例如: findByUsernameAndPassword(String username , String password)
  • 總數 查詢 count() 或者 根據某個屬性的值查詢總數countByAge(int age);
  • 是否存在某個id exists()

修改,刪除,新增

  • 新增:直接使用 save(T) 方法
  • 刪除: delete() 或者 deleteByProperty 例如:deleteByAge(int age) ;
  • 更新: @Modifying @Query("update Customer u set u.age = ?1 where u.id = ?2") int update(int age1 , long id);

項目結構

spring_data_jpa

相關配置

pom.xml(部分代碼,詳見源碼):

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

application.properties:

# 項目contextPath
server.context-path=/jpa
# 服務端口
server.port=8080
# session最大超時時間(分鍾),默認為30
server.session-timeout=60
# 該服務綁定IP地址,啟動服務器時如本機不是該IP地址則拋出異常啟動失敗,隻有特殊需求的情況下才配置
#server.address=192.168.1.66

# tomcat最大線程數,默認為200
server.tomcat.max-threads=100
# tomcat的URI編碼
server.tomcat.uri-encoding=UTF-8

#注意中文亂碼
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# Specify the DBMS
spring.jpa.database = MYSQL
# Show or not log for each sql query
spring.jpa.show-sql = true
# DDL mode. This is actually a shortcut for the "hibernate.hbm2ddl.auto" property. Default to "create-drop" when using an embedded database, "none" otherwise.
spring.jpa.hibernate.ddl-auto = update
# Hibernate 4 naming strategy fully qualified name. Not supported with Hibernate 5.
spring.jpa.hibernate.naming.strategy = org.hibernate.cfg.ImprovedNamingStrategy
# stripped before adding them to the entity manager)
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect

spring.jpa.properties.hibernate.hbm2ddl.auto是hibernate的配置屬性,其主要作用是:自動創建、更新、驗證數據庫表結構。該參數的幾種配置如下:

  • create:每次加載hibernate時都會刪除上一次的生成的表,然後根據你的model類再重新來生成新表,哪怕兩次沒有任何改變也要這樣執行,這就是導致數據庫表數據丟失的一個重要原因。

  • create-drop:每次加載hibernate時根據model類生成表,但是sessionFactory一關閉,表就自動刪除。

  • update:最常用的屬性,第一次加載hibernate時根據model類會自動建立起表的結構(前提是先建立好數據庫),以後加載hibernate時根據model類自動更新表結構,即使表結構改變了但表中的行仍然存在不會刪除以前的行。要注意的是當部署到服務器後,表結構是不會被馬上建立起來的,是要等應用第一次運行起來後才會。

  • validate:每次加載hibernate時,驗證創建數據庫表結構,隻會和數據庫中的表進行比較,不會創建新表,但是會插入新值。

實體類 User.java:

package com.itstyle.jpa.model;
import java.io.Serializable;
import javax.persistence.*;
/**
 * 用戶實體(此處注意引用的注解包為javax.persistence*下麵的)
 * 創建者 科幫網
 * 創建時間 2017年7月25日
 *
 */
@Entity
@Table(name = "sys_user")
public class User implements Serializable{
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Long id;
    @Column(nullable = false, name = "name")
    private String name;
    @Column(nullable = false, name = "age")
    private Integer age;
    --- 省略 get set 方法
}

數據操作UserRepository.java:

/**
 * 數據操作層
 * 創建者 科幫網
 * 創建時間 2017年7月25日
 *
 */
public interface UserRepository extends JpaRepository<User, Long> {

    User findByName(String name);

    User findByAge(Integer age);

    User findByNameAndAge(String name, Integer age);

    List<User> findByNameLike(String name);

    @Query("from User u where u.name=:name")
    User findUser(@Param("name") String name);

}

小夥伴沒有沒有發現,我們隻是定義了一個方法而已,怎麼就這麼奇妙的實現的對應功能?其實這是Spring-data-jpa的新特性,通過解析方法名創建查詢。更多解析說明如下:

And => 等價於 SQL 中的 and 關鍵字 例如:findByUsernameAndPassword(String user, Striang pwd);
Or => 等價於 SQL 中的 or 關鍵字,例如:findByUsernameOrAddress(String user, String addr);
Between => 等價於 SQL 中的 between 關鍵字,例如:SalaryBetween(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) ,方法的參數可以是 Collection 類型,也可以是數組或者不定長參數;
NotIn => 等價於 SQL 中的 "not in",例如: findByUsernameNotIn(Collection userList) ,方法的參數可以是 Collection 類型,也可以是數組或者不定長參數;
創建一個按單字段排序的Sort對象: new Sort(Sort.Direction.DESC, "description").and(new Sort(Sort.Direction.ASC, "id"))

最終測試類SpringbootJpaApplication.java:

package com.itstyle.jpa;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import com.itstyle.jpa.model.User;
import com.itstyle.jpa.repository.UserRepository;

@SpringBootApplication
public class SpringbootJpaApplication implements CommandLineRunner {

    @Autowired
    private UserRepository userRepository;

    public static void main(String[] args) {
        SpringApplication.run(SpringbootJpaApplication.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        try {
            User user = new User();
            user.setName("張三");
            user.setAge(20);
            userRepository.save(user);
            List<User> u = userRepository.findByNameLike("%張三%");
            System.out.println(u.size());
            User  us =  userRepository.findByAge(20);
            System.out.println(us.getAge());
            us =  userRepository.findByName("這是你幹");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

偶遇問題

No identifier specified for entity:

檢查一下包是否引入正確,引入一下:

import javax.persistence.*;

中文亂碼問題:

spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8

在高版本mysql中需要指定是否進行SSL連接

spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf-8&useSSL=false

代碼:https://git.oschina.net/52itstyle/spring-data-jpa

作者: 小柒

出處: https://blog.52itstyle.com

本文版權歸作者雲棲社區所有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁麵明顯位置給出, 如有問題, 可郵件(345849402@qq.com)谘詢。

最後更新:2017-07-26 12:03:54

  上一篇:go  安全自動化在於信任,而非技術
  下一篇:go  多用途數據主導“物聯網未來”的實施