隔壁组的云计算零零后男同事,后文简称云先生,是一位对技术充满热情的后浪开发者。他自信满满地向我推荐 Go 的 Gin 框架,认为它比 Java 的 Spring Boot 更加轻量、简洁,尤其适合微服务场景下的快速开发。作为一名扎根 Java 技术栈多年的开发者,我自然不甘示弱。毕竟,Spring Boot 是 Java 生态中的标杆,凭借其丰富的生态体系和强大的社区支持,成为许多企业级项目的首选框架。
为了验证各自框架的优劣,我们决定通过一个“快速搭建 CRUD 工程”的实际开发任务来一较高下。我选择使用 Spring Boot 搭配 MyBatis-Plus,而云先生则选择 Gin 和 Gorm 组合。任务要求在短时间内完成一个完整的增删改查功能,并且需要评估开发效率、代码简洁度和框架的易用性。通过这个实践,我们希望能够更客观地分析这两种框架的优劣,并为开发者在选择技术栈时提供一些参考。
准备事项
既然是 CRUD 工程,自然要先准备好操作的表。我和云先生分别在各自的数据库中创建了如下两张表:
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 工程
云先生的工程结构如下所示:
Gin 目录结构
gobase/
├── dao/
├── model/
├── mysql/
├── router/
└── main.go
云先生的 go.mod 文件内容如下:
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 表分别定义了对应的模型结构体,分别在 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 接口及其实现,以下为 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 的实现...
Spring Boot 快速搭建 CRUD 工程
Spring Boot 目录结构
springboot-demo/
├── src/
│ ├── main/
│ │ ├── java/
│ │ │ └── com.icoderoad.demo/
│ │ │ ├── controller/
│ │ │ ├── entity/
│ │ │ ├── mapper/
│ │ │ ├── service/
│ │ │ └── service/impl/
│ │ └── resources/
│ └── test/
配置文件
application.yml 文件内容如下:
spring:
datasource:
url: jdbc:mysql://localhost:3306/demo
username: root
password: root
mybatis-plus:
mapper-locations: classpath:mapper/*.xml
数据表实体类
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 实现
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!";
}
}
总结
最后经过团队投票,Spring Boot 和 Gin 各有优劣:
- Gin 的确轻量化,但需要写大量代码。
- Spring Boot 的生态更完善,代码量少但配置复杂。
如果团队追求快速迭代,Gin 是一个不错的选择;如果注重长期维护和扩展,Spring Boot 更加合适。你怎么看?