代码拉取完成,页面将自动刷新
package commSql
import (
"database/sql"
"errors"
"gitee.com/fierce_wolf/go-fox-edge-common/commEntity"
// _ "github.com/mattn/go-sqlite3" //具体使用的时候,请在服务中,某个go文件中import这一句话
// _ "github.com/go-sql-driver/mysql" //具体使用的时候,请在服务中,某个go文件中import这一句话
)
type SQLOption struct {
DriverName string
DataSource string
}
type SqlClient struct {
db *sql.DB
}
func (e *SqlClient) ConnectMySQL() error {
if e.db != nil {
e.db.Close()
e.db = nil
}
option := buildMySQLOption()
// 连接数据库
db, err := sql.Open(option.DriverName, option.DataSource)
if err != nil {
return err
}
// 检查数据库连接是否成功
if err := db.Ping(); err != nil {
db.Close()
return err
}
e.db = db
return nil
}
func (e *SqlClient) ConnectSQLite(fileName string) error {
if e.db != nil {
e.db.Close()
e.db = nil
}
// 定义数据库连接信息
option := buildSQLite3Option(fileName)
// 连接数据库
db, err := sql.Open(option.DriverName, option.DataSource)
if err != nil {
return err
}
e.db = db
return nil
}
func (e *SqlClient) readQueryRows(entityType string, rows *sql.Rows) ([]commEntity.IEntity, error) {
// 获得返回的列信息
columns, err := rows.Columns()
if err != nil {
return nil, err
}
if columns == nil {
return nil, err
}
// 构造一个准备用来接收数据的临时行
scanRow, err := schema.buildRowVar(entityType, columns)
if err != nil {
return nil, err
}
result := make([]commEntity.IEntity, 0)
for rows.Next() {
// 读取一行数据
err = rows.Scan(scanRow...)
if err != nil {
return nil, err
}
// 将row转换为entity
entity, err := schema.buildEntity(entityType, columns, scanRow)
if err != nil {
return nil, err
}
// 保存数据
result = append(result, entity)
}
if err = rows.Err(); err != nil {
return nil, err
}
return result, nil
}
// SQuery 安全查询数据
// 说明:带预处理的方式执行SQL语句,防止注入攻击,或者特殊字符的冲突
func (e *SqlClient) SQuery(entityType string, sql string, args []interface{}) ([]commEntity.IEntity, error) {
if e.db == nil {
return nil, errors.New("尚未与数据库建立未连接")
}
// 预处理
stmt, err := e.db.Prepare(sql)
if err != nil {
return nil, err
}
defer stmt.Close()
// 执行查询
rows, err := stmt.Query(args...)
if err != nil {
return nil, err
}
defer rows.Close()
// 读取行数据
return e.readQueryRows(entityType, rows)
}
// Query 查询数据
// 说明:直接执行SQL语句,不进行预处理
func (e *SqlClient) Query(entityType string, sql string) ([]commEntity.IEntity, error) {
if e.db == nil {
return nil, errors.New("尚未与数据库建立未连接")
}
// 执行查询
rows, err := e.db.Query(sql)
if err != nil {
return nil, err
}
defer rows.Close()
// 读取行数据
return e.readQueryRows(entityType, rows)
}
func (e *SqlClient) SQueryList(sql string, fields []FieldValue, args []interface{}) ([]map[string]interface{}, error) {
if e.db == nil {
return nil, errors.New("尚未与数据库建立未连接")
}
// 预处理
stmt, err := e.db.Prepare(sql)
if err != nil {
return nil, err
}
defer stmt.Close()
// 执行查询
rows, err := stmt.Query(args...)
if err != nil {
return nil, err
}
defer rows.Close()
return e.readMapListRows(rows, fields)
}
func (e *SqlClient) QueryList(sql string, fields []FieldValue) ([]map[string]interface{}, error) {
if e.db == nil {
return nil, errors.New("尚未与数据库建立未连接")
}
// 获得返回的列信息
if len(fields) == 0 {
return nil, errors.New("fields参数缺失")
}
// 执行查询
rows, err := e.db.Query(sql)
if err != nil {
return nil, err
}
defer rows.Close()
return e.readMapListRows(rows, fields)
}
func (e *SqlClient) readMapListRows(rows *sql.Rows, fields []FieldValue) ([]map[string]interface{}, error) {
// 构造一个准备用来接收数据的临时行
scanRow, err := schema.buildRawRowVar(fields)
if err != nil {
return nil, err
}
result := make([]map[string]interface{}, 0)
for rows.Next() {
// 读取一行数据
err = rows.Scan(scanRow...)
if err != nil {
return nil, err
}
data, err := schema.buildRawRow(fields, scanRow)
if err != nil {
return nil, err
}
// 保存数据
result = append(result, data)
}
if err = rows.Err(); err != nil {
return nil, err
}
return result, nil
}
func (e *SqlClient) QueryCount(sql string) (int, error) {
if e.db == nil {
return 0, errors.New("尚未与数据库建立未连接")
}
count := 0
// 执行查询
err := e.db.QueryRow(sql).Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}
func (e *SqlClient) SQueryCount(sql string, args []interface{}) (int, error) {
if e.db == nil {
return 0, errors.New("尚未与数据库建立未连接")
}
// 预处理
stmt, err := e.db.Prepare(sql)
if err != nil {
return 0, err
}
defer stmt.Close()
// 执行查询
count := 0
err = stmt.QueryRow(args...).Scan(&count)
if err != nil {
return 0, err
}
return count, nil
}
// Exec 执行sql
// 参数:
//
// sql 准备执行的sql语句
// values sql语言中的参数表
//
// 说明:如果你构造的values参数为nil,那么你要确保自己的sql不含有文本参数的语句,不会发生注入式攻击
func (e *SqlClient) Exec(sql string, values []interface{}) (int64, error) {
if e.db == nil {
return 0, errors.New("尚未与数据库建立未连接")
}
if values != nil && len(values) > 0 {
// 预处理模式:避免注入攻击和SQL语句中携带了冲突字符的问题
stmt, err := e.db.Prepare(sql)
if err != nil {
return 0, err
}
defer stmt.Close()
// 传递参数
res, err := stmt.Exec(values...)
if err != nil {
return 0, err
}
// 获得新增数据的ID
return res.LastInsertId()
} else {
// 简单模式:直接执行SQL语句
res, err := e.db.Exec(sql)
if err != nil {
return 0, err
}
return res.LastInsertId()
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。