Spring Boot 2 + jpa + mysql例子


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,代碼略。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM