MST

星途 面试题库

面试题:Go代码生成之复杂代码结构生成与优化

要求实现一个Go代码生成工具,它可以根据给定的数据库表结构(通过SQL语句描述,例如`CREATE TABLE users (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(50), age INT)`),生成完整的Go语言数据访问层(DAL)代码,包括结构体定义、数据库连接函数、增删改查方法。并且需要对生成的代码进行性能优化,说明优化思路与具体措施,最后提供生成代码的完整示例。
49.8万 热度难度
编程语言Go

知识考点

AI 面试

面试题答案

一键面试

1. 优化思路

  • 数据库连接池:减少每次数据库操作时建立新连接的开销,通过连接池复用已有连接。
  • 预编译SQL语句:避免重复编译SQL语句,提高执行效率,同时防止SQL注入。
  • 批量操作:在进行插入、更新等操作时,尽量采用批量方式,减少数据库交互次数。

2. 具体措施

  • 连接池:使用database/sql包的sql.Opendb.SetMaxIdleConnsdb.SetMaxOpenConns方法来管理连接池。
  • 预编译SQL:使用db.Prepare方法对SQL语句进行预编译,然后使用预编译的stmt执行操作。
  • 批量操作:在插入多条记录时,构建包含多个值的SQL语句,一次执行。

3. 生成代码示例

package main

import (
    "database/sql"
    "fmt"
    _ "github.com/go-sql-driver/mysql"
)

// User 结构体对应 users 表
type User struct {
    ID   int
    Name string
    Age  int
}

// GetDB 初始化数据库连接
func GetDB() (*sql.DB, error) {
    db, err := sql.Open("mysql", "user:password@tcp(127.0.0.1:3306)/database_name")
    if err != nil {
        return nil, err
    }
    // 设置最大空闲连接数
    db.SetMaxIdleConns(10)
    // 设置最大打开连接数
    db.SetMaxOpenConns(100)
    return db, nil
}

// InsertUser 插入用户
func InsertUser(user User) (int64, error) {
    db, err := GetDB()
    if err != nil {
        return 0, err
    }
    defer db.Close()

    sqlStmt := `INSERT INTO users (name, age) VALUES (?,?)`
    stmt, err := db.Prepare(sqlStmt)
    if err != nil {
        return 0, err
    }
    defer stmt.Close()

    result, err := stmt.Exec(user.Name, user.Age)
    if err != nil {
        return 0, err
    }
    return result.LastInsertId()
}

// GetUser 获取用户
func GetUser(id int) (*User, error) {
    db, err := GetDB()
    if err != nil {
        return nil, err
    }
    defer db.Close()

    sqlStmt := `SELECT id, name, age FROM users WHERE id =?`
    stmt, err := db.Prepare(sqlStmt)
    if err != nil {
        return nil, err
    }
    defer stmt.Close()

    var user User
    err = stmt.QueryRow(id).Scan(&user.ID, &user.Name, &user.Age)
    if err != nil {
        return nil, err
    }
    return &user, nil
}

// UpdateUser 更新用户
func UpdateUser(user User) (int64, error) {
    db, err := GetDB()
    if err != nil {
        return 0, err
    }
    defer db.Close()

    sqlStmt := `UPDATE users SET name =?, age =? WHERE id =?`
    stmt, err := db.Prepare(sqlStmt)
    if err != nil {
        return 0, err
    }
    defer stmt.Close()

    result, err := stmt.Exec(user.Name, user.Age, user.ID)
    if err != nil {
        return 0, err
    }
    return result.RowsAffected()
}

// DeleteUser 删除用户
func DeleteUser(id int) (int64, error) {
    db, err := GetDB()
    if err != nil {
        return 0, err
    }
    defer db.Close()

    sqlStmt := `DELETE FROM users WHERE id =?`
    stmt, err := db.Prepare(sqlStmt)
    if err != nil {
        return 0, err
    }
    defer stmt.Close()

    result, err := stmt.Exec(id)
    if err != nil {
        return 0, err
    }
    return result.RowsAffected()
}

4. 代码说明

  • 结构体定义User结构体对应数据库中的users表结构。
  • 数据库连接GetDB函数初始化数据库连接,并设置连接池参数。
  • 增删改查方法
    • InsertUser:使用预编译SQL插入用户数据。
    • GetUser:通过预编译SQL查询单个用户。
    • UpdateUser:预编译SQL更新用户信息。
    • DeleteUser:预编译SQL删除用户。

上述代码以MySQL为例,实际使用时需根据具体数据库类型调整驱动和连接字符串。