go实现个留言本-----------------

十一文 2013-06-08 11:39:02
go实现个留言本


一、分析

要实现这个下面是几个重要的东西。

1.数据库操作(go怎么操作数据库)、
2.输出js,css,图片等
3.html显示


为什么会有以上的几个问题.下面一一分析

1.数据库操作。
go并没有提供对应的数据库操作的包。只提供了数据库的接口。各种数据库必须自己去实现数据库操作的接口。
感谢开源社区,这些别人帮你实现了。然后我们只需要导入对应的包即可。


2.输出js,css,图片
这也是个问题。这的确是个问题。上次的代码只是实现了动态页面的显示。但是js和图片这些是不同的他们有着不同的http头(不懂可以去查查http协议的东西)。不能简单的只输出内容。
信号go给我们考虑好了其http包里面有方法可实现。没法go不是专门的web服务器。一般这都是web服务器干的事情。

3.html显示
html显示的时候如果我们在代码里面直接输出,那么一旦我们每次 仅仅只是更改点html的代码却要重新编译。是不是很痛苦。
感谢go为我们提供了template包。我们可以用模板。



好吧以上问题找到了 解决的方向。那么开始吧。

我们实现一个留言本。


一个留言本的基本功能就是。提交留言,显示留言。
为了使得这个项目好理解和容易实现我们尽量简单。所以这个例子代码会非常的烂。请别砸砖头。囧!


先上go代码:
package main
import (
"database/sql"
"fmt"
_ "github.com/go-sql-driver/mysql"
"html/template"
"log"
"net/http"
"time"
)
type Message struct {
Id int
Uname string
Email string
Content string
InsertTime string
}
func CheckErr(err error) {
if err != nil {
fmt.Println("ddddddddddd")
panic(err)
}
}
func bookList(w http.ResponseWriter, r *http.Request) {
var id int
var insert_time int
var uname string
var content string
var email string
db, err := sql.Open("mysql", "root:123456@tcp(172.20.10.80:3306)/test?charset=utf8")
CheckErr(err)
rows, err := db.Query("select id, uname,content, email, insert_time from book")
CheckErr(err)
var msgSlice []*Message
for rows.Next() {
err = rows.Scan(&id, &uname, &content, &email, &insert_time)
CheckErr(err)
msg := new(Message)
msg.Id = id
msg.InsertTime = time.Unix(int64(insert_time), 0).Format("2006-01-02 15:04:05")
msg.Uname = uname
msg.Content = content
msg.Email = email
//fmt.Fprintf(w, id)
msgSlice = append(msgSlice, msg)
}
t, err := template.ParseFiles("index.html")
if err != nil {
log.Println(err)
}
t.Execute(w, &msgSlice)
}
func add(w http.ResponseWriter, r *http.Request) {
err := r.ParseForm()
uname := "hahahah 没有"
content := r.FormValue("content")
email := r.FormValue("email")
insertTime := time.Now().Unix()
db, err := sql.Open("mysql", "root:123456@tcp(172.20.10.80:3306)/test?charset=utf8")
CheckErr(err)
stmt, err := db.Prepare("insert into book(uname,content, email, insert_time)values(?,?,?,?)")
if _, err := stmt.Exec(uname, content, email, insertTime); err == nil {
//w.Write([]byte("ok"))
}
bookList(w, r)
db.Close()
}
func main() {
http.HandleFunc("/", bookList)
http.HandleFunc("/list", bookList)
http.HandleFunc("/add", add)
http.Handle("/static/", http.FileServer(http.Dir("./")))
//http.HandleFunc("/", sayhelloName) //设置访问的路由
err := http.ListenAndServe(":9090", nil) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}


首先我们勇mysql建立了个 数据库test.有一张表:

CREATE TABLE `book` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`uname` CHAR(1) DEFAULT NULL,
`email` VARCHAR(32) NOT NULL,
`content` TEXT,
`insert_time` INT(10) UNSIGNED NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=INNODB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8



uname 用户名
content 留言内容
insert_time 留言时间


然后为了操作数据库,我们导入了第三方包 _ "github.com/go-sql-driver/mysql"
这个包数据怎么弄了?首先你在系统中安装git吧(真麻烦 囧,这个自行google)
另外你得设置个gopath 可以是任意目录 第三方包惠粗在这个目录
然后通过命令go get github.com/go-sql-driver/mysql
这样第三方包就会被下载下来了。

然后才是操作数据库:

db, err := sql.Open("mysql", "root:123456@tcp(172.20.10.80:3306)/test?charset=utf8")
这里是连接数据库
mysql是数据库类型
root账号
123456密码
tcp是协议类型
172.20.10.80数据库地址
3306 端口号
/test 这个是数据库库名
utf8 编码类型 建议就用utf8吧。因为go默认是utf8 编码的(鄙视哈居然不能用中文当变量名,看看java或者c#)

操作数据库 看代码应该基本没太大问题。这里略过。


http.Handle("/static/", http.FileServer(http.Dir("./"))) 这个设置了静态路由。记住路径是以最后编译的exe文件的位置来算的


然后是模板代码:

<!doctype html>
<html>
<header>
<title>留言本</title>
<link type="text/css" rel="stylesheet" href="static/main.css"/>
</header>
<body>
<div id="container">
<h4>go语言留言本</h4>
{{range .}}
<div class="list">
<span>{{.Email}}</span>{{.InsertTime}}发表:
<p>{{.Content}}</p>
</div>
{{end}}
</div>
<div class="subform">
<form action="/add" method="post">
<em for="email">您的邮箱:</em><input type="text" id="email" name="email" /></br>
<textarea cols="100" rows="5" name="content">
....
</textarea></br>
<input type="submit" value="提交">
</form>
</div>
</body>
</html>

range 表示循环 点表示当前的对象 即 t.Execute(w, &msgSlice)中的msgSlice对象。
这里要注意 对象中的属性 必须是对外可见的 即Email Content 都必须是首字母大写的。
否则没法解析
而循环中的.Email 就是表示的msgSlice对象数组(slice)中的email属性。

贴下css和文件结构:
body{font-family: Verdana,Arial,Helvetica,sans-serif;font-size:12px}
textarea{font-family: Verdana,Arial,Helvetica,sans-serif;}
input[type=button] {-webkit-appearance: button;}
img{border:0px;}
.list{margin:5px;border:#cccccc 1px solid;min-height:100px}
.list span{margin:0 5px 0 5px;font-weight: bold;}
.list p{text-indent:2em}


文件结构:
-----
|----static
|----main.css
----main.go
----index.html



然后go run 就ok了。


最后介绍个win下的go开发工具liteIde用起来还不错。并且其还有中文版的。
(完)






...全文
3805 55 打赏 收藏 转发到动态 举报
写回复
55 条回复
切换为时间正序
请发表友善的回复…
发表回复
JPF1024 2015-05-01
  • 打赏
  • 举报
回复
不错不错
healer_kx 2015-04-27
  • 打赏
  • 举报
回复
不错,不错!
kugou123 2015-04-25
  • 打赏
  • 举报
回复
引用 50 楼 alanmaths 的回复:
导入"github.com/go-sql-driver/mysql"这个包是不是意味着编译代码的时候必须联网?
如果你本机没有这个包,用go get取一下,取的时候需要联网
JPF1024 2015-01-14
  • 打赏
  • 举报
回复
风/xin云 2014-11-12
  • 打赏
  • 举报
回复
好例子啊,学习
沙尘暗影 2014-01-28
  • 打赏
  • 举报
回复
导入"github.com/go-sql-driver/mysql"这个包是不是意味着编译代码的时候必须联网?
樱木花道 2013-08-13
  • 打赏
  • 举报
回复
nicolezyh 2013-07-31
  • 打赏
  • 举报
回复
版主 2013-07-31
  • 打赏
  • 举报
回复
十一文 2013-06-18
  • 打赏
  • 举报
回复
引用 43 楼 beginI 的回复:
请问这是C/S 还是B/S 代码咋又像JS的 GO GO GO 十一这么会玩
bs 留言本啊 当然 bs
肆水東澤 2013-06-18
  • 打赏
  • 举报
回复
谁是莫默的呢 2013-06-18
  • 打赏
  • 举报
回复
请问这是C/S 还是B/S 代码咋又像JS的 GO GO GO 十一这么会玩
  • 打赏
  • 举报
回复
谁是莫默的呢 2013-06-18
  • 打赏
  • 举报
回复
十一文,你什么毛病??GO?
十一文 2013-06-18
  • 打赏
  • 举报
回复
引用 38 楼 xiaozhihui5535 的回复:
[quote=引用 37 楼 yanzi_kiki 的回复:] 斑竹可以新开个GO语言版块啊
不是版主说了算[/quote]准备申请 大家请期待!
_萧萧 2013-06-17
  • 打赏
  • 举报
回复
引用 37 楼 yanzi_kiki 的回复:
斑竹可以新开个GO语言版块啊
不是版主说了算
  • 打赏
  • 举报
回复
斑竹可以新开个GO语言版块啊
  • 打赏
  • 举报
回复
夜轻风 2013-06-17
  • 打赏
  • 举报
回复
萧君 2013-06-17
  • 打赏
  • 举报
回复
加载更多回复(34)

2,154

社区成员

发帖
与我相关
我的任务
社区描述
go语言学习与交流版
社区管理员
  • go语言社区
  • Freeman Z
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告