当前位置: 首页 > news >正文

石碣网站建设010-58813333 可信网站

石碣网站建设,010-58813333 可信网站,销售平台app,宠物网站建设方案书导读#xff1a; 在 Go 项目中#xff0c;虽然没有像 MyBatis Plus 这样特定的 ORM 插件#xff0c;但可以使用功能相似的 Go ORM 框架#xff0c;比如 GORM#xff0c;它支持链式查询、自动迁移、预加载等功能#xff0c;与 MyBatis Plus 有相似之处。通过一些插件或扩…导读 在 Go 项目中虽然没有像 MyBatis Plus 这样特定的 ORM 插件但可以使用功能相似的 Go ORM 框架比如 GORM它支持链式查询、自动迁移、预加载等功能与 MyBatis Plus 有相似之处。通过一些插件或扩展可以实现更丰富的功能比如软删除、分页查询等。下面是 GORM 集成的一些步骤和相关插件的推荐本文以之前集成的项目Go语言IDEA能支持吗增删查走起_go idea-CSDN博客为模版在此基础上进行迭代。 目录 一、引入GORM 二、GORM能力 2.1分页查询 2.2软删除 2.3分页拓展 2.4链式查询 2.5自定义拓展 三、源码改造 3.1改造数据库连接类database.go 3.2改造中间件DBMiddleware 3.3 改造userDao.go 3.4 改造userService.go 3.5 改造router.go 3.6 改造main.go 四、启动 五、异常情况 5.1解决思路 六、复杂查询拓展 6.1实体类Orders.go 6.2新增OrderInfoDTO.go 6.3新增GetUserWithOrders方法 一、引入GORM 先在项目中引入 GORM go get -u gorm.io/gorm go get -u gorm.io/driver/mysql # 根据你的数据库类型选择驱动二、GORM能力 GORM 提供了一些类似 MyBatis Plus 的功能比如 软删除通过 gorm.Model 或自定义字段来实现软删除。条件查询可以通过链式查询构建条件查询。分页插件可以手动实现分页或使用封装的分页插件。 2.1分页查询 go 一遍集成GORM 的 Limit 和 Offset 方法实现分页查询 var users []User db.Limit(10).Offset(20).Find(users) // 查询第 21-30 条数据2.2软删除 例如通过 gorm.Model 或自定义字段来实现软删除。 type User struct {gorm.ModelName stringAge int }db.Delete(user) // 软删除2.3分页拓展 可以手动实现分页或使用封装的分页插件比如分页器 github.com/biezhi/gorm-paginator 。 2.4链式查询 GORM 支持链式调用来构建复杂的查询 var users []User db.Where(age ?, 18).Find(users)2.5自定义拓展 如果需要类似 MyBatis Plus 的扩展功能你可以通过自定义 GORM 的钩子函数Hooks或中间件来实现数据插入、更新时自动添加字段等逻辑。GORM 提供了生命周期回调接口可以在执行操作前后进行拦截和处理。 三、源码改造 3.1改造数据库连接类database.go 引入 GORM通过 gorm.io/gorm 和 gorm.io/driver/mysql 代替原来的 database/sql。 初始化数据库连接使用 gorm.Open() 方法替代 sql.Open()并且支持更多的配置参数比如 charsetutf8mb4 和 parseTimeTrue。 GetDB 函数返回 *gorm.DB 类型的数据库实例供其他模块使用。 这边删除了原先的func GetDB() *sql.DB { return DB } 方法 package configimport (fmtgorm.io/driver/mysqlgorm.io/gormgorm.io/gorm/loggerlog )var DB *gorm.DB// InitGormDatabase 初始化 GORM 数据库连接并返回 *gorm.DB func InitGormDatabase() *gorm.DB {dsn : fmt.Sprintf(%s:%stcp(%s:%s)/%s?charsetutf8mb4parseTimeTruelocLocal,AppConfig.Database.User,AppConfig.Database.Password,AppConfig.Database.Host,AppConfig.Database.Port,AppConfig.Database.DBName,)var err errorDB, err gorm.Open(mysql.Open(dsn), gorm.Config{Logger: logger.Default.LogMode(logger.Info),})if err ! nil {log.Fatalf(Failed to connect to database: %v, err)return nil}log.Println(GORM database successfully connected)return DB }3.2改造中间件DBMiddleware 这边说明一下中间件的引入是刚搭建项目时想从java中的切面编程来实现跨功能关注点的处理。比如数据库的连接。但是呢go没有内置切面的支持。所以就引入了中间件模式每次调用数据库操作都通过中间件来处理。下面是优化前的中间件 package middlewareimport (database/sqlgo_tas/dao/databaselog )type DBMiddleware struct {db *sql.DB }func NewDBMiddleware() *DBMiddleware {return DBMiddleware{db: database.GetDB(),} }func (mw *DBMiddleware) ExecuteQuery(query string, args ...interface{}) (*sql.Rows, error) {rows, err : mw.db.Query(query, args...) // 使用中间件中保存的 dbif err ! nil {return nil, mw.logError(Failed to execute query, err)}return rows, nil }func (mw *DBMiddleware) ExecuteExec(query string, args ...interface{}) (int64, error) {result, err : mw.db.Exec(query, args...) // 使用中间件中保存的 dbif err ! nil {return 0, mw.logError(Failed to execute exec, err)}insertID, err : result.LastInsertId()if err ! nil {return 0, mw.logError(Failed to get last insert ID, err)}return insertID, nil }func (mw *DBMiddleware) BeginTransaction() (*sql.Tx, error) {tx, err : mw.db.Begin() // 使用中间件中保存的 dbif err ! nil {return nil, mw.logError(Failed to begin transaction, err)}return tx, nil }func (mw *DBMiddleware) logError(message string, err error) error {log.Printf(%s: %v, message, err)return err } 使用原生的 database/sql 改造为使用 GORM可以直接使用 GORM 的功能来处理查询、事务等操作。GORM 已经封装了这些常见的操作并且支持更简洁的 API。 下面是改造后的 middleware 模块使用 GORM 替代 database/sql gorm.DB 替换 sql.DBDBMiddleware 中的 db 现在使用 *gorm.DB所有的数据库操作通过 GORM 进行。 ExecuteQuery 方法 使用 GORM 的 Raw 方法执行原生 SQL 查询并通过 Scan 将结果映射到传入的 model 结构体。原生 SQL 查询返回的结果可以映射到结构体切片中。var users []User middleware.ExecuteQuery(users, SELECT * FROM users WHERE age ?, 18)ExecuteExec 方法 使用 GORM 的 Exec 方法执行修改插入、更新、删除语句。返回执行后影响的行数而不是插入 ID。 事务管理 使用 GORM 的 Begin 方法开启事务返回事务对象 *gorm.DB。tx, err : middleware.BeginTransaction() if err ! nil {// handle error } // 在事务中执行操作 err tx.Create(user).Error if err ! nil {tx.Rollback() } else {tx.Commit() }中间件现在可以使用 GORM 的功能简化数据库操作并支持复杂的 ORM 功能。 package middlewareimport (go_tas/dao/databaseloggorm.io/gorm )type DBMiddleware struct {db *gorm.DB }func NewDBMiddleware() *DBMiddleware {return DBMiddleware{db: database.GetDB(), // 使用 GORM 的 DB 实例} }// ExecuteQuery 执行查询语句 func (mw *DBMiddleware) ExecuteQuery(model interface{}, query string, args ...interface{}) error {result : mw.db.Raw(query, args...).Scan(model) // 使用 GORM 的 Raw 方法if result.Error ! nil {return mw.logError(Failed to execute query, result.Error)}return nil }// ExecuteExec 执行修改语句插入、更新、删除 func (mw *DBMiddleware) ExecuteExec(query string, args ...interface{}) (int64, error) {result : mw.db.Exec(query, args...) // 使用 GORM 的 Exec 方法if result.Error ! nil {return 0, mw.logError(Failed to execute exec, result.Error)}return result.RowsAffected, nil // 返回影响的行数 }// BeginTransaction 开启事务 func (mw *DBMiddleware) BeginTransaction() (*gorm.DB, error) {tx : mw.db.Begin() // 使用 GORM 的事务支持if tx.Error ! nil {return nil, mw.logError(Failed to begin transaction, tx.Error)}return tx, nil }// logError 记录错误信息 func (mw *DBMiddleware) logError(message string, err error) error {log.Printf(%s: %v, message, err)return err }3.3 改造userDao.go 使用原生 SQL 改造为使用 GORM可以直接利用 GORM 的模型操作方法来简化数据库操作。GORM 允许直接对结构体进行增删改查而不需要手动编写 SQL 查询 package daoimport (go_tas/entitygorm.io/gormlog )type UserDAO struct {db *gorm.DB }// NewUserDAO 创建新的 UserDAO 实例 func NewUserDAO(db *gorm.DB) *UserDAO {return UserDAO{db: db} }// GetAllUsers 获取所有用户 func (dao *UserDAO) GetAllUsers() ([]entity.User, error) {var users []entity.User// 使用 GORM 查询所有用户if err : dao.db.Find(users).Error; err ! nil {log.Printf(Failed to get users: %v, err)return nil, err}return users, nil }// CreateUser 创建新用户 func (dao *UserDAO) CreateUser(user *entity.User) (int64, error) {// 使用 GORM 创建用户if err : dao.db.Create(user).Error; err ! nil {log.Printf(Failed to create user: %v, err)return 0, err}// 返回创建的用户 IDreturn int64(user.ID), nil }3.4 改造userService.go 使用 GORM 替代原生 SQL 操作来进行数据处理。可以将事务处理和数据库操作使用 GORM 的特性进行简化和改造 package serviceimport (encoding/jsongo_tas/daogo_tas/entitygo_tas/utilsgorm.io/gormnet/http )// GetUsers 获取所有用户 func GetUsers(w http.ResponseWriter, r *http.Request, db *gorm.DB) {userDAO : dao.NewUserDAO(db)users, err : userDAO.GetAllUsers()if err ! nil {utils.HandleError(w, http.StatusInternalServerError, Failed to retrieve users, err)return}respondWithJSON(w, http.StatusOK, users) }// CreateUser 创建新用户 func CreateUser(w http.ResponseWriter, r *http.Request, db *gorm.DB) {var user entity.Userif err : json.NewDecoder(r.Body).Decode(user); err ! nil {utils.HandleError(w, http.StatusBadRequest, Invalid request payload, err)return}// 开始一个事务tx : db.Begin()if tx.Error ! nil {utils.HandleError(w, http.StatusInternalServerError, Failed to begin transaction, tx.Error)return}defer func() {if r : recover(); r ! nil {tx.Rollback() // 回滚事务utils.HandleError(w, http.StatusInternalServerError, Internal server error, nil)}}()// 插入用户数据userDAO : dao.NewUserDAO(tx)if _, err : userDAO.CreateUser(user); err ! nil {tx.Rollback() // 回滚事务utils.HandleError(w, http.StatusInternalServerError, Failed to create user, err)return}// 提交事务if err : tx.Commit().Error; err ! nil {utils.HandleError(w, http.StatusInternalServerError, Failed to commit transaction, err)return}respondWithJSON(w, http.StatusCreated, user) }// respondWithJSON 处理JSON响应 func respondWithJSON(w http.ResponseWriter, status int, payload interface{}) {w.Header().Set(Content-Type, application/json)w.WriteHeader(status)if err : json.NewEncoder(w).Encode(payload); err ! nil {utils.HandleError(w, http.StatusInternalServerError, Failed to encode response data, err)} }3.5 改造router.go 将 router 中的数据库操作从 dbMiddleware 改为使用 GORM 数据库连接并清理代码逻辑 package routerimport (github.com/gorilla/muxhttpSwagger github.com/swaggo/http-swaggergo_tas/controllergo_tas/middlewarego_tas/servicegorm.io/gormnet/http )func InitRouter(authMiddleware *middleware.CustomAuthMiddleware, db *gorm.DB) *mux.Router {r : mux.NewRouter()// 添加身份验证中间件r.Use(authMiddleware.Middleware)// 使用 GORM 数据库连接r.HandleFunc(/users, func(w http.ResponseWriter, r *http.Request) {service.GetUsers(w, r, db)}).Methods(GET)r.HandleFunc(/users, func(w http.ResponseWriter, r *http.Request) {service.CreateUser(w, r, db)}).Methods(POST)// 设备控制接口r.HandleFunc(/tas/control, controller.Control).Methods(POST)r.HandleFunc(/tas/adminControl, controller.AdminControl).Methods(POST)// Swagger Handlerr.PathPrefix(/swagger/).Handler(httpSwagger.WrapHandler)return r }3.6 改造main.go main 函数中可以将原本使用的 dbMiddleware 改为直接使用 GORM 初始化的数据库连接以便与前面改造的代码保持一致 package mainimport (go_tas/configgo_tas/loggergo_tas/middlewarego_tas/routerlognet/http )func main() {// 初始化配置config.InitConfig()log.Println(Config initialized)// 初始化数据库获取 GORM 数据库连接db : config.InitGormDatabase()if db nil {log.Fatal(Failed to initialize database)}log.Println(Database initialized with GORM)// 初始化 Redisconfig.InitRedis()log.Println(Redis initialized)// 初始化日志logger.InitLogger()// 初始化认证中间件appCode : config.AppConfig.AppCodeappSecret : config.AppConfig.AppSecretauthMiddleware : middleware.NewCustomAuthMiddleware(appCode, appSecret)// 初始化路由并传递 GORM 数据库连接r : router.InitRouter(authMiddleware, db)log.Println(authMiddleware initialized)// 启动服务器log.Println(Starting server on :8080)log.Fatal(http.ListenAndServe(:8080, r)) }四、启动 五、异常情况 如果提示Table go_data_base.users doesnt exist这种情况可以查看一下实体类原因可能是由于查询时表名不匹配造成的。GORM 默认会使用复数形式表名进行查询因此它在查找 users 表而你的实际表名是 user。 5.1解决思路 可以通过在 GORM 模型中设置表名 package entitytype User struct {ID int json:idName string json:nameEmail string json:email }// TableName 指定表名为 user func (User) TableName() string {return user }六、复杂查询拓展 如果涉及多表关联查询则可使用Joins来进行SQL联表查询下面举个栗子 6.1实体类Orders.go package entitytype Orders struct {ID int json:idUserId int json:user_idAmount int json:amountDescription string json:description }func (Orders) TableName() string {return orders } 6.2新增OrderInfoDTO.go package dtotype OrderInfoDTO struct {ID int json:idName string json:nameEmail string json:emailAmount int json:amountDescription string json:description }6.3新增GetUserWithOrders方法 在userDao.go 新增一个GetUserWithOrders方法Joins 用于执行 SQL 联表查Select(users.*, orders.amount) 指定返回的字段你可以选择返回哪些表的字段Scan(users) 将查询结果扫描到 users 切片中。 func (dao *UserDAO) GetUsersWithOrderInfo() ([]dto.OrderInfoDTO, error) {var userInfo []dto.OrderInfoDTOerr : dao.db.Table(user).Joins(LEFT JOIN orders ON orders.user_id user.id).Select(user.*, orders.*).Scan(userInfo).Errorif err ! nil {log.Printf(Failed to get users with order info: %v, err)return nil, err}return userInfo, nil } 最后将数据库的语句 DROP TABLE IF EXISTS orders; CREATE TABLE orders (id bigint(20) NOT NULL AUTO_INCREMENT,user_id bigint(20) NULL DEFAULT NULL COMMENT 用户ID,amount int(10) NULL DEFAULT NULL COMMENT 支付金额/分,description varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT 商品描述,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 7 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT Dynamic;-- ---------------------------- -- Table structure for user -- ---------------------------- DROP TABLE IF EXISTS user; CREATE TABLE user (id bigint(20) NOT NULL AUTO_INCREMENT,name varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,email varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,PRIMARY KEY (id) USING BTREE ) ENGINE InnoDB AUTO_INCREMENT 5 CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci ROW_FORMAT Dynamic;SET FOREIGN_KEY_CHECKS 1; 如果需要源码的同学评论区把邮箱放置一下哈
http://www.pierceye.com/news/990595/

相关文章:

  • 网站无法连接服务器哪些国家网站无须备案
  • 重庆做网站设计培训机构排名全国十大教育机构排名
  • 做网站建设销售网络营销推广技巧
  • 南宁网站制作定制北京网站seo服务
  • 门户网站网页设计规范willin kan 让你的wordpress飞起来
  • 建设银行广州招聘网站wordpress dz
  • 如何介绍自己做的网站东莞回收网站设计
  • 北京驾校网站建设厦门网页设计培训班
  • 网络公司给我做网站我有没有源代码版权吗我怎么做个人网站
  • 免费建站网站一站式做网站需要懂那些软件
  • 做新网站怎样提交360寻找销售团队外包
  • 重庆市建设网站wordpress 新闻模版
  • 国内网站建设推荐手工做的网站
  • 深圳罗湖做网站的公司网站建设与管理案例教程第三版课后答案
  • 有关网站招标商务标书怎么做做终端客户网站
  • c 网站做微信收款功能青岛网站建设定制
  • 贵州安顺建设主管部门网站网站全程设计技术
  • 公司宣传网站建设企业网站建设与实现的论文
  • 连云港网站建设推广网站的推广优化
  • 手机商城网站制作公司网站版面设计方案
  • 网站开发制作熊掌号网站推广方法主要有什么
  • 怎么查看网站的建设时间提高企业网站的访问率
  • 宁德做网站的公司长沙网站建设 芙蓉区
  • 兴平市住房和城乡建设局门户网站会员管理网站建设
  • 做seo的网站是怎么样的上饶小程序开发公司
  • 网站硬件需求建网站网站
  • 网站主机域名合肥室内装修设计培训
  • 上海网站优化网站对企业的作用
  • 哪些园林网站可以做外链网址怎么注册
  • 做网站域名服务器wordpress 互动性