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")
}
发布了20 篇原创文章 · 获赞 0 · 访问量 3801

猜你喜欢

转载自blog.csdn.net/Laughing_G/article/details/103124527