最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Java后端開(kāi)發(fā)標(biāo)準(zhǔn)流程之從數(shù)據(jù)庫(kù)到接口的完整實(shí)現(xiàn)方法

 更新時(shí)間:2026年05月15日 10:12:25   作者:Filotimo_  
后端開(kāi)發(fā)是指開(kāi)發(fā)基于服務(wù)器端的軟件應(yīng)用程序,也稱為系統(tǒng)的后臺(tái)或服務(wù)器端編程,下面這篇文章主要介紹了Java后端開(kāi)發(fā)標(biāo)準(zhǔn)流程之從數(shù)據(jù)庫(kù)到接口的完整實(shí)現(xiàn)方法,文中通過(guò)代碼介紹的非常詳細(xì),需要的朋友可以參考下

前言

在實(shí)際的Java后端開(kāi)發(fā)中,我們通常會(huì)遵循一個(gè)標(biāo)準(zhǔn)的開(kāi)發(fā)流程,確保代碼結(jié)構(gòu)清晰、層次分明、易于維護(hù)。本文將以一個(gè)圖書管理系統(tǒng)為例,詳細(xì)介紹從數(shù)據(jù)庫(kù)設(shè)計(jì)到接口實(shí)現(xiàn)的完整流程。

完整開(kāi)發(fā)流程

第1步:創(chuàng)建數(shù)據(jù)表
       ↓
第2步:創(chuàng)建Entity實(shí)體類
       ↓
第3步:創(chuàng)建DTO對(duì)象
       ↓
第4步:創(chuàng)建Repository數(shù)據(jù)訪問(wèn)層
       ↓
第5步:創(chuàng)建Service業(yè)務(wù)邏輯層
       ↓
第6步:創(chuàng)建Controller控制器層
       ↓
第7步:創(chuàng)建SQL配置類(可選,復(fù)雜查詢使用)

第1步:創(chuàng)建數(shù)據(jù)表

首先在數(shù)據(jù)庫(kù)中創(chuàng)建表結(jié)構(gòu),這是整個(gè)系統(tǒng)的數(shù)據(jù)基礎(chǔ)。

-- 圖書表
CREATE TABLE book (
    id VARCHAR(32) PRIMARY KEY,
    book_name VARCHAR(100) NOT NULL,
    author VARCHAR(50),
    isbn VARCHAR(20) UNIQUE,
    price DECIMAL(10, 2),
    stock INT DEFAULT 0,
    publish_date DATE,
    deleted INT DEFAULT 0,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    update_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 圖書借閱記錄表
CREATE TABLE book_borrow (
    id VARCHAR(32) PRIMARY KEY,
    book_id VARCHAR(32),
    reader_name VARCHAR(50),
    borrow_date DATE,
    return_date DATE,
    status INT DEFAULT 0,  -- 0-借閱中 1-已歸還
    deleted INT DEFAULT 0,
    create_time TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    FOREIGN KEY (book_id) REFERENCES book(id)
);

設(shè)計(jì)要點(diǎn):

  • 每個(gè)表都有主鍵 id
  • 使用 deleted 字段實(shí)現(xiàn)邏輯刪除(0-正常 1-刪除)
  • 使用 create_time 和 update_time 記錄時(shí)間
  • 外鍵關(guān)聯(lián)保持?jǐn)?shù)據(jù)完整性

第2步:創(chuàng)建Entity實(shí)體類

Entity類對(duì)應(yīng)數(shù)據(jù)庫(kù)表結(jié)構(gòu),用于ORM映射。

package com.example.library.entity;

import lombok.Data;
import javax.persistence.*;
import java.math.BigDecimal;
import java.util.Date;

/**
 * 圖書實(shí)體類
 * 對(duì)應(yīng)數(shù)據(jù)庫(kù)表:book
 */
@Data
@Entity
@Table(name = "book")
public class Book {
    
    @Id
    @GeneratedValue(generator = "uuid")
    @GenericGenerator(name = "uuid", strategy = "uuid")
    @Column(name = "id", nullable = false)
    private String id;
    
    @Column(name = "book_name", nullable = false)
    private String bookName;
    
    @Column(name = "author")
    private String author;
    
    @Column(name = "isbn", unique = true)
    private String isbn;
    
    @Column(name = "price")
    private BigDecimal price;
    
    @Column(name = "stock")
    private Integer stock;
    
    @Column(name = "publish_date")
    private Date publishDate;
    
    @Column(name = "deleted")
    private Integer deleted;
    
    @Column(name = "create_time")
    private Date createTime;
    
    @Column(name = "update_time")
    private Date updateTime;
}

Entity的作用:

  • 與數(shù)據(jù)庫(kù)表一一對(duì)應(yīng)
  • 負(fù)責(zé)數(shù)據(jù)的存儲(chǔ)和讀取
  • 不包含業(yè)務(wù)邏輯

第3步:創(chuàng)建DTO對(duì)象

DTO(Data Transfer Object)用于前后端數(shù)據(jù)傳輸,與Entity分離。

3.1 請(qǐng)求DTO(接收前端參數(shù))

package com.example.library.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;

/**
 * 新增圖書請(qǐng)求DTO
 */
@Data
@ApiModel("新增圖書請(qǐng)求")
public class AddBookDTO {
    
    @ApiModelProperty("圖書名稱")
    private String bookName;
    
    @ApiModelProperty("作者")
    private String author;
    
    @ApiModelProperty("ISBN")
    private String isbn;
    
    @ApiModelProperty("價(jià)格")
    private BigDecimal price;
    
    @ApiModelProperty("庫(kù)存數(shù)量")
    private Integer stock;
    
    @ApiModelProperty("出版日期")
    private String publishDate;
}

3.2 響應(yīng)DTO(返回?cái)?shù)據(jù)給前端)

package com.example.library.dto;

import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import java.math.BigDecimal;

/**
 * 圖書詳情響應(yīng)DTO
 */
@Data
@ApiModel("圖書詳情")
public class BookDetailDTO {
    
    @ApiModelProperty("圖書ID")
    private String id;
    
    @ApiModelProperty("圖書名稱")
    private String bookName;
    
    @ApiModelProperty("作者")
    private String author;
    
    @ApiModelProperty("價(jià)格")
    private BigDecimal price;
    
    @ApiModelProperty("庫(kù)存狀態(tài)")
    private String stockStatus;  // "充足"、"緊張"、"缺貨"
    
    @ApiModelProperty("是否可借")
    private Boolean borrowable;
}

為什么要用DTO?

  • Entity管數(shù)據(jù):與數(shù)據(jù)庫(kù)表結(jié)構(gòu)對(duì)應(yīng)
  • DTO管傳輸:與前端接口對(duì)應(yīng),可以包含計(jì)算字段、格式化數(shù)據(jù)
  • 解耦合:數(shù)據(jù)庫(kù)表結(jié)構(gòu)變化不影響接口
  • 安全性:避免暴露敏感字段(如deleted、create_time)

第4步:創(chuàng)建Repository數(shù)據(jù)訪問(wèn)層

Repository負(fù)責(zé)與數(shù)據(jù)庫(kù)交互,提供基本的CRUD操作。

package com.example.library.repository;

import com.example.library.entity.Book;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;

/**
 * 圖書數(shù)據(jù)訪問(wèn)層
 */
public interface BookRepository extends JpaRepository<Book, String> {
    
    /**
     * 根據(jù)ISBN查找圖書
     */
    Book findByIsbn(String isbn);
    
    /**
     * 根據(jù)作者模糊查詢
     */
    List<Book> findByAuthorContaining(String author);
    
    /**
     * 查詢庫(kù)存不足的圖書
     */
    @Query("SELECT b FROM Book b WHERE b.stock < :threshold AND b.deleted = 0")
    List<Book> findLowStockBooks(@Param("threshold") Integer threshold);
    
    /**
     * 統(tǒng)計(jì)圖書總數(shù)
     */
    @Query("SELECT COUNT(b) FROM Book b WHERE b.deleted = 0")
    Long countByDeleted();
}

Repository的特點(diǎn):

  • 繼承 JpaRepository 獲得基礎(chǔ)CRUD方法
  • 使用方法命名規(guī)則自動(dòng)生成SQL(如 findByAuthorContaining
  • 使用 @Query 注解自定義復(fù)雜查詢
  • 只負(fù)責(zé)數(shù)據(jù)訪問(wèn),不包含業(yè)務(wù)邏輯

第5步:創(chuàng)建Service業(yè)務(wù)邏輯層

Service負(fù)責(zé)業(yè)務(wù)邏輯處理,連接Controller和Repository。

5.1 Service接口

package com.example.library.service;
import com.example.library.dto.AddBookDTO;
import com.example.library.dto.BookDetailDTO;
import com.example.library.entity.Book;
import java.util.List;
/**
 * 圖書業(yè)務(wù)邏輯接口
 */
public interface BookService {
    /**
     * 新增圖書
     */
    boolean addBook(AddBookDTO dto);
    /**
     * 獲取圖書詳情
     */
    BookDetailDTO getBookDetail(String bookId);
    /**
     * 借閱圖書
     */
    boolean borrowBook(String bookId, String readerName);
    /**
     * 獲取庫(kù)存不足的圖書列表
     */
    List<Book> getLowStockBooks(Integer threshold);
}

5.2 Service實(shí)現(xiàn)類

package com.example.library.service.impl;

import com.example.library.dto.AddBookDTO;
import com.example.library.dto.BookDetailDTO;
import com.example.library.entity.Book;
import com.example.library.repository.BookRepository;
import com.example.library.service.BookService;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * 圖書業(yè)務(wù)邏輯實(shí)現(xiàn)
 */
@Transactional
@Log4j2
@Service
public class BookServiceImpl implements BookService {
    
    @Autowired
    private BookRepository bookRepository;
    
    @Override
    public boolean addBook(AddBookDTO dto) {
        try {
            // 1. 檢查ISBN是否已存在
            Book existingBook = bookRepository.findByIsbn(dto.getIsbn());
            if (existingBook != null) {
                log.warn("ISBN已存在: {}", dto.getIsbn());
                return false;
            }
            
            // 2. 創(chuàng)建圖書實(shí)體
            Book book = new Book();
            book.setId(UUID.randomUUID().toString());
            book.setBookName(dto.getBookName());
            book.setAuthor(dto.getAuthor());
            book.setIsbn(dto.getIsbn());
            book.setPrice(dto.getPrice());
            book.setStock(dto.getStock());
            book.setDeleted(0);
            book.setCreateTime(new Date());
            book.setUpdateTime(new Date());
            
            // 3. 保存到數(shù)據(jù)庫(kù)
            bookRepository.save(book);
            return true;
        } catch (Exception e) {
            log.error("新增圖書失敗", e);
            return false;
        }
    }
    
    @Override
    public BookDetailDTO getBookDetail(String bookId) {
        // 1. 查詢圖書
        Book book = bookRepository.findById(bookId).orElse(null);
        if (book == null) {
            return null;
        }
        
        // 2. Entity轉(zhuǎn)DTO
        BookDetailDTO dto = new BookDetailDTO();
        dto.setId(book.getId());
        dto.setBookName(book.getBookName());
        dto.setAuthor(book.getAuthor());
        dto.setPrice(book.getPrice());
        
        // 3. 計(jì)算庫(kù)存狀態(tài)
        if (book.getStock() == 0) {
            dto.setStockStatus("缺貨");
            dto.setBorrowable(false);
        } else if (book.getStock() < 5) {
            dto.setStockStatus("緊張");
            dto.setBorrowable(true);
        } else {
            dto.setStockStatus("充足");
            dto.setBorrowable(true);
        }
        
        return dto;
    }
    
    @Override
    public boolean borrowBook(String bookId, String readerName) {
        try {
            // 1. 查詢圖書
            Book book = bookRepository.findById(bookId).orElse(null);
            if (book == null) {
                log.warn("圖書不存在: {}", bookId);
                return false;
            }
            
            // 2. 檢查庫(kù)存
            if (book.getStock() <= 0) {
                log.warn("庫(kù)存不足: {}", book.getBookName());
                return false;
            }
            
            // 3. 扣減庫(kù)存
            book.setStock(book.getStock() - 1);
            book.setUpdateTime(new Date());
            bookRepository.save(book);
            
            // 4. 創(chuàng)建借閱記錄(省略)
            // ...
            
            return true;
        } catch (Exception e) {
            log.error("借閱圖書失敗", e);
            return false;
        }
    }
    
    @Override
    public List<Book> getLowStockBooks(Integer threshold) {
        return bookRepository.findLowStockBooks(threshold);
    }
}

Service的職責(zé):

  • 業(yè)務(wù)邏輯處理(如庫(kù)存檢查、狀態(tài)計(jì)算)
  • 事務(wù)管理(@Transactional
  • 異常處理和日志記錄
  • Entity與DTO之間的轉(zhuǎn)換

第6步:創(chuàng)建Controller控制器層

Controller負(fù)責(zé)接收HTTP請(qǐng)求,調(diào)用Service處理,返回響應(yīng)。

package com.example.library.controller;

import com.example.library.dto.AddBookDTO;
import com.example.library.dto.BookDetailDTO;
import com.example.library.entity.Book;
import com.example.library.service.BookService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.log4j.Log4j2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;

/**
 * 圖書管理接口
 */
@Log4j2
@RestController
@RequestMapping("/api/book")
@Api(tags = "圖書管理")
public class BookController {
    
    @Autowired
    private BookService bookService;
    
    /**
     * 新增圖書
     * POST /api/book/add
     */
    @PostMapping("/add")
    @ApiOperation("新增圖書")
    public boolean addBook(@RequestBody AddBookDTO dto) {
        log.info("新增圖書: {}", dto.getBookName());
        return bookService.addBook(dto);
    }
    
    /**
     * 獲取圖書詳情
     * GET /api/book/detail/{id}
     */
    @GetMapping("/detail/{id}")
    @ApiOperation("獲取圖書詳情")
    public BookDetailDTO getBookDetail(@PathVariable String id) {
        log.info("查詢圖書詳情: {}", id);
        return bookService.getBookDetail(id);
    }
    
    /**
     * 借閱圖書
     * POST /api/book/borrow
     */
    @PostMapping("/borrow")
    @ApiOperation("借閱圖書")
    public boolean borrowBook(@RequestParam String bookId, 
                              @RequestParam String readerName) {
        log.info("借閱圖書: bookId={}, reader={}", bookId, readerName);
        return bookService.borrowBook(bookId, readerName);
    }
    
    /**
     * 獲取庫(kù)存不足的圖書
     * GET /api/book/low-stock
     */
    @GetMapping("/low-stock")
    @ApiOperation("獲取庫(kù)存不足的圖書")
    public List<Book> getLowStockBooks(@RequestParam(defaultValue = "5") Integer threshold) {
        log.info("查詢庫(kù)存不足圖書: threshold={}", threshold);
        return bookService.getLowStockBooks(threshold);
    }
}

Controller的職責(zé):

  • 定義REST接口(URL、請(qǐng)求方法、參數(shù))
  • 參數(shù)校驗(yàn)和綁定
  • 調(diào)用Service處理業(yè)務(wù)
  • 返回響應(yīng)數(shù)據(jù)
  • 記錄接口訪問(wèn)日志

第7步:創(chuàng)建SQL配置類(可選)

對(duì)于復(fù)雜的統(tǒng)計(jì)查詢、多表關(guān)聯(lián),可以使用YAML配置SQL,提高可維護(hù)性。

7.1 YAML配置文件

# src/main/resources/sql/book-sql.yml
book:
  # 圖書借閱統(tǒng)計(jì)
  borrow-statistics:
    columns: |
      SELECT 
          b.book_name,
          b.author,
          COUNT(bb.id) AS borrow_count,
          SUM(CASE WHEN bb.status = 0 THEN 1 ELSE 0 END) AS borrowing_count
    tables: |
      FROM book b
      LEFT JOIN book_borrow bb ON b.id = bb.book_id AND bb.deleted = 0
    condition: |
      WHERE b.deleted = 0
        AND b.publish_date &gt;= :startDate
      GROUP BY b.id, b.book_name, b.author
      ORDER BY borrow_count DESC
  
  # 熱門圖書排行
  popular-books:
    columns: |
      SELECT 
          b.id,
          b.book_name,
          b.author,
          COUNT(bb.id) AS borrow_times
    tables: |
      FROM book b
      INNER JOIN book_borrow bb ON b.id = bb.book_id
    condition: |
      WHERE b.deleted = 0 
        AND bb.borrow_date &gt;= :startDate
        AND bb.borrow_date &lt;= :endDate
      GROUP BY b.id
      ORDER BY borrow_times DESC
      LIMIT 10

7.2 SQL配置類

package com.example.library.sql;

import com.gri.iot.common.sourceloader.YamlPropertySourceFacetory;
import com.gri.iot.common.sql.SqlBody;
import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

/**
 * 圖書SQL配置類
 */
@Data
@PropertySource(value = "classpath:/sql/book-sql.yml", factory = YamlPropertySourceFacetory.class)
@Configuration
@ConfigurationProperties(prefix = "book")
public class BookSqlConfig {
    
    /**
     * 圖書借閱統(tǒng)計(jì)
     */
    private SqlBody borrowStatistics;
    
    /**
     * 熱門圖書排行
     */
    private SqlBody popularBooks;
}

7.3 使用SQL配置

@Service
public class BookReportServiceImpl implements BookReportService {
    
    @Autowired
    private BookSqlConfig bookSqlConfig;
    
    @Autowired
    private JdbcTemplate jdbcTemplate;
    
    @Override
    public List<Map<String, Object>> getBorrowStatistics(String startDate) {
        // 1. 獲取SQL配置
        SqlBody sqlBody = bookSqlConfig.getBorrowStatistics();
        
        // 2. 組裝SQL
        String sql = sqlBody.getColumns() + 
                    sqlBody.getTables() + 
                    sqlBody.getCondition();
        
        // 3. 執(zhí)行查詢
        return jdbcTemplate.queryForList(sql, startDate);
    }
}

什么時(shí)候用YAML配置SQL?

  • ? 復(fù)雜的多表關(guān)聯(lián)查詢
  • ? 需要?jiǎng)討B(tài)條件拼接
  • ? 頻繁調(diào)整的統(tǒng)計(jì)報(bào)表
  • ? SQL語(yǔ)句很長(zhǎng)(超過(guò)50行)

什么時(shí)候用JPA?

  • ? 簡(jiǎn)單的CRUD操作
  • ? 單表查詢
  • ? 方法命名規(guī)則可以滿足的需求

各層之間的調(diào)用關(guān)系

┌─────────────────────────────────────────────────────────┐
│  前端(Vue/React/小程序)                                │
└──────────────────────┬──────────────────────────────────┘
                       │ HTTP請(qǐng)求
                       ▼
┌─────────────────────────────────────────────────────────┐
│  Controller層(控制器)                                   │
│  - 接收請(qǐng)求參數(shù)                                          │
│  - 調(diào)用Service                                           │
│  - 返回響應(yīng)                                              │
└──────────────────────┬──────────────────────────────────┘
                       │
                       ▼
┌─────────────────────────────────────────────────────────┐
│  Service層(業(yè)務(wù)邏輯)                                    │
│  - 業(yè)務(wù)邏輯處理                                          │
│  - 事務(wù)管理                                              │
│  - Entity ? DTO 轉(zhuǎn)換                                     │
└─────────────┬─────────────────────────┬─────────────────┘
              │                         │
              ▼                         ▼
┌─────────────────────────┐  ┌──────────────────────────┐
│  Repository層(JPA)     │  │  SQL配置類(YAML)        │
│  - 簡(jiǎn)單CRUD              │  │  - 復(fù)雜查詢               │
│  - 方法命名規(guī)則          │  │  - 統(tǒng)計(jì)報(bào)表               │
└────────────┬────────────┘  └────────────┬─────────────┘
             │                           │
             └───────────┬───────────────┘
                         ▼
              ┌─────────────────────────┐
              │  數(shù)據(jù)庫(kù)(PostgreSQL)     │
              └─────────────────────────┘

總結(jié)

Java后端開(kāi)發(fā)的標(biāo)準(zhǔn)流程可以總結(jié)為:

步驟名稱作用技術(shù)選型
1數(shù)據(jù)庫(kù)設(shè)計(jì)數(shù)據(jù)存儲(chǔ)基礎(chǔ)PostgreSQL/MySQL
2Entity實(shí)體類ORM映射,數(shù)據(jù)存儲(chǔ)JPA @Entity
3DTO對(duì)象數(shù)據(jù)傳輸,前后端交互@Data, @ApiModel
4Repository層數(shù)據(jù)訪問(wèn),簡(jiǎn)單CRUDJpaRepository
5Service層業(yè)務(wù)邏輯,事務(wù)管理@Service, @Transactional
6Controller層接口定義,請(qǐng)求處理@RestController
7SQL配置類復(fù)雜查詢,統(tǒng)計(jì)報(bào)表YAML + SqlBody

核心原則

  • 單一職責(zé):每層只做自己該做的事
  • 向下依賴:Controller → Service → Repository → Database
  • Entity與DTO分離:數(shù)據(jù)存儲(chǔ)與數(shù)據(jù)傳輸解耦
  • 簡(jiǎn)潔至上:簡(jiǎn)單用JPA,復(fù)雜用YAML SQL
  • 異常處理:Service層統(tǒng)一處理異常,記錄日志

最佳實(shí)踐

  • ? Entity類只包含字段映射,不包含業(yè)務(wù)邏輯
  • ? Service接口和實(shí)現(xiàn)類分離,便于擴(kuò)展
  • ? 使用Optional避免NPE
  • ? 使用@Transactional管理事務(wù)
  • ? Controller只做參數(shù)綁定和響應(yīng),不做業(yè)務(wù)邏輯
  • ? 復(fù)雜SQL使用YAML配置,便于維護(hù)
  • ? 所有接口添加Swagger文檔注解

到此這篇關(guān)于Java后端開(kāi)發(fā)標(biāo)準(zhǔn)流程之從數(shù)據(jù)庫(kù)到接口的完整實(shí)現(xiàn)方法的文章就介紹到這了,更多相關(guān)Java數(shù)據(jù)庫(kù)到接口實(shí)現(xiàn)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評(píng)論

周口市| 邓州市| 扎兰屯市| 安达市| 永昌县| 从化市| 长白| 沙田区| 沁水县| 前郭尔| 山阳县| 梨树县| 历史| 大田县| 新营市| 尉氏县| 庐江县| 和静县| 华池县| 辽宁省| 乌鲁木齐县| 惠水县| 垦利县| 台南市| 韶山市| 休宁县| 阿坝县| 泰来县| 凤凰县| 乌鲁木齐县| 龙岩市| 承德市| 喀喇沁旗| 双峰县| 定襄县| 信阳市| 文安县| 梨树县| 宜兴市| 韩城市| 贺兰县|