Go实战(篇三)使用接口封装SQL操作

图片待插入

引言

在C++中,通过使用关键字public、protected和private实现对类的封装和继承。其中public和private实现了类的封装,protected实现了类的继承。在Java中,类的修饰添加了两个个关键字default和friendly。其中default同一包中的类可以访问,声明时没有加修饰符,认为是friendly。比较内容见表1。

表1 关键字比较

C++
JavaC#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表
名字类型排序规则属性默认额外
userIDint(10)
UNSIGNEDAUTO_INCREMENT
userNum (主键)varchar(20)

uft8mb4_general_ci



userPhonevarchar(11)uft8mb4_general_ci
NULL
userMailvarchar(50)uft8mb4_general_ci
NULL
userPwdvarchar(32)uft8mb4_general_ci

userRolevarchar(7)uft8mb4_general_ci
NULL
userLockTimetime

NULL
createdtimestamp

CURRENT_TIMESTAMP 
updatedtimestamp

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操作的介绍了,暂时先写这么多,后面也会进行完善。


你知道的越多,你不知道的越多,人才们的 【三连】 就是我创作的最大动力,我们下期见!


注:如果本篇博客有任何错误和建议,欢迎人才们留言,你快说句话啊!

#转载请注明出处!
快来制作你的简历吧 ,请猛戳这里→点击在线制作
宝塔服务器面板,一键全能部署及管理,送你3188元礼包。请猛戳这里→点我领取

本文标题:《Go实战(篇三)使用接口封装SQL操作》作者:dongchenxuan
原文链接:http://blog.dongchenxuan.com/?id=69
特别注明外均为原创,转载请注明。

分享到微信

扫描二维码

可在微信查看或分享至朋友圈。

相关文章

发表评论:
验证码

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

dongchenxuan

dongchenxuan

你好,朋友

真是美好的一天!

访客信息

  • IP: 3.145.179.120
  • 地点: United StatesOhioDublin

标签列表

站点信息

  • 文章总数:69
  • 页面总数:2
  • 分类总数:19
  • 标签总数:34
  • 评论总数:7
  • 浏览总数:157370
您好,欢迎到访网站!
忘记密码

网站分类

文章归档

歌曲 - 歌手
0:00