GoWeb及Go_Mysql相关操作

@Go Web

1)Web应用的工作原理

在这里插入图片描述

2)基本Go Web创建服务器代码编写

使用http.HandleFunc方法

package main

import (
	"net/http"
	"fmt"
	)

/*
创建一个net/http 服务,响应hello world demo
	1. 创建一个函数用来,响应请求内容
	2. 使用http.HandleFunc() 处理请求
	3. 监听端口内容,等待用户端访问
*/

// 1. 创建一个函数用来,响应请求内容
func handler(w http.ResponseWriter, r *http.Request){
	a := "hello world"
	w.Write([]byte(a))
}


func main() {
	fmt.Println("您已成功启动服务,Web请求监听localhost:8080端口")
	// 2. 使用http.HandleFunc() 处理请求
	http.HandleFunc("/",handler)
	// 3. 监听端口内容,等待用户端访问
	http.ListenAndServe("127.0.0.1:8080", nil)
}

使用http.Handle方法,并且自定义一个MyHandler struct结构体满足handler这个接口.

package main

import (
	"fmt"
	"net/http"
)
/*
自己定义一个handler 处理请求
	1. 创建一个结构体 myHenDler
	2. 创建serverHttp(),并且给myHenDler 绑定指定方法serverHttp
	3. main 中实例化结构体得到方法
	4. 4. 使用Handle("/",&myHenDler),注意这里的myHenDler.ServerHttp 必须满足w http.ResponseWriter, r *http.Request
*/

//1. 创建一个结构体 myHenDler
type MyHandler struct {

}

//2. 创建serverHttp(),并且给myHenDler 绑定指定方法serverHttp
// 注意方法中w http.ResponseWriter, r *http.Request 为固定写法,不能随意修改
func (m *MyHandler) ServeHTTP(w http.ResponseWriter, r *http.Request){
	a := "陈浩天编写的第一个后台web服务器"
	w.Write([]byte(a))
}

func main() {
	//3. main 中实例化结构体得到方法
	myHenDler := MyHandler{}
	fmt.Println("您已成功启动服务,Web请求监听localhost:8080端口")

	//4. 使用Handle("/",&myHenDler),注意这里的myHenDler.ServerHttp 必须满足w http.ResponseWriter, r *http.Request
	http.Handle("/",&myHenDler)

	//5. 监听端口内容,等待用户端访问
	http.ListenAndServe(":8080",nil)
}

使用自定义server结构体参数,详细配置ListenAndServe,上述重复内容就没有过多赘述,了解即可

//4. 创建server结构
	server := http.Server{
		Addr:	":8080",
		Handler:	&myHenDler,
		ReadTimeout:	2 * time.Second,
	}
	fmt.Println("您已成功启动服务,Web请求监听localhost:8080端口")

	//4. 使用HandleFunc("/",myHenDler.ServeHTTP),注意这里的serverHttp 必须满足w http.ResponseWriter, r *http.Request
	//http.Handle("/",&myHenDler)
	//5. 使用server.ListenAndServe监听端口内容,等待用户端访问,因为server结构体中已经详细定义了,**所以使用ListenAndServe不用再传参数**
	server.ListenAndServe()

使用自定义多路复用器,上述重复内容就没有过多赘述

package main

import (
	"fmt"
	"net/http"
)

/*
自己定义一个ServeMux,通过新的ServeMux,处理http请求
	1. 通过NewServeMux 创建一个新的多路复用器
	2. 创建一个函数handler(w http.ResponseWriter, r *http.Request),固定格式
	3. 监听端口,选择多路路由复用器mux
	4. 调用mux的HandleFunc处理请求访问
*/

//	2. 创建一个函数handler(w http.ResponseWriter, r *http.Request),固定格式
func handler(w http.ResponseWriter, r *http.Request){
	a := "自己创建多路复用器"
	w.Write([]byte(a))
}

func main() {
	//	1. 通过NewServeMux 创建一个新的多路复用器
	mux := http.NewServeMux()
	fmt.Println("您已成功启动服务,Web请求监听localhost:8080端口")
	
	//	4. 调用mux的HandleFunc处理请求访问
	mux.HandleFunc("/",handler)

	//	3. 监听端口,选择多路复用器mux
	http.ListenAndServe(":8082",mux)
}


@Go MySql

1)操作数据库前提

    Go 语言中的database/sql 定义了对数据库的一系列操作。database/sql/driver包中定义了应被数据库驱动
实现的接口,我们需要导入第三方的数据库驱动,不过我们连接数据库之后对数据库操作大部分代码都是
通过sql包来实现的。

2)操作数据库编码

首先编写一个dbsql文件,获取数据库链接句柄。

package dbsql

import (
	// 官方提供的接口文档,我们通过sql 包中的结构体函数
	"database/sql"
	"log"

	// 我们只是要使用mysql 这个报下的init函数,所以前面用匿名导包方式,本文件并不会去调用mysql下的任何内容方法
	_ "github.com/go-sql-driver/mysql"
)

/*
得到一个数据库句柄
	1. 声明一个*sql.DB 类型的变量接受,sql.Open后的参数,err error 类型的变量判断句柄是否正常
	2. 注意:这里的变量要大写,因为其他包中要使用到Db 和Err 这两个变量
	** 本文件的作用:
		用于获取到一个数据库句柄,将句柄返回给导入本包的文件使用
*/

var(
	// 声明一个*sql.DB 类型的变量接受,sql.Open后的参数
	Db *sql.DB
	Err error
)

func init(){
	Db, Err = sql.Open("mysql","root:a@199862@tcp(localhost:3306)/zhangsan")
	if Err != nil {
		log.Panicln("sql.Open is error:", Err)
	}
}

得到数据库句柄后,操作数据库表usersinsert 插入内容。

package users

import (
	"log"
	"goWeb/dbsql"
)

/*
创建结构体,对应数据库表中的字段,
为结构体绑定对应操作数据库表的方法
增删改查
	//1. 创建User结构体
	//2. 添加AddUser方法   (AddUser和AddUser2两种方法的区别在于一个使用了预处理,一个直接调用Exec 执行)
	//3. 添加AddUser2方法
*/

// User 结构体 对应数据库表中的字段与类型
type User struct {
	Id       int
	Username string
	Password string
	Email    string
}

Adduser 预处理添加User的方法

func (user *User) AddUser() error {
	/*
		1. 编写SQL语句
		2. 预处理
		3. 执行
	*/

	// 写sql 语句
	sqlStr := "insert into users (username,password,email) values(?,?,?)"
	// 预处理
	instmt, err := dbsql.Db.Prepare(sqlStr)
	if err != nil {
		log.Println("预处理异常")
		return err
	}
	// 执行
	_, err2 := instmt.Exec("admin","123456","admin@atguigu.com")
	if err2 != nil {
		log.Println("执行异常")
		return err
	}
	return nil
}

Adduser2 添加User的方法

func (user *User) AddUser2() error {
	/*
		1. 编写SQL语句
		2. 执行
	*/

	// 写sql 语句
	sqlStr := "insert into users (username,password,email) values(?,?,?)"
	// 执行语句
	_, err := dbsql.Db.Exec(sqlStr,"admin2","666666","admin2@atguigu.com")
	if err != nil {
		log.Println("执行异常")
		return err
	}
	return nil
}

SelectUsersAll 查询users表中所有方法

// Selectusers 查询users表所有方法
func (user *User) SelectUsersAll() ([]*User,error) {
	/*
	查询users表所有内容
		1. 指定sql查询语句
		2. 获取Rows结构体
		3. 指定游标,通过游标一行一行读取数据,并且存储到一个结构体中
		4. 创建一个Users []*User 切片
		5. 将新的结构体存放到Users 这个切片当中
		6. 返回Users 和err
	*/

	// 1. 指定sql查询语句
	sqlStr := "select * from users"
	// 4. 创建一个Users []*User 切片
	var Users []*User

	//2. 获取Rows结构体
	rows, err := dbsql.Db.Query(sqlStr)
	if err != nil {
		fmt.Println("查询失败")
	}
	
	//3. 指定游标,每一次Next 指定下一行内容
	for rows.Next(){
		var id int
		var username string
		var password string
		var email string
		err := rows.Scan(&id, &username, &password, &email)
		if err != nil {
			break
		}
		var u *User = &User{
			Id: id,
			Username: username,
			Password: password,
			Email: email,
		}
		
		//5. 将新的结构体存放到Users 这个切片当中
		Users = append(Users, u)
	}
	fmt.Println(Users)
	
	//6. 返回Users 和err
	return Users, err
}

Selectusers 查询users表一行方法,这里的问号是占位符

func (user *User) SelectUsersOne() (*User,error){
	/*
	Selectusers 查询users表一行方法
		1. 指定sql查询语句
		2. 获取Rows结构体
		3. row.Scan 扫描该行内容所有字段,并一一对应赋值
		4. 返回user结构体
	*/
	//1. 指定sql查询语句
	sqlStr := "select * from users where id = ?"
	//2. 获取Row结构体
	row := dbsql.Db.QueryRow(sqlStr, user.Id)
	//3. row.Scan 扫描该行内容所有字段,并一一对应赋值
	err := row.Scan(&user.Id, &user.Username, &user.Password, &user.Email)
	if err != nil {
		return nil, err
	}
	//4. 返回user结构体
	return user, nil
}


@GoWeb 处理请求

Go 语言的net/http 包提供了一系列用于表示HTTP报文的结构,我们可以使用它处理请求和发送响应,其中Request结构代表了客户端发送的请求报文,下面一起来学习操作一下。

获取请求路径r.URL.Path,获取请求参数r.URL.RawQuery

// 自定义处理函数中,r.URL.Path 代表访问路径如(localhost/hello,那么本次显示的路径就是/hello),r.URL.RawQuery代表url?后面的参数如(localhost/hello?name=zhangsan&age=13),那么本次显示的内容就是name=zhangsan&age=13


func handler(w http.ResponseWriter, r *http.Request){
	fmt.Printf("%v%v\n",

	// 自定义处理函数中,r.URL.Path 代表访问路径如(localhost/hello,那么本次显示的路径就是/hello)
	r.URL.Path,

	//r.URL.RawQuery代表url?后面的参数如(localhost/hello?name=zhangsan&age=13),那么本次显示的内容就是name=zhangsan&age=13
	r.URL.RawQuery)
}

读取请求头Header中的信息

//	2. 创建一个处理请求函数handler(w http.ResponseWriter, r *http.Request),固定格式
func handler(w http.ResponseWriter, r *http.Request){
	a = fmt.Sprintf("%v \n%v \n%v \n",
		//r.Header 是一个map 类型,所有请求头信息以键值对方式存放在map中
		r.Header,

		//r.Header["Accept-Encoding"] 取头字段中的值以[] 切片形式返回
		r.Header["Accept-Encoding"],

		//r.Header["Accept-Encoding"] 取头字段中的值以值 形式返回
		r.Header.Get("Accept-Encoding"))
	w.Write([]byte(a))
}

读取请求体Body中的信息

//	2. 创建一个处理请求函数handler(w http.ResponseWriter, r *http.Request),固定格式
func handler(w http.ResponseWriter, r *http.Request){
	/*
		读取Post请求发送过来的请求体内容,并返还给前端浏览器页面
		r.ContentLength 获取请求体内容的长度
		r.Body.Read   读取Body内容放到body[]byte切片中
		w.Write(body) 将读取到的body返回给浏览器前端
	*/

	// 获取body长度
	length := r.ContentLength
	// 创建一个[]byteq
	body := make([]byte, length)
	// 读取请求体内容读取到body中
	r.Body.Read(body)
	// 将读取到的body返回给浏览器前端
	w.Write(body)
}

获取请求参数

// r.Method 返回字符串返回当前客户端请求方法
if r.Method != "Get" {
		// Post 请求
		leng := r.ContentLength
		body := make([]byte, leng)
		r.Body.Read(body)
		w.Write(body)
	} else {
		// Get 请求
		r.ParseForm()
		username := r.FormValue("username")
		password := r.FormValue("password")
		res := fmt.Sprintf("用户名:%v \n密码:%v",username,password)
		w.Write([]byte(res))
	}


@Goweb 响应客户端

1)向客户端返回字符串类型数据

// 按照固定类型返回
func handler(w http.ResponseWriter, r *http.Request) {
	r.ParseForm()
	res := fmt.Sprintf("请求方法 %v\n请求用户名:%v\n请求用户密码: %v", r.Method, r.Form.Get("username"), r.Form.Get("password"))
	// w.Write响应客户端内容	
	w.Write([]byte(res))
	fmt.Println(r.URL.RawPath)
}

2)向客户端返回模板数据

func testTemplate(w http.ResponseWriter, r *http.Request) {
	/*
	前端响应,模板内容:
		1. 解析模板,默认会选择第一个
		2. 传入动态内容返回给前端
		3. 若需要指定解析模板,t.ExecuteTemplate
	*/

	//		1. 解析模板,默认会选择第一个
	t, _ := template.ParseFiles("index.html","hello.html")
	//		2. 传入动态内容返回给前端
	t.Execute(w, "hello world")
    //		3. 若需要指定解析模板,t.ExecuteTemplate
	t.ExecuteTemplate(w, "hello.html","hello 世界")
}

3)简单的首页登录,提交表单跳转首页

IndexHandler 登录页面
IndexHandler1 首页页面
编写以上两个函数,处理相关请求
登录提交表单数据,后台将数据拿出显示到主页面
package main

import (
   "fmt"
   "html/template"
   "net/http"
)

/*
   简单的首页登录,提交表单跳转首页
   IndexHandler 登录页面
   IndexHandler1 首页页面
   编写以上两个函数,处理相关请求
   登录提交表单数据,后台将数据拿出显示到主页面
*/
func IndexHandler(w http.ResponseWriter, r *http.Request){
   // 解析模板
   t, _ := template.ParseFiles("views/index.html")
   // 返回模板内容
   t.Execute(w,"")
}
func IndexHandler1(w http.ResponseWriter, r *http.Request)  {
   r.ParseForm()
   user := r.FormValue("username")
   pwd := r.FormValue("password")
   res := fmt.Sprintf("欢迎来到主页面 %v,\n您的密码是 %v",user,pwd)
   w.Write([]byte(res))
}

func main() {
   http.HandleFunc("/main", IndexHandler)
   http.HandleFunc("/index", IndexHandler1)
   fmt.Println("Web程序启动成功,请访问locahost地址80端口")
   http.ListenAndServe(":80", nil)
}

4)http.StripPrefix路径重定向

func main() {
   http.HandleFunc("/main", IndexHandler)
   http.HandleFunc("/index", IndexHandler1)

   //http.StripPrefix 类似于重定向,当客户端访问指定地址,触发函数http.FileServer打开重定向到指定路径,
   //可以显示指定目录下内容,注意此处http.Dir只能指定目录,不能打开文件
   http.Handle("/a/", http.StripPrefix("/a/",http.FileServer(http.Dir("views/static"))))

   fmt.Println("Web程序启动成功,请访问locahost地址80端口")
   http.ListenAndServe(":80", nil)
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值