我是這樣使用SpringBoot(使用 Spring data jpa)

目錄

Spring data jpa是Spring使用jpa的組件。采用Hibernate實(shí)現(xiàn)jpa能力。但是比自行Spring和Hibernate整合使用方便很多。

引入組件

在pom.xml中加入組件,這里連接MySQL數(shù)據(jù)庫(kù),所以引入mysql-connector-java

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

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

創(chuàng)建模型

jpa講究的是面向?qū)ο蟮乃季S,降低了數(shù)據(jù)庫(kù)的可見(jiàn)性。它可以完全不去寫(xiě)SQL語(yǔ)句完成對(duì)數(shù)據(jù)庫(kù)中數(shù)據(jù)的增刪改查操作。一個(gè)數(shù)據(jù)模型對(duì)應(yīng)一個(gè)數(shù)據(jù)表。我們對(duì)數(shù)據(jù)的操作關(guān)心對(duì)這個(gè)對(duì)象的業(yè)務(wù)過(guò)程。
創(chuàng)建一個(gè)模型,名稱為Account。這個(gè)對(duì)象是用于描述系統(tǒng)中的賬戶。創(chuàng)建名稱為com.biboheart.demos.domain的package,在此package中新建類Account。如下:

package com.biboheart.demos.domain;

import lombok.Data;

import javax.persistence.*;

@Data
@Entity // 表示這是一個(gè)jpa模型
@Table(name = "bh_account") // 表示對(duì)應(yīng)數(shù)據(jù)表bh_account
public class Account {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer id;  // ID
    private String sn; // 賬戶編號(hào)
    private String username; // 用戶名
    private String mobile; // 手機(jī)號(hào)
    private String password; // 密碼
    private Long createTime; // 創(chuàng)建時(shí)間
}

創(chuàng)建接口

創(chuàng)建模型后,執(zhí)行數(shù)據(jù)增刪查改操作。spring data jpa提供了約定的方式來(lái)簡(jiǎn)化使用。它約定,繼承JpaRepository的接口,在接口中定義的函數(shù)名稱就可以執(zhí)行不同的數(shù)據(jù)操作。復(fù)雜的可以用注解來(lái)完成。如findBySn函數(shù),就可以實(shí)現(xiàn)用戶sn匹配查找賬戶。通過(guò)這樣約定的情況下使用spring data jpa,不需要實(shí)現(xiàn)這個(gè)接口。寫(xiě)了這個(gè)接口,就可以將這個(gè)接口注入到業(yè)務(wù)中使用。
在com.biboheart.demos.repository中創(chuàng)建AccountRepository。如下代碼:

package com.biboheart.demos.repository;

import com.biboheart.demos.domain.Account;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface AccountRepository extends JpaRepository<Account, Integer>, JpaSpecificationExecutor<Account> {
    Account findBySn(String sn);
}

在業(yè)務(wù)代碼中如下方法注入,就可以通過(guò)accountRepository.findBySn(sn)查找匹配到sn的用戶。

    @Autowired
    private AccountRepository accountRepository;

配置連接

這時(shí)候,jpa并不知道Account對(duì)應(yīng)的是哪個(gè)數(shù)據(jù)庫(kù)的表。要配置數(shù)據(jù)庫(kù)連接。在application.yml中配置spring.datasource,spring boot中項(xiàng)目中許多框架就可以自動(dòng)得到數(shù)據(jù)庫(kù)的連接參數(shù)。配置spring.jpa設(shè)置spring data jpa的屬性。

server:
  port: 80
spring:
  profiles:
    active: dev
  resources:
    static-locations: file:/usr/local/bhhello/static, classpath:/static/
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/bh_springbootdemo?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8&useSSL=false&autoReconnect=true
    username: root
    password: root
  jpa:
    database: MYSQL
    database-platform: org.hibernate.dialect.MySQL5Dialect
    show-sql: false
    hibernate:
      ddl-auto: update
    properties:
      hibernate:
        format_sql: false
custom:
  name: bhhello-app

測(cè)試連接

在com.biboheart.demos.service中創(chuàng)建接口AccountService,在com.biboheart.demos.service.impl中創(chuàng)建實(shí)現(xiàn)AccountServiceImpl。代碼如下:

package com.biboheart.demos.service;

import com.biboheart.demos.domain.Account;

public interface AccountService {
    /**
     * 保存賬戶
     * @param account 賬戶對(duì)像
     * @return 保存后的賬戶對(duì)像,如果保存失敗返回null
     */
    Account save(Account account);

    /**
     * 查詢賬戶
     * @param sn 賬戶編號(hào)
     * @return 查詢結(jié)果,賬戶對(duì)像
     */
    Account load(String sn);
}

實(shí)現(xiàn)(這里未做容錯(cuò)處理):

package com.biboheart.demos.service.impl;

import com.biboheart.brick.utils.CheckUtils;
import com.biboheart.demos.domain.Account;
import com.biboheart.demos.repository.AccountRepository;
import com.biboheart.demos.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.UUID;

@Service
public class AccountServiceImpl implements AccountService {
    // 注入account數(shù)據(jù)庫(kù)訪問(wèn)對(duì)象
    @Autowired
    private AccountRepository accountRepository;

    @Override
    public Account save(Account account) {
        if (CheckUtils.isEmpty(account.getSn())) {
            // 生成賬戶編號(hào)
            String sn = UUID.randomUUID().toString().replace("-", "").toUpperCase();
            while (null != accountRepository.findBySn(sn)) {
                sn = UUID.randomUUID().toString().replace("-", "").toUpperCase();
            }
            account.setSn(sn);
        }
        account = accountRepository.save(account);
        return account;
    }

    @Override
    public Account load(String sn) {
        Account account = accountRepository.findBySn(sn);
        return account;
    }
}

開(kāi)放兩個(gè)API,實(shí)現(xiàn)創(chuàng)建賬戶與查詢賬戶的功能。在com.biboheart.demos.controller中創(chuàng)建AccountController類。

package com.biboheart.demos.controller;

import com.biboheart.brick.model.BhResponseResult;
import com.biboheart.demos.domain.Account;
import com.biboheart.demos.service.AccountService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class AccountController {
    @Autowired
    private AccountService accountService;
    
    @RequestMapping(value = "/public/userapi/account/save", method = {RequestMethod.POST, RequestMethod.GET})
    public BhResponseResult<?> save(Account account) {
        account = accountService.save(account);
        return new BhResponseResult<>(0, "success", account);
    }

    @RequestMapping(value = "/public/userapi/account/load", method = {RequestMethod.POST, RequestMethod.GET})
    public BhResponseResult<?> load(String sn) {
        Account account = accountService.load(sn);
        return new BhResponseResult<>(0, "success", account);
    }
}

為了方便測(cè)試,配置SecurityConfiguration,使"/public"開(kāi)頭的api不需要安全認(rèn)證。

    @Override
    protected void configure(HttpSecurity http) throws Exception {
        // @formatter:off
        http
                .authorizeRequests()
                    .antMatchers("/", "/home", "/mobileCodeLogin", "/public/**").permitAll() // 這三個(gè)目錄不做安全控制
                    .anyRequest().authenticated()
                    .and()
                .formLogin()
                    .loginPage("/login")// 自定義的登錄頁(yè)面
                    .permitAll()
                    .and()
                .logout()
                    .logoutSuccessUrl("/");
        http.addFilterBefore(mobileCodeAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
        // @formatter:on
    }
保存

查詢

數(shù)據(jù)庫(kù)

結(jié)尾

這章中,通過(guò)spring data jpa對(duì)數(shù)據(jù)庫(kù)進(jìn)行創(chuàng)建表,增加數(shù)據(jù),查詢數(shù)據(jù)的操作。從頭到尾沒(méi)有使用SQL語(yǔ)句。除了配置文件中配置了數(shù)據(jù)庫(kù)連接參數(shù),業(yè)務(wù)過(guò)程與java程序的面向?qū)ο蟛僮鳠o(wú)異。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容