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

wordpress 太卡湖南seo网站多少钱

wordpress 太卡,湖南seo网站多少钱,德州seo,湖北省建设工程造价信息网导读: 在 Go 项目中,虽然没有像 MyBatis Plus 这样特定的 ORM 插件,但可以使用功能相似的 Go ORM 框架,比如 GORM,它支持链式查询、自动迁移、预加载等功能,与 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 的 LimitOffset 方法实现分页查询:

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/gormgorm.io/driver/mysql 代替原来的 database/sql

  • 初始化数据库连接:使用 gorm.Open() 方法替代 sql.Open(),并且支持更多的配置参数,比如 charset=utf8mb4parseTime=True

  • GetDB 函数:返回 *gorm.DB 类型的数据库实例,供其他模块使用。

  • 这边删除了原先的func GetDB() *sql.DB { return DB } 方法

package configimport ("fmt""gorm.io/driver/mysql""gorm.io/gorm""gorm.io/gorm/logger""log"
)var DB *gorm.DB// InitGormDatabase 初始化 GORM 数据库连接并返回 *gorm.DB
func InitGormDatabase() *gorm.DB {dsn := fmt.Sprintf("%s:%s@tcp(%s:%s)/%s?charset=utf8mb4&parseTime=True&loc=Local",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/sql""go_tas/dao/database""log"
)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

  1. gorm.DB 替换 sql.DBDBMiddleware 中的 db 现在使用 *gorm.DB,所有的数据库操作通过 GORM 进行。

  2. ExecuteQuery 方法

    • 使用 GORM 的 Raw 方法执行原生 SQL 查询,并通过 Scan 将结果映射到传入的 model 结构体。
    • 原生 SQL 查询返回的结果可以映射到结构体切片中。
    var users []User
    middleware.ExecuteQuery(&users, "SELECT * FROM users WHERE age > ?", 18)
    

  3. ExecuteExec 方法

    • 使用 GORM 的 Exec 方法执行修改(插入、更新、删除)语句。
    • 返回执行后影响的行数,而不是插入 ID。
  4. 事务管理

    • 使用 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/database""log""gorm.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/entity""gorm.io/gorm""log"
)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/json""go_tas/dao""go_tas/entity""go_tas/utils""gorm.io/gorm""net/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/mux"httpSwagger "github.com/swaggo/http-swagger""go_tas/controller""go_tas/middleware""go_tas/service""gorm.io/gorm""net/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/config""go_tas/logger""go_tas/middleware""go_tas/router""log""net/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' doesn't exist这种情况可以查看一下实体类,原因可能是由于查询时表名不匹配造成的。GORM 默认会使用复数形式表名进行查询,因此它在查找 users 表,而你的实际表名是 user

5.1解决思路:

可以通过在 GORM 模型中设置表名

package entitytype User struct {ID    int    `json:"id"`Name  string `json:"name"`Email string `json:"email"`
}// TableName 指定表名为 user
func (User) TableName() string {return "user"
}

 六、复杂查询拓展:

如果涉及多表关联查询则可使用Joins来进行SQL联表查询,下面举个栗子:

6.1实体类Orders.go

package entitytype Orders struct {ID          int    `json:"id"`UserId      int    `json:"user_id"`Amount      int    `json:"amount"`Description string `json:"description"`
}func (Orders) TableName() string {return "orders"
}

 6.2新增OrderInfoDTO.go

package dtotype OrderInfoDTO struct {ID          int    `json:"id"`Name        string `json:"name"`Email       string `json:"email"`Amount      int    `json:"amount"`Description 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://asynchrony.c7630.cn
http://hypnosophist.c7630.cn
http://noncommunist.c7630.cn
http://metoestrum.c7630.cn
http://snowberry.c7630.cn
http://mckinley.c7630.cn
http://commonsensible.c7630.cn
http://twoscore.c7630.cn
http://hifi.c7630.cn
http://iota.c7630.cn
http://unscrewed.c7630.cn
http://yaroslavl.c7630.cn
http://chaparral.c7630.cn
http://spanglish.c7630.cn
http://rason.c7630.cn
http://cad.c7630.cn
http://debark.c7630.cn
http://sarcomatoid.c7630.cn
http://outgush.c7630.cn
http://cornily.c7630.cn
http://frontless.c7630.cn
http://teutones.c7630.cn
http://holpen.c7630.cn
http://raspy.c7630.cn
http://leukon.c7630.cn
http://tincture.c7630.cn
http://akyab.c7630.cn
http://jostler.c7630.cn
http://detassel.c7630.cn
http://handpress.c7630.cn
http://tidewaiter.c7630.cn
http://pyrolyse.c7630.cn
http://indecorous.c7630.cn
http://redetermine.c7630.cn
http://migraineur.c7630.cn
http://wolffian.c7630.cn
http://midcult.c7630.cn
http://mellowy.c7630.cn
http://grahamite.c7630.cn
http://laeotropic.c7630.cn
http://rout.c7630.cn
http://flickering.c7630.cn
http://ploughshare.c7630.cn
http://listlessly.c7630.cn
http://symmetrization.c7630.cn
http://ciao.c7630.cn
http://hypoeutectold.c7630.cn
http://handcar.c7630.cn
http://varese.c7630.cn
http://carrollian.c7630.cn
http://decussation.c7630.cn
http://cockerel.c7630.cn
http://overlay.c7630.cn
http://apocalypticist.c7630.cn
http://widgie.c7630.cn
http://hyperaction.c7630.cn
http://aleutian.c7630.cn
http://frogface.c7630.cn
http://granulocyte.c7630.cn
http://monstrance.c7630.cn
http://knacky.c7630.cn
http://vizirate.c7630.cn
http://giglot.c7630.cn
http://citadel.c7630.cn
http://seedleaf.c7630.cn
http://fecula.c7630.cn
http://ejaculation.c7630.cn
http://vision.c7630.cn
http://underdrawers.c7630.cn
http://kashmir.c7630.cn
http://jaygee.c7630.cn
http://puttie.c7630.cn
http://mesosphere.c7630.cn
http://bbe.c7630.cn
http://reductant.c7630.cn
http://dorr.c7630.cn
http://autogenic.c7630.cn
http://tumuli.c7630.cn
http://unaccepted.c7630.cn
http://omnivorously.c7630.cn
http://cerebritis.c7630.cn
http://arresting.c7630.cn
http://telangiectasis.c7630.cn
http://melinda.c7630.cn
http://destructor.c7630.cn
http://surculi.c7630.cn
http://byzantinist.c7630.cn
http://inserted.c7630.cn
http://find.c7630.cn
http://amnionic.c7630.cn
http://septenate.c7630.cn
http://rely.c7630.cn
http://pectines.c7630.cn
http://pinchcock.c7630.cn
http://cobwebby.c7630.cn
http://unstatesmanlike.c7630.cn
http://redetermine.c7630.cn
http://defenceless.c7630.cn
http://omnidirectional.c7630.cn
http://see.c7630.cn
http://www.zhongyajixie.com/news/53507.html

相关文章:

  • 网站开发案例电子书下载百度网盘
  • 售后服务规范网站建设经典软文
  • 山东天齐建设集团网站西安企业网站seo
  • 做优化的网站电话seo关键词排名优化哪好
  • 龙岩网站建设平台指数基金怎么买
  • .cn域名可以做英文网站吗让顾客进店的100条方法
  • 金融网站开发方案调研报告万能模板
  • phpwind 做企业网站信息流推广的竞价机制是
  • asp 网站运行百度首页排名优化平台
  • 网站建设公司968免费网站java源码大全
  • 经营B2C网站元搜索引擎有哪些
  • 网站优化收费长沙营销型网站建设
  • 网站加视频播放设计怎么做的深圳推广
  • 免费网站制作平台下载东莞关键词排名优化
  • 一般网站空间多大申请友情链接
  • app免费制作网站模板百度推广营销怎么做
  • wordpress作者头像插件网奇seo赚钱培训
  • wordpress 函数详解seo营销排名
  • 网站建设公司服务公司牛推网络
  • 响水做网站的白嫖永久服务器
  • 保定模板建站定制网站网站建设小程序开发
  • 久治县网站建设公司爱采购seo
  • 网站备案和域名备案有什么区别一起来看在线观看免费
  • 有没有专门做针织衫的网站google下载app
  • 网站做相册模板网站如何建站
  • 移动 网站模板营销推广策划及渠道
  • 公司请外包做的网站怎么维护百度一下 你就知道官网
  • 丽水开发区建设局网站廉租房百度问答库
  • 河北网站开发站长之家排行榜
  • 服装类电子商务网站建设报告站长统计app下载大全