对操作mysql数据库进行简单的面向对象封装

基本的结构体

type dbConn struct{
	db *sql.DB
	tx *sql.Tx
}

func NewDBConn()(*dbConn){
	return &dbConn{}
}

初始化数据库

func (conn *dbConn)Init()(error){
	var err error
	conn.db,err = sql.Open("mysql","root:root@tcp(localhost:3306)/salehouse?charset=utf8");
	if err!=nil{
		return ErrorMsg("不能链接数据库",err)
	}
	return ErrorMsg("",err)
}

重写begin函数

func (conn *dbConn) Begin()(error){
	var err error
	conn.tx,err=conn.db.Begin() //赋值给tx
	return ErrorMsg("",err)
}

重写close函数

func (conn *dbConn) Close()(error){
	if(conn.IsNULL()){
		return ErrorMsg("连接数据库为空",nil)
	}
	conn.db.Close()
	conn.db = nil
	return ErrorMsg("",nil)
}

判断时候为空

func (conn *dbConn)IsNULL()(bool){
	return conn.db==nil
}

简单的错误信息

func ErrorMsg(msg string,err error)(error){
	if(err==nil){
		if(msg==""){
			return err
		}
		return errors.New(msg)
	}
	return err
}

假设现在操作的人员的表 对应的表user如下:

type User struct{
	Tid int
	account string
	pwd string
}

func NewUser(tid int,account string ,pwd string)(User){
	return  User{"tid":tid,"account":account,"pwd":pwd}
}

CRUD操作

查找

使用 db.Query 获取多行数据

func (conn dbConn)GetUser()([]User,error){
	users:=make([]User,20)
	if(conn.IsNULL()){
		return users,ErrorMsg("连接数据库为空",nil)
	}
	rows,err := conn.db.Query("select tid,account,pwd from demo_user");
	if err!=nil {
		return users,ErrorMsg("查询失败",nil)
	}
	defer rows.Close();
	cols,_ :=  rows.Columns();
	for i := range cols { //查看表的列
		fmt.Print(cols[i]);
		fmt.Print("\t");
	}
	fmt.Print("\n");
	i:=0
	user:=User{}
	for rows.Next(){
		if err := rows.Scan(&user.Tid,&user.Account,&user.Pwd);err==nil {
			if i < 20 {
				users[i] = user
			}else{
				users = append(users,user)
			}
			i++;
		}
	}
	newUser:=users[:i]

	return newUser,ErrorMsg("连接数据库为空",nil)
}

使用 QueryRow 获取单条数据

func(conn dbConn)GetUserCount()(int,error){
	var num int = 0
	if(conn.IsNULL()){
		return num,ErrorMsg("连接数据库为空",nil)
	}
	err:=conn.db.QueryRow("select count(tid) from demo_user").Scan(&num)
	if(err!=nil){
		return num,ErrorMsg("查询失败",nil)
	}
	return num,nil
}

增删改

  • 在这里我先说好使用要使用的sql语句
var (
	insert string = "insert into demo_user(account,pwd)values(?,?)"
	update string = "update demo_user set account=?,pwd=? where tid=?"
	delete string = "delete from demo_user where tid=?"
)

使用 Exec执行sql语句

func (conn dbConn)SQLExec(sql string,params ...interface{})(sql.Result,error){
	if(conn.IsNULL()){
		return nil, ErrorMsg("连接数据库为空",nil)
	}
	result,err:=conn.db.Exec(sql,params...)
	return result,ErrorMsg("",err)
}
func main(){
	conn:=NewDBConn()
	err :=conn.Init()
	if(err!=nil){
		fmt.Println("不能初始化数据库")
	}
	result,_:=conn.SQLExec(insert,"赵四",123465)
	resultid,_:= result.LastInsertId()
	conn.SQLExec(delete,resultid)
	conn.SQLExec(insert,"王九",123465)
	result,_ = conn.SQLExec(insert,"宋七",123465)
	resultid,_ = result.LastInsertId()
	conn.SQLExec(update,"宋七",456798,resultid)
	conn.Close()
}

使用prepare处理数据

prepare*Stmt
_,err:=conn.db.Prepare(sql)
prepareStmt.Close()
func (conn *dbConn) SQLDBStmt(sql string,params ...interface{})(sql.Result,error){
	if(conn.IsNULL()){
		return nil, ErrorMsg("连接数据库为空",nil)
	}
	Stmt,err:=conn.db.Prepare(sql) // 返回*stmt指针
	if(err!=nil){
		return nil,ErrorMsg("Prepare出错",nil)
	}
	defer  Stmt.Close()
	result,err2:=Stmt.Exec(params...)
	return result,ErrorMsg("",err2)
}

先使用sql.db.prepar的方法获取stmt,这样可以在stmt关闭之前处理大量的数据

开启事务处理数据

func (conn *dbConn) SQLTxStmt(sql string,params ...interface{})(sql.Result,error){
	if(conn.IsNULL()){
		return nil, ErrorMsg("连接数据库为空",nil)
	}
	conn.Begin()
	Stmt,err:=conn.db.Prepare(sql)
	if(err!=nil){
		return  nil,ErrorMsg("Prepare出错",nil)
	}
	defer Stmt.Close()
	result,err2:=Stmt.Exec(params...)
	if err2!=nil {
		conn.tx.Rollback()
		return result,ErrorMsg("",err2)
	}
	conn.tx.Commit()
	return result,ErrorMsg("",nil)
}
DB.begin()tx.prepare()Rollback()
commitrollbackbegincommitrollback