Go实战(篇三)使用接口封装SQL操作
Posted 是轩哲啊
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Go实战(篇三)使用接口封装SQL操作相关的知识,希望对你有一定的参考价值。
引言
在C++中,通过使用关键字public、protected和private实现对类的封装和继承。其中public和private实现了类的封装,protected实现了类的继承。在Java中,类的修饰添加了两个个关键字default和friendly。其中default同一包中的类可以访问,声明时没有加修饰符,认为是friendly。比较内容见表1。
表1 关键字比较
C++ | Java | C# | Go | |
public | 可以被该类中的函数、子类的函数、友元函数访问,也可以由该类的对象访问 | 具有最大的访问权限,可以访问任何一个在classpath下的类、接口、异常等。它往往用于对外的情况,也就是对象或类对外的一种接口的形式。 | 公有访问,不受任何限制。 | Go的关键字中没有public |
private | 可以被该类中的函数、子类的函数、友元函数访问,但不可以由该类的对象访问 | 访问权限仅限于类的内部,是一种封装的体现,例如,大多数成员变量都是修饰符为private的,它们不希望被其他任何外部的类访问。 | 私有访问,只限于本类成员访问,子类、实例都不能访问。 | Go的关键字中没有private |
protected | 可以被该类中的函数、友元函数访问,但不可以由子类的函数、该类的对象、访问 | 主要的作用就是用来保护子类的。它的含义在于子类可以用它修饰的成员,其他的不可以,它相当于传递给子类的一种继承的东西 | 保护访问,只限于本类和子类访问,实例不能访问。 | Go的关键字中没有protected |
internal | C++的关键字中没有interface | 用于声明仅包含抽象方法的特殊类型的类 | 内部访问,只限于本项目内访问,其他不能访问。 | Go的关键字中没有internal |
default | 通过default关键字恢复构造函数 | 有时候也称为friendly,它是针对本包访问而设计的,任何处于本包下的类、接口、异常等,都可以相互访问,即使是父类没有用protected修饰的成员也可以。 | C#的关键字中没有default,这里不讨论switch语句。 | Go的关键字中没有default |
为什么要进行封装
提到封装的好处,我们想从函数说起。在我们学习计算机编程语言时,是不是习惯将一系列操作全部写在main函数中。在学到函数章节时,才会开始尝试并习惯将不同的操作写在不同的函数中。函数的使用,可以提高编码效率,较少定位错误的时间。在面对对象编程中,一个对象涉及多个变量和方法,在对象内部函数不受限制。对对象进行封装,使用者就不必关注方法是如何实现的。封装的好处如下:
- 提高了数据的安全性:调用者不能够通过变量名、属性名的方式来修改某个私有的成员属性
- 操作简单:封装后,调用者在使用的时候,只需调用方法即可,调用者不需要再进行判断
- 隐藏了实现:实现过程对调用者是不可见的,调用者只需调用方法即可,不知道具体实现过程
代码实现
数据库表结构如表2所示。
表2 user_login_info表
名字 | 类型 | 排序规则 | 属性 | 空 | 默认 | 额外 |
userID | int(10) | UNSIGNED | 否 | 无 | AUTO_INCREMENT | |
userNum (主键) | varchar(20) | uft8mb4_general_ci | 否 | 无 | ||
userPhone | varchar(11) | uft8mb4_general_ci | 是 | NULL | ||
userMail | varchar(50) | uft8mb4_general_ci | 是 | NULL | ||
userPwd | varchar(32) | uft8mb4_general_ci | 否 | 无 | ||
userRole | varchar(7) | uft8mb4_general_ci | 是 | NULL | ||
userLockTime | time | 是 | NULL | |||
created | timestamp | 否 | CURRENT_TIMESTAMP | |||
updated | timestamp | 否 | CURRENT_TIMESTAMP | ON UPDATE CURRENT_TIMESTAMP |
sqlhelper的代码如下:
package toolkit
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"log"
"time"
)
const (
USERNAME = ""
PASSWORD = ""
NETWORK = "tcp"
SERVER = "127.0.0.1"
PORT = 3306
DATABASE = ""
)
type Search interface
UserLogin(account string, password string, actype int) bool
UserRegister(account string, password string, actype int) bool
UserUpdate(account string, password string, actype int) bool
UserCancel(account string, password string, actype int) bool
type User struct
func (user User) UserInfo()
func (user User) UserLogin(account string, password string, actype int) bool
db := open()
defer db.Close()
var sql string
switch actype
case 0:
sql = fmt.Sprintf("select userNum,userPwd from user_login_info where userNum =%s and userPwd = %s;", account, password)
case 1:
sql = fmt.Sprintf("select userNum,userPwd from user_login_info where userPhone =%s and userPwd = %s;", account, password)
case 2:
sql = fmt.Sprintf("select userNum,userPwd from user_login_info where userMail =%s and userPwd = %s;", account, password)
rows, err := db.Query(sql)
if err != nil
fmt.Println("query failed:", err)
return false
for rows.Next()
var userNum, userPasswd string
err = rows.Scan(&userNum, &userPasswd)
//err = rows.Scan(&infos.fileID, &infos.fileName, &infos.fileSize, &infos.fileSource, &infos.filePayment, &infos.fileDownloads, &infos.userID, &infos.created, &infos.updated)
if err != nil
fmt.Println("scan failed:", err)
if userNum == account && userPasswd == password
return true
return false
func (user User) UserRegister(account string, password string, actype int) bool
db := open()
defer db.Close()
var sql string
switch actype
case 0:
sql = fmt.Sprintf("select 1 from user_login_info where userNum =%s limit 1;", account)
case 1:
sql = fmt.Sprintf("select 1 from user_login_info where userPhone =%s limit 1;", account)
case 2:
sql = fmt.Sprintf("select 1 from user_login_info where userMail =%s limit 1;", account)
rows, err := db.Query(sql)
if err != nil
fmt.Println("query failed:", err)
return false
num := 0
for rows.Next()
err = rows.Scan(&num)
if err != nil
fmt.Println("scan failed:", err)
fmt.Println(num)
var operation Operation
if num == 1
operation = new(Record)
operation.Writer(fmt.Sprintf("user %s register fault at %s, because it exist", account, time.Now().Format("20060102")))
return false
else
sql := fmt.Sprintf("insert into user_login_info (userNum,userPwd) values (%s,%s)", account, password)
_, err := db.Exec(sql)
if err != nil
operation = new(SQL_ERROE_SAVEPATH)
operation.Writer(err.Error() + "," + time.Now().Format("20060102"))
return false
operation = new(Record)
operation.Writer(fmt.Sprintf("user %s register successful at %s", account, time.Now().Format("20060102")))
return true
return false
func (user User) UserUpdate(account string, password string, actype int) bool
db := open()
defer db.Close()
if user.UserLogin(account, password, actype) == true
return false
var sql string
switch actype
case 0:
sql = fmt.Sprintf("update user_login_info set userPwd =%s where userNum =%s;", password, account)
case 1:
sql = fmt.Sprintf("update user_login_info set userPwd =%s where userPhone =%s;", password, account)
case 2:
sql = fmt.Sprintf("update user_login_info set userPwd =%s where userMail =%s;", password, account)
result, err := db.Exec(sql)
if err != nil
fmt.Println("update fault:", err)
return false
idAff, err := result.RowsAffected()
if err != nil
log.Println("RowsAffected failed:", err)
return false
if idAff == 0
return false
return true
func (user User) UserCancel(account string, password string, actype int) bool
db := open()
defer db.Close()
if user.UserLogin(account, password, actype) == false
return false
var sql string
switch actype
case 0:
sql = fmt.Sprintf("delete from user_login_info where userNum =%s;", account)
case 1:
sql = fmt.Sprintf("delete from user_login_info where userPhone =%s;", account)
case 2:
sql = fmt.Sprintf("delete from user_login_info where userMail =%s;", account)
result, err := db.Exec(sql)
if err != nil
fmt.Println("delete fault:", err)
return false
idAff, err := result.RowsAffected()
if err != nil
log.Println("RowsAffected failed:", err)
return false
if idAff == 0
return false
return true
func open() *sql.DB
conn := fmt.Sprintf("%s:%s@%s(%s:%d)/%s", USERNAME, PASSWORD, NETWORK, SERVER, PORT, DATABASE)
//fmt.Println("conn:", conn)
db, err := sql.Open("mysql", conn)
if err != nil
fmt.Println("connection to mysql fault:", err)
return db
db.SetConnMaxLifetime(100 * time.Second)
db.SetMaxOpenConns(100)
return db
以登陆为例,代码如下:
account := "account"
password := "password"
actype := "actype"
var search Search
search = new(User)
loginsuc := search.UserLogin(account, password, actypeInt)
fmt.Println(loginsuc)
写在最后的话
以上就是接口封装SQL操作的介绍了,暂时先写这么多,后面也会进行完善。
你知道的越多,你不知道的越多,人才们的 【三连】 就是我创作的最大动力,我们下期见!
注:如果本篇博客有任何错误和建议,欢迎人才们留言,你快说句话啊!
原文链接:Go实战(篇三)使用接口封装SQL操作_Go_轩哲驿站
以上是关于Go实战(篇三)使用接口封装SQL操作的主要内容,如果未能解决你的问题,请参考以下文章