MJGA:讓 Java 再次偉大!SpringBoot 能否硬剛 Gin?
隔壁組的云計算零零后男同事,后文簡稱云先生,是一位對技術(shù)充滿熱情的后浪開發(fā)者。他自信滿滿地向我推薦 Go 的 Gin 框架,認(rèn)為它比 Java 的 Spring Boot 更加輕量、簡潔,尤其適合微服務(wù)場景下的快速開發(fā)。作為一名扎根 Java 技術(shù)棧多年的開發(fā)者,我自然不甘示弱。畢竟,Spring Boot 是 Java 生態(tài)中的標(biāo)桿,憑借其豐富的生態(tài)體系和強大的社區(qū)支持,成為許多企業(yè)級項目的首選框架。
為了驗證各自框架的優(yōu)劣,我們決定通過一個“快速搭建 CRUD 工程”的實際開發(fā)任務(wù)來一較高下。我選擇使用 Spring Boot 搭配 MyBatis-Plus,而云先生則選擇 Gin 和 Gorm 組合。任務(wù)要求在短時間內(nèi)完成一個完整的增刪改查功能,并且需要評估開發(fā)效率、代碼簡潔度和框架的易用性。通過這個實踐,我們希望能夠更客觀地分析這兩種框架的優(yōu)劣,并為開發(fā)者在選擇技術(shù)棧時提供一些參考。
準(zhǔn)備事項
既然是 CRUD 工程,自然要先準(zhǔn)備好操作的表。我和云先生分別在各自的數(shù)據(jù)庫中創(chuàng)建了如下兩張表:
CREATE TABLE people (
id INT(11)PRIMARYKEYAUTO_INCREMENT,
p_name VARCHAR(255)NOTNULL,
p_age INT(11)NOTNULL
);
CREATETABLE book (
id INT(11)PRIMARYKEYAUTO_INCREMENT,
b_name VARCHAR(255)NOTNULL,
b_price FLOATNOTNULL
);
Gin 快速搭建 CRUD 工程
云先生的工程結(jié)構(gòu)如下所示:
Gin 目錄結(jié)構(gòu)
gobase/
├── dao/
├── model/
├── mysql/
├── router/
└── main.go
云先生的 go.mod 文件內(nèi)容如下:
module gobase
go 1.17
require (
github.com/gin-gonic/gin v1.6.0
github.com/jinzhu/gorm v1.9.16
github.com/sirupsen/logrus v1.9.3
github.com/spf13/cast v1.5.1
)
模型定義
云先生為 book 和 people 表分別定義了對應(yīng)的模型結(jié)構(gòu)體,分別在 model/book.go 和 model/people.go 文件中:
model/book.go
package model
const(
BookTableName ="book"
)
type Book struct{
ID int64 `gorm:"column:id"`
BookName string`gorm:"column:b_name"`
BookPrice float64`gorm:"column:b_price"`
}
func(b *Book)TableName()string{
return BookTableName
}
model/people.go
package model
const(
PeopleTableName ="people"
)
type People struct{
ID int64`gorm:"column:id"`
PeopleName string`gorm:"column:p_name"`
PeopleAge int64`gorm:"column:p_age"`
}
func(p *People)TableName()string{
return PeopleTableName
}
Dao 層
云先生為 book 和 people 表分別定義了 Dao 接口及其實現(xiàn),以下為 dao 文件夾下的部分代碼:
dao/book_dao_impl.go
package dao
import(
"github.com/jinzhu/gorm"
"gobase/model"
)
type BookDaoImpl struct{
DB *gorm.DB
}
func(b *BookDaoImpl)AddBook(book *model.Book)error{
if createResult := b.DB.Create(book); createResult.Error !=nil{
return createResult.Error
}
returnnil
}
// 省略 UpdateBook、DeleteBook、ListBookById 的實現(xiàn)...
Spring Boot 快速搭建 CRUD 工程
Spring Boot 目錄結(jié)構(gòu)
springboot-demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com.icoderoad.demo/
│ │ │ ├── controller/
│ │ │ ├── entity/
│ │ │ ├── mapper/
│ │ │ ├── service/
│ │ │ └── service/impl/
│ │ └── resources/
│ └── test/
配置文件
application.yml 文件內(nèi)容如下:
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo
username: root
password: root
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
數(shù)據(jù)表實體類
package com.icoderoad.demo.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
@Data
@TableName("book")
public class Book{
private Long id;
private String bName;
private Double bPrice;
}
Mapper 接口
package com.example.demo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.demo.entity.Book;
public interface BookMapper extends BaseMapper<Book> {}
Service 實現(xiàn)
package com.icoderoad.demo.service.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.icoderoad.demo.entity.Book;
import com.icoderoad.demo.mapper.BookMapper;
import com.icoderoad.demo.service.BookService;
import org.springframework.stereotype.Service;
@Service
public class BookServiceImpl extends ServiceImpl<BookMapper, Book> implements BookService{}
Controller
package com.icoderoad.demo.controller;
import com.icoderoad.demo.entity.Book;
import com.icoderoad.demo.service.BookService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/book")
public class BookController{
@Autowired
private BookService bookService;
@PostMapping
public String addBook(@RequestBody Book book){
bookService.save(book);
return"Book added successfully!";
}
@GetMapping("/{id}")
public BookgetBook(@PathVariable Long id){
return bookService.getById(id);
}
@GetMapping
public List<Book>listBooks(){
return bookService.list();
}
@PutMapping
public String updateBook(@RequestBody Book book){
bookService.updateById(book);
return"Book updated successfully!";
}
@DeleteMapping("/{id}")
public String deleteBook(@PathVariable Long id){
bookService.removeById(id);
return"Book deleted successfully!";
}
}
總結(jié)
最后經(jīng)過團隊投票,Spring Boot 和 Gin 各有優(yōu)劣:
- Gin 的確輕量化,但需要寫大量代碼。
- Spring Boot 的生態(tài)更完善,代碼量少但配置復(fù)雜。
如果團隊追求快速迭代,Gin 是一個不錯的選擇;如果注重長期維護和擴展,Spring Boot 更加合適。你怎么看?