xorm基礎學習
- 為什么要學習xorm
- 原本的JDBC操作數據庫已經滿足我們的所有需求了,但是我們還要提出一個概念叫做:orm(Object-Relation Mapping),一種對象與關系型數據庫之間的映射,也可以說將對象持久化到磁盤。通過這樣的技術能夠將減少代碼、便於理解和操作數據庫、是數據訪問層和數據庫層清晰分界、而且能夠提高服務器的性能
package main
import (
"log"
"os"
"github.com/go-xorm/xorm"
"xorm.io/core"
_ "github.com/lib/pq"
)
var engine *xorm.Engine
func init() {
log.SetFlags(log.Ldate | log.Lshortfile)
var err error
connStr := "postgres://postgres:ysm@121388@localhost/experiment?sslmode=disable"
engine, err = xorm.NewEngine("postgres", connStr)
if err != nil {
log.Println(err)
}
log.Println("開啟postgres數據成功")
f, err := os.OpenFile("sql.log", os.O_APPEND|os.O_CREATE|os.O_RDWR, 0666)
if err != nil {
log.Println(err)
return
}
engine.SetLogger(xorm.NewSimpleLogger(f))
engine.Logger().SetLevel(core.LOG_DEBUG)
engine.ShowSQL(true)
// 設置命名規則,遵從駝峰規則,但是對特殊詞支持的更好,使得ID翻譯為id而不是i_d, 但是創建表的格式好奇怪啊 select 語句會變成SELECT "ID", "Content", "Version", "UpdateTime", "CreateTime" FROM public."TPhoto";
// engine.SetMapper(core.SameMapper{})
}
// TPhoto 創建圖片表
type TPhoto struct {
Id int64 `xorm:"pk notnull unique autoincr"`
Content string `xorm:"notnull"`
Version int64 `xorm:"version"`
UpdateTime int64 `xorm:"updated"`
CreateTime int64 `xorm:"created"`
Name string `xorm:"varchar notnull"`
}
// ShowAllTables 顯示所有的table
func ShowAllTables() {
info, err := engine.DBMetas()
if err != nil {
log.Println(err)
return
}
for _, v := range info {
log.Println(v.Name)
}
}
// createTable 創建表
func createTable() {
tPhoto := &TPhoto{}
// 創建表
isExist, err := engine.IsTableExist("t_photo")
if err != nil {
log.Println(err)
return
}
if !isExist {
err := engine.CreateTables(tPhoto)
if err != nil {
log.Println(err)
}
}
// 結構體和表一致,當結構體改變的時候,也能夠根據結構體的內容修改表的結構
err = engine.Sync2(tPhoto)
if err != nil {
log.Println(err)
}
}
// createTableSQL 原生的創建表的方式
func createTableSQL() {
SQL := "create table t_small_photo(id int primary key,name varchar)"
isExit, err := engine.IsTableExist("t_small_photo")
if err != nil {
log.Println(err)
return
}
if isExit {
log.Println("t_small_photo已經存在")
}
_, err = engine.Exec(SQL)
if err != nil {
log.Println(err)
return
}
isExit, err = engine.IsTableExist("t_small_photo")
if err != nil {
log.Println(err)
return
}
if isExit {
log.Println("t_small_photo存在")
}
}
// dropTable 刪除表
func dropTable() {
tPhoto := &TPhoto{}
// 判斷指定表是否存在
isExist, err := engine.IsTableExist("t_photo")
if err != nil {
log.Println(err)
return
}
if !isExist {
// 刪除指定的表
err := engine.DropTables(tPhoto)
if err != nil {
log.Println(err)
}
}
}
// insertData 插入數據庫,會根據不同的結構體的名字找到表,進行相應數據的修改
func insertData() {
// 插入一條數據
tPhoto := &TPhoto{Content: "content1", Name: "name1"}
_, err := engine.Insert(tPhoto)
if err != nil {
log.Println(err)
return
}
// 插入多條數據
tPhotos := []*TPhoto{
{Content: "content2", Name: "name2"},
{Content: "content3", Name: "name3"},
{Content: "content4", Name: "name4"},
{Content: "content5", Name: "name5"},
}
_, err = engine.Insert(&tPhotos)
if err != nil {
log.Println(err)
}
}
// insertDataSQL 插入數據庫,使用SQL方式
func insertDataSQL() {
// 這樣不會自動生成 插入時間和修改時間
SQL := "insert into t_photo (content,name) values($1,$2)"
_, err := engine.Exec(SQL, "content7", "name7")
if err != nil {
log.Println(err)
return
}
}
// selectData 查詢數據
func selectData() {
/*
Get 查詢一條信息 參數不是map(json格式) 也不是數組
Find 查詢很多條數據 參數是map(json格式) 或者是 數據
*/
// 查詢第一條數據 select * from 表 limit 1
tPhoto := &TPhoto{}
isHas, err := engine.Get(tPhoto)
if err != nil {
log.Println(err)
return
}
log.Println(isHas)
log.Println(tPhoto)
// 毫無差別的查詢 select * from 表
tPhotos := make([]TPhoto, 0)
err = engine.Find(&tPhotos)
if err != nil {
log.Println(err)
return
}
log.Println(tPhotos)
// 按條件查找 獲取任一條數據 就是根據結構體的名字和表的名字相對應了 select * from t_photo where content='content' and name='name',理解起來就是跟sql中條件的表述一樣
tPhotos1 := make([]TPhoto, 0)
err = engine.Where("content = ?", "content1").And("name =?", "name1").Find(&tPhotos1)
if err != nil {
log.Println(err)
return
}
log.Println(tPhotos1)
// 指定查詢的數據
tPhtot1 := &TPhoto{}
isHas, err = engine.Select("id,content,name").Where("id = ?", 1).Get(tPhtot1)
if err != nil {
log.Println(err)
return
}
if isHas {
log.Println(tPhtot1)
}
}
// count 統計
func count() {
tPhtot1 := &TPhoto{}
num,err := engine.Where("id = ?", 1).Count(tPhtot1)
if err!=nil{
log.Println(err)
return
}
log.Println(num)
}
// updateData 修改數據
func updateData(){
// 原來是樂觀鎖帶來的小坑,因為使用version標記在修改的時候,update的內容必須包含version
tPhtot1 := &TPhoto{Content:"content12",Name: "name12",Version: 1}
affect,err := engine.Where("id = ?",1).Cols("content,name").Update(tPhtot1)
if err!=nil{
log.Println(err)
return
}
log.Println("affect:",affect)
tPhotos := make([]TPhoto,0)
err = engine.Where("id = ?",1).Find(&tPhotos)
if err!=nil{
log.Println(err)
return
}
log.Println(tPhotos)
}
func main() {
log.Println("學習log")
// 顯示所有的表
// ShowAllTables()
// createTableSQL()
// createTable()
// insertData()
// insertDataSQL()
// selectData()
// count()
updateData()
}
注意:當在創建表的對象中有version標記的時候,即是有樂觀鎖的時候,在update的時候,需要帶上version的內容