SQL基礎知識回顧--(Go/Python/Beego ORM/Django ORM/原生Sql)

序言

Filecoin即將上線、我們知道filecoin是由goLang編寫的,所以在此間歇期,我打算同時複習一下go和python的知識,本文的側重點在於如何高效率的使用orm-sql語句。

Go操作mysql

  Golang可以操作原生sql,具體實現如下,但基礎語句直接操作原生sql,在實際開發過程中,需要封裝大量的處理類函數,很是麻煩,因爲orm提供了更好的方式,所以我建議基礎語句(基本的增刪查改)使用orm,而複雜的語句就使用原生sql。

1.安裝git(略)
2.go get github.com/go-sql-driver/mysql 安裝之後會放在go path 目錄下 

3.連接代碼如下

package main

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

var(
	dbhost="127.0.0.1"
	dbuser="root"
	dbpasswd="root"
	dbName="project01"
)
func errorCheck(err error){
	if err!=nil{
		fmt.Println("mysql conncet error")
		panic(err)
	}
}
func main(){
	db,err:=sql.Open("mysql",dbuser+":"+dbpasswd+"@tcp("+dbhost+")/"+dbName+"?charset=utf8")
	defer db.Close()
	errorCheck(err)
	//檢測是否連接成功,如果返回值err有值則代表失敗
	err=db.Ping()
	fmt.Println(err)
}

4.執行語句如下:(包括增、刪、改)

func insert_db(insert_sql [][]string,db *sql.DB)(error){
	db_obj,error:=db.Prepare("insert into stu values (?,?)")
	for _,value :=range insert_sql{
		resultobj,err:=db_obj.Exec(value[0],value[1])
		n,_:=resultobj.RowsAffected()
		fmt.Println(resultobj,err,n)
	}
	return error
}

5.查詢語句如下:

func get_info(sql string,db *sql.DB){
	var id,name string
	//單行查詢,默認返回第一行數據
	row:=db.QueryRow(sql)
	row.Scan(&id,&name)
	fmt.Println(id,name)
	//多行查詢,rows.Next 有值爲1,無值爲0
	rows,_:=db.Query(sql)
	for rows.Next(){
		rows.Scan(&id,&name)
		fmt.Println(id,name)
	}

}

6.完整代碼如下:

package main

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

var(
	dbhost="127.0.0.1"
	dbuser="root"
	dbpasswd="root"
	dbName="project01"
)
func errorCheck(err error){
	if err!=nil{
		fmt.Println("mysql conncet error")
		panic(err)
	}
}
func insert_db(insert_sql [][]string,db *sql.DB)(error){
	db_obj,error:=db.Prepare("insert into stu values (?,?)")
	for _,value :=range insert_sql{
		resultobj,err:=db_obj.Exec(value[0],value[1])
		n,_:=resultobj.RowsAffected()
		fmt.Println(resultobj,err,n)
	}
	return error
}
func get_info(sql string,db *sql.DB){
	var id,name string
	//單行查詢,默認返回第一行數據
	row:=db.QueryRow(sql)
	row.Scan(&id,&name)
	fmt.Println(id,name)
	//多行查詢,rows.Next 有值爲1,無值爲0
	rows,_:=db.Query(sql)
	for rows.Next(){
		rows.Scan(&id,&name)
		fmt.Println(id,name)
	}

}
func main(){
	db,err:=sql.Open("mysql",dbuser+":"+dbpasswd+"@tcp("+dbhost+")/"+dbName+"?charset=utf8")
	defer db.Close()
	errorCheck(err)
	//檢測是否連接成功,如果返回值err有值則代表失敗
	err=db.Ping()
	get_sql:="select * from stu"
	get_info(get_sql,db)

	//insert_values:=[][]string{{"5","laughing"},{"6","spring"}}
	//error1:=insert_db(insert_values,db)
	//fmt.Println(error1)
}

Beego操作ORM(基礎語句建議多使用)

安裝 ORM:

go get github.com/astaxie/beego/orm

 據數據庫自動生成 go 代碼(從數據庫自動生成models):

1.安裝

首先我們要下載該工具 :

 go get github.com/gohouse/converter
然後我們創建一個go文件執行:
package main
import (
	"fmt"
	"github.com/gohouse/converter"
)
func main() {
	err := converter.NewTable2Struct().
		SavePath("/home/go/project/model/model.go").
		Dsn("root:root@tcp(localhost:3306)/test?charset=utf8").
		Run()
	fmt.Println(err)
}

 

2.查看

此時在gopath中 我們可以看見一個models的目錄,點擊進入這個目錄 裏面的model.go即爲生成的文件 

 創建、最簡單ID查詢、插入一條數據操作如下:

package controllers

import (
	"github.com/astaxie/beego"
	"github.com/astaxie/beego/orm"
	_"github.com/go-sql-driver/mysql"   //請手動引入mysql驅動
)

type UserController struct {
	beego.Controller
}
type User struct {
	Id int
	Name string
}
func ErrorHandler(err error){
	beego.Info(err)
}
func (this *UserController) Get(){
	//1.連接數據庫
	err:=orm.RegisterDataBase("default","mysql","root:root@tcp(127.0.0.1:3306)/project01?charset=utf8")
	ErrorHandler(err)
	//2.註冊創建數據庫、若已有database則可將參數force改爲false跳過創建,verbose參數爲True時顯示創建過程
	orm.RegisterModel(new(User))
	err=orm.RunSyncdb("default",false,true)
	ErrorHandler(err)
	//3.獲取orm對象和待查詢的User對象
	OrmObject:=orm.NewOrm()
	UserObj:=User{Id:1}
	//4.將兩個對象搭橋,創建查詢關係
	err=OrmObject.Read(&UserObj)
	ErrorHandler(err)
	//5.打印查詢的數據
	beego.Info(UserObj.Name)
	this.Ctx.WriteString("GET sucess")
}
func (this *UserController) Post(){
	//1.連接數據庫
	err:=orm.RegisterDataBase("default","mysql","root:root@tcp(127.0.0.1:3306)/project01?charset=utf8")
	ErrorHandler(err)
	//2.註冊創建數據庫、若已有database則可將參數force改爲false跳過創建,verbose參數爲True時顯示創建過程
	orm.RegisterModel(new(User))
	err=orm.RunSyncdb("default",false,true)
	ErrorHandler(err)
	//3.獲取orm對象和待插入數據的User對象
	OrmObject:=orm.NewOrm()
	UserObj:=User{}
	UserObj.Name="韓梅梅"
	//4.將兩個對象搭橋,創建查詢關係
	Number,err:=OrmObject.Insert(&UserObj)
	beego.Info(Number)
	ErrorHandler(err)
	this.Ctx.WriteString("sucess")
}

以上類容便是基礎知識點了,下面我們通過練習來加強對orm、sql的理解:

(ps:

1、 一道題會用三種方案解決:1sql、2beego Orm 3Django Orm

2、Django爲python的重量級框架,爲了鞏固python知識這裏我們也將djangoOrm的解決方案寫入。)

一、我們先利用python Django生成表結構

from django.db import models
# 創建表結構
# Create your models here.

class Class_grade(models.Model):
    """年級表"""
    gid = models.AutoField(primary_key=True)
    gname = models.CharField(max_length=32)

class Teacher(models.Model):
    """老師表"""
    tid = models.AutoField(primary_key=True)
    tname = models.CharField(max_length=32)

class Classtb(models.Model):
    """班級表"""
    cid = models.AutoField(primary_key=True)
    caption = models.CharField(max_length=32)
    grade = models.ForeignKey(to="Class_grade", on_delete=models.CASCADE)
    # 多對多
    teachers = models.ManyToManyField(to="Teacher")

class Student(models.Model):
    """學生表"""
    sid = models.AutoField(primary_key=True)
    sname = models.CharField(max_length=32)
    gender = models.CharField(max_length=32)
    classtb = models.ForeignKey(to="Classtb",on_delete=models.CASCADE)

class Course(models.Model):
    """課程表"""
    cname = models.CharField(max_length=32)
    teacher = models.ForeignKey(to="Teacher",on_delete=models.CASCADE)

class Score(models.Model):
    """成績表"""
    student = models.ForeignKey(to="Student",on_delete=models.CASCADE)
    course = models.ForeignKey(to="Course",on_delete=models.CASCADE)
    score = models.IntegerField()  #整數

二、增加數據

def addclass(request):
    Student.objects.create(sname="喬丹",gender="女",classtb_id=1)
    Student.objects.create(sname="艾弗森",gender="女",classtb_id=1)
    Student.objects.create(sname="科比",gender="男",classtb_id=2)
    Student.objects.create(sname="清風徐來",gender="男",classtb_id=3)
    Course.objects.create(cname="生物",teacher_id=1)
    Course.objects.create(cname="體育",teacher_id=1)
    Course.objects.create(cname="物理",teacher_id=2)
    c1=Classtb.objects.create(caption="一年一班",grade_id=1)
    c2=Classtb.objects.create(caption="二年一班",grade_id=2)
    c3=Classtb.objects.create(caption="三年二班",grade_id=3)
    Score.objects.create(student_id=1,course_id=1,score=60)
    Score.objects.create(student_id=1,course_id=2,score=59)
    Score.objects.create(student_id=2,course_id=2,score=99)
    #多對多添加表記錄
    c1.teachers.add(*[1, 2])
    c2.teachers.add(*[1, 3])
    c3.teachers.add(2)
    return HttpResponse("ok")

三、練習題:

下文查詢格式爲:
1.  問題                                 //此處爲問題

select * from XXX                       //第一句爲sql語句
models.User.object.all()               //第二句爲Django
ormObj.QueryTable("XXX").RelatedSel()  //第三句爲Beego

2、查詢學生總人數;Count

SELECT COUNT(sid) FROM project_student;         //sql
studentNum=Student.objects.all().count()        //Django  orm
n,err:=o.QueryTable("Project_student").Count()  //beego orm
# 3、查詢“生物”課程和“物理”課程成績都及格的學生id和姓名;

sql:
分組:
select sid,sname from student where sid in(
                select score.student_id from score inner join course on score.course_id=course.cid
                where course.cname in(
                    "生物",
                    "物理")
                    and score.score >= 60 
                    group by score.student_id
                    having count(course_id) = 2
                    );



# 3、查詢“生物”課程和“物理”課程成績都及格的學生id和姓名;
Django:

Score.objects.filter(Q(course__cname='生物')|Q(course__cname='物理'),score__gte=60).values("student_id","student__sname").annotate(c_course=Count("course__cname")).filter(c_course=2)

 

# 3、查詢“生物”課程和“物理”課程成績都及格的學生id和姓名;(Beego)
1.orm執行原生sql:
o:=orm.NewOrm()
	var maps []orm.Params
	var sql string
	tmp:=[]string{"生物","物理"}
	score:=60
	sql="select sid,sname from student where sid in( " +
		"select score.student_id from score inner join course on score.course_id=course.id " +
		"where  course.cname in(?,?) and score.score >= ? " +
		"group by score.student_id " +
		"having count(course_id) = ? " +
		");"
	num,err:=o.Raw(sql,tmp,score,"2").Values(&maps)
	if err!=nil{
		beego.Info(err)
	}
	if err==nil && num>0{
		for _,value:=range maps{
			beego.Info(value)
		}
	}


2.orm查詢數據、beego處理數據
func removePro(ddbenv []string, k int) []string {

	return append(ddbenv[:k], ddbenv[k+1:]...)
}
func (this *SqlControllers)HandleSql(){
	o:=orm.NewOrm()
	var score []*model.Score
	qs:=o.QueryTable("Score")
	n,err:=qs.RelatedSel("Student","Course").Filter("Score__gte",60,).Filter("Course__id__in",1,3).All(&score)
	beego.Info(n,err)
	tmp:=[]string{}
	num:=map[string]int{}
	for _,value :=range score{
		beego.Info(value.Student.Sname,value.Score,value.Course.Cname,"Wwwwwwwwwww")
		if len(tmp)!=0{
			//1.如果tmp中老元素已存在,則將加1、    2.若加了1則刪除tmp中的老元值,防止重複
			for _,item:= range tmp{
				if item==value.Student.Sname{
					num[item]+=1
					for k,v :=range tmp{
						if v==item{
							tmp=removePro(tmp,k)
						}
					}
				}
			}
		}
		//添加數據庫中取出的元素
		tmp=append(tmp,value.Student.Sname )
	}
	beego.Info(tmp,num)

	this.Ctx.WriteString("ok")
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章