Spring Boot 2 + jpa + mysql例子

来源:https://www.cnblogs.com/gdjlc/archive/2019/10/27/11748875.html
-Advertisement-
Play Games

JPA是Spring Data框架的其中一個模塊,全稱為Java Persistence API,是一個持久層規範,Hibernate框架是JPA實現之一。 本文內容: (1)項目構建 (2)數據訪問層與業務層 (3)自定義數據存儲邏輯 (4)方法名查詢 (5)使用@Query註解 ...


Spring Data框架為數據訪問提供了一個通用的模型,無論訪問哪種資料庫,都可以使用同樣的方式主要有以下幾個功能
(1)提供數據與對象映射的抽象層,同一個對象,可以被映射為不同資料庫的數據;
(2)根據數據存儲介面的方法名,自動實現數據查詢;
(3)為各個領域模型提供最基本的實現,例如增刪改查功能;
(4)可在原有邏輯的基礎上實現自定義資料庫操作邏輯。
JPA是Spring Data框架的其中一個模塊,全稱為Java Persistence API,是一個持久層規範,Hibernate框架是JPA實現之一。
本文內容:
(1)項目構建
(2)數據訪問層與業務層
(3)自定義數據存儲邏輯
(4)方法名查詢
(5)使用@Query註解

開發環境:IntelliJ IDEA 2019.2.2
Spring Boot版本:2.1.8

一、項目構建

1、新建一個名稱為demo的Spring Boot項目。
2、pom.xml

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

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

        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

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

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
        </dependency>

3、application.yml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/testdb?useSSL=false&serverTimezone=UTC
    username: root
    password:

4、打開Navicat for MySQL,在測試資料庫testdb中創建表user

CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(32) NOT NULL,
`age` tinyint(4) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8mb4;

5、實體類 User.java

package com.example.demo.entity;

import javax.persistence.*;

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;
    private String name;
    private Integer age;

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

 

二、數據訪問層與業務層

數據訪問層繼承JpaRepository後會自動實現很多內置的方法,擁有基本的資料庫CRUD操作。

1、數據訪問層 UserRepository.java

package com.example.demo.repository;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User,Integer>{
   
}

2、業務層 UserService.java

package com.example.demo.service;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Optional;

@Service
public class UserService {
    @Autowired
    UserRepository userRepository;

    public void save(User user) {
        userRepository.save(user);
    }

    public Page<User> getUserPage(Pageable pageable) {
        return userRepository.findAll(pageable);
    }

    public List<User> getUsers(){
        List<User> users = userRepository.findAll();
        return users;
    }

    public Optional<User> findById(Integer id) {
        return userRepository.findById(id);
    }

    public void deleteById(Integer id) {
        userRepository.deleteById(id);
    }
}

3、控制器 UserController.java

package com.example.demo;

import com.example.demo.entity.User;
import com.example.demo.service.UserService;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;

@RestController
public class UserController {
    @Resource
    UserService userService;

    @RequestMapping("/save")
    public String save(){
        for(int i=1;i<=20;i++){
            User user = new User();
            user.setName("a" + i);
            user.setAge(i);
            userService.save(user);
        }
        return "添加成功";
    }

    @RequestMapping("/getUserPage")
    public Page<User> getUserPage(Integer page, Integer size){
        Sort sort = new Sort(Sort.Direction.ASC, "id");
        Pageable pageable = PageRequest.of(page,size,sort);
        Page<User> users = userService.getUserPage(pageable);
        return users;
    }

    @RequestMapping("/getUsers")
    public List<User> getUsers(){
        List<User> users = userService.getUsers();
        return users;
    }

    @RequestMapping("/findById")
    public Optional<User> findById(Integer id){
        Optional<User> user = userService.findById(id);
        return user;
    }

    @RequestMapping("/deleteById")
    public String deleteById(Integer id){
        userService.deleteById(id);
        return "刪除成功";
    }
}

 

三、自定義數據存儲邏輯

繼承JpaRepository可以完成很多工作,但有時需要實現自定義數據存儲邏輯。

使用例子:

1、新建一個介面 UserRepositoryCustom.java

package com.example.demo.repository;

import com.example.demo.entity.User;

import java.util.List;

public interface UserRepositoryCustom {
    List<User> myQuery();
}

2、新建介面 UserRepositoryCustom的實現類UserRepositoryCustomImpl.java

package com.example.demo.repository.impl;

import com.example.demo.entity.User;
import com.example.demo.repository.UserRepositoryCustom;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import java.util.List;

public class UserRepositoryImpl implements UserRepositoryCustom {
    @PersistenceContext
    private EntityManager em;

    public List<User> myQuery(){
        //說明:下麵這個User不是資料庫表名,而是實體類名,並且區分大小寫
        Query q = em.createQuery("from User");
        return q.getResultList();
    }
}

3、修改原來的 UserRepository.java,同時繼承JpaRepository和UserRepositoryCustom

package com.example.demo.repository;

import com.example.demo.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User,Integer>,UserRepositoryCustom {
   
}

4、修改原來的 UserService.java,增加方法

    public List<User> myQuery(){
        return userRepository.myQuery();
    }

5、修改原來的 UserController.java,代碼略。

 

四、方法名查詢

JpaRepository支持介面規範方法名查詢,即如果在介面中定義的查詢方法符合它的命名規則,就可以不用寫實現邏輯。
例如根據對象User的欄位name進行查詢,實現類似“from User where name=?”查詢,直接在介面中寫“List<User> name(String name);”,方法名也可寫findByName,Spring Data JPA框架在進行方法名解析時,會先把方法名多餘的首碼截取掉,比如find、findBy、read、readBy、get、getBy,然後對剩下部分進行解析。另外還可以根據特定關鍵字實現條件查詢,如下表所示: 

關鍵字 例子 對應的SQL
IsNotNull findByAgeNotNull ...  where x.age not null
Like findByNameLike ...  where x.name like ?1
NotLike findByNameNotLike ...  where x.name not like ?1
StartingWith findByNameStartingWith ...  where x.name like ?1(parameter bound with appended %)
EndingWith findByNameEndingWith ...  where x.name like ?1(parameter bound with prepended %)
Containing findByNameContaining ...  where x.name like ?1(parameter bound wrapped in %)
OrderBy findByAgeOrderByName ...  where x.age = ?1 order by x.name desc
Not findByNameNot ...  where x.name <> ?1
In findByAgeIn ...  where x.age in ?1
NotIn findByAgeNotIn ...  where x.age not in ?1
True findByActiveTrue ...  where x.avtive = true
Flase findByActiveFalse ...  where x.active = false
And  findByNameAndAge ...  where x.name = ?1 and x.age = ?2
Or findByNameOrAge ...  where x.name = ?1 or x.age = ?2
Between findBtAgeBetween ...  where x.age between ?1 and ?2
LessThan findByAgeLessThan ...  where x.age  <  ?1
GreaterThan findByAgeGreaterThan ...  where x.age > ?1
After/Before ... ...
IsNull findByAgeIsNull ...  where x.age is null


使用例子:

1、修改原來的 UserRepository.java,增加方法

    @RequestMapping("/id")
    public List<User> id(Integer id){
        List<User> users = userService.id(id);
        return users;
    }
    @RequestMapping("/name")
    public List<User> name(String name){
        List<User> users = userService.name(name);
        return users;
    }
    @RequestMapping("/age")
    public List<User> age(Integer age){
        List<User> users = userService.age(age);
        return users;
    }
    @RequestMapping("/findByIdAndName")
    public List<User> findByIdAndName(Integer id, String name){
        List<User> users = userService.findByIdAndName(id, name);
        return users;
    }
    @RequestMapping("/findByAgeBetween")
    public List<User> findByAgeBetween(Integer startAge, Integer endAge){
        List<User> users = userService.findByAgeBetween(startAge, endAge);
        return users;
    }

2、修改原來的 UserService.java,增加方法

    public List<User> id(Integer id){
        return userRepository.id(id);
    }
    public List<User> name(String name){
        return userRepository.name(name);
    }
    public List<User> age(Integer age){
        return userRepository.age(age);
    }

    public List<User> findByIdAndName(Integer id, String name){
        return userRepository.findByIdAndName(id, name);
    }

    public List<User> findByAgeBetween(Integer startAge, Integer endAge){
        return userRepository.findByAgeBetween(startAge, endAge);
    }

3、修改原來的 UserController.java,代碼略。

 

五、使用@Query註解

在方法中使用@Query註解,提供JPQL(Java Presistence Query Language)或SQL語句,同樣可以實現查詢功能。

使用例子:

1、修改原來的 UserRepository.java,增加方法

    @Query("select u from User u where u.name = ?1")
    List<User> findUserName(String name);

    @Query(value = "select * from user u where u.name = ?1", nativeQuery = true)
    List<User> findNativeByName(String name);

2、修改原來的 UserService.java,增加方法 

    public List<User> findUserName(String name){
        return userRepository.findUserName(name);
    }

    public List<User> findNativeByName(String name){
        return userRepository.findNativeByName(name);
    }

3、修改原來的 UserController.java,代碼略。


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

-Advertisement-
Play Games
更多相關文章
  • 1.什麼是rpc RPC全稱為Remote Procedure Call,翻譯過來為“遠程過程調用”。目前,主流的平臺中都支持各種遠程調用技術,以滿足分散式系統架構中不同的系統之間的遠程通信和相互調用。遠程調用的應用場景極其廣泛,實現的方式也各式各樣。 2.從通信協議的層面 基於HTTP協議的(例如 ...
  • 前言 本方法基於web2py框架,使用web2py的完整網站數據包創建簡單網站。 web2py 是一個為Python語言提供的全功能Web應用框架,旨在敏捷快速的開發Web應用,具有快速、安全以及可移植的資料庫驅動的應用,相容 Google App Engine。 (百度百科:https://bai ...
  • lambda表達式是什麼? lambda 表達式是 Python 中創建匿名函數的一個特殊語法. 我稱 lambda 語法本身為 lambda 表達式,而它返回的函數我稱之為 lambda 函數。或者稱為匿名函數。 Python 的 lambda 表達式允許在一行代碼中創建一個函數並傳遞。 看下麵的 ...
  • 相信用過 Spring Boot 的朋友們一定在啟動日誌中見過類似如下的內容,比如在啟動 Spring Boot 時,控制台預設會列印 Spring Boot Logo 以及版本信息,這是 Spring Boot 固定的還是可自定義的呢? . ____ _ __ _ _ /\\ / ___'_ __ ...
  • Python 提供了兩個基本的 socket 模塊。 第一個是 Socket,它提供了標準的 BSD Sockets API。 第二個是 SocketServer, 它提供了伺服器中心類,可以簡化網路伺服器的開發。 1、Scoket類型 套接字格式: socket(family,type[,prot ...
  • 單點登陸說明:在多個應用系統中,只需要登錄一次,就可以訪問其他相互信任的應用系統。 單點註銷說明:在多個應用系統中,只需要註銷一次,就可以註銷其他相互信任的應用系統的用戶登陸狀態。 下圖是標準單點登陸流程圖: 單點登陸與單點註銷具體實現: 1. 一共有三個相互獨立的項目,cas-server;sso ...
  • 眾所周知,線段樹是algo中很重要的一項! 一.簡介 線段樹是一種二叉搜索樹,與區間樹相似,它將一個區間劃分成一些單元區間,每個單元區間對應線段樹中的一個葉結點。 使用線段樹可以快速的查找某一個節點在若幹條線段中出現的次數,時間複雜度為O(logN)。而未優化的空間複雜度為2N,實際應用時一般還要開 ...
  • (手機橫屏看源碼更方便) 註:java源碼分析部分如無特殊說明均基於 java8 版本。 註:線程池源碼部分如無特殊說明均指ThreadPoolExecutor類。 簡介 上一章我們一起重溫了下線程的生命周期(六種狀態還記得不?),但是你知不知道其實線程池也是有生命周期的呢?! 問題 (1)線程池的 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...