xorm - Update,樂觀鎖,更新時間updated,NoAutoTime()


  • 更新數據使用Update方法

  • Update方法的第一個參數為需要更新的內容,可以為一個結構體指針或者一個Map[string]interface{}類型。

    • 當傳入的為結構體指針時,只有非nil和非0的field才會被作為更新的字段,也就是說結構體至少要有一個字段被賦予非0值
    • 當傳入的為Map類型時,key為數據庫Column的名字,value為要更新的內容。
  • Update方法將返回兩個參數:

    • 第一個為更新的記錄數,需要注意的是 SQLITE 數據庫返回的是根據更新條件查詢的記錄數而不是真正受更新的記錄數。
  • 如果需要更新一個值為0,有兩種選擇:

    • 通過添加Cols函數指定需要更新結構體中的哪些值,未指定的將不更新,指定了的即使為0也會更新。
    • 通過傳入map[string]interface{}來進行更新,但這時需要額外指定更新到哪個表,因為通過map是無法自動檢測更新哪個表的。
package main

import (
	"fmt"
	_ "github.com/go-sql-driver/mysql"
	"github.com/go-xorm/xorm"
	"log"
	"time"
)

var engine *xorm.Engine

type User struct {
	Name      string    `xorm:"varchar(25) 'name'"`
	Id        int       `xorm:"pk 'id' autoincr"`
	Money     int       `xorm:" 'money' "`
	Age       int       `xorm:"age"`
	CreatedAt time.Time `xorm:"created"`
}

func main() {
	var err error
	engine, err = xorm.NewEngine("mysql", "root:123456@/test")
	if err != nil {
		log.Fatal(err)
		return
	}
	//創建表和插入數據
/*	err = engine.CreateTables(User{})
	if err != nil {
		log.Fatal(err)
		return
	}

	u := make([]User, 3)
	u[0].Name = "u0"
	u[0].Money = 1
	u[0].Age = 1
	u[1].Name = "u1"
	u[1].Money = 2
	u[1].Age = 1
	u[2].Name = "u2"
	u[2].Money = 3
	u[2].Age = 1

	_, err = engine.Insert(u)
	if err != nil {
		log.Fatal(err)
		return
	}*/


	u1 := new(User)
	u1.Money = 2
	affected, err := engine.Id(1).Update(u1)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("第一個參數為結構體指針,結構體中更新的數據不是0值時,受影響的行數:", affected)


	u2 := new(User)
	u2.Money = 0
	affected, err = engine.Id(1).Cols("money").Update(u2)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("第一個參數為結構體指針,結構體中更新的數據是0值,Cols函數指定需要更新結構體中的哪些值時,受影響的行數:", affected)

	affected, err = engine.Table(new(User)).Id(2).Update(map[string]interface{}{"age":0})
	fmt.Println("第一個參數為map,0值,受影響的行數:", affected)

  u3 := new(User)
	u3.Money = 0
	affected, err = engine.Id(1).Update(u3)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("第一個參數為結構體指針,結構體中更新的數據是0值時,受影響的行數:", affected)


/*
    如果傳入的數據和數據庫原有的數據相同時上面第一個方法受影響的行數就是0行,不同時上面第一個方法受影響的行數就是1行,輸出:
		第一個參數為結構體指針,結構體中更新的數據不是0值時,受影響的行數: 1
		第一個參數為結構體指針,結構體中更新的數據是0值,Cols函數指定需要更新結構體中的哪些值時,受影響的行數: 1
    第一個參數為map,0值,受影響的行數: 1
		2019/05/28 11:51:35 No content found to be updated
*/

}
  • 樂觀鎖/更新時間update/不自動更新時間NoAutoTime()

    package main
    
    import (
    	"fmt"
    	_ "github.com/go-sql-driver/mysql"
    	"github.com/go-xorm/xorm"
    	"log"
    	"time"
    )
    
    var engine *xorm.Engine
    
    type User struct {
    	Name      string    `xorm:"varchar(25) 'name'"`
    	Id        int       `xorm:"pk 'id' autoincr"`
    	Version   int       `xorm:"version"`
    	UpdatedAt time.Time `xorm:"updated"`
    }
    
    func main() {
    	var err error
    	engine, err = xorm.NewEngine("mysql", "root:123456@/test")
    	if err != nil {
    		log.Fatal(err)
    		return
    	}
    	//創建表和插入數據
    /*	err = engine.CreateTables(User{})
    	if err != nil {
    		log.Fatal(err)
    		return
    	}
    
    	u := make([]User, 3)
    	u[0].Name = "u0"
    	u[1].Name = "u1"
    	u[2].Name = "u2"
    
    	_, err = engine.Insert(u)
    	if err != nil {
    		log.Fatal(err)
    		return
    	}*/
    
    	/*
    		要使用樂觀鎖,需要使用version標記
    		在Insert時,version標記的字段將會被設置為1,在Update時,Update的內容必須包含version原來的值。
    	*/
    
    		var user User
    		has, err := engine.Id(1).Get(&user)
    		if err != nil {
    			log.Fatal(err)
    			return
    		}
    		if has {
    			fmt.Println("樂觀鎖,初始的userName:", user.Name, "  初始的version:", user.Version, "更新時間:", user.UpdatedAt)
    		}
    
    		user.Name = "version2Name"
    		affected, err := engine.Id(1).Update(&user)
    		if err != nil {
    			log.Fatal(err)
    			return
    		}
    		fmt.Println("樂觀鎖,改變了的數據庫記錄數:", affected, "  改變后的userName:", user.Name,
    			"  改變后的version:", user.Version, "更新時間:", user.UpdatedAt)
    
    		/*
    	  更新時間Updated可以讓您在記錄插入或每次記錄更新時自動更新數據庫中的標記字段為當前時間,
    		需要在xorm標記中使用updated標記,對應的字段可以為time.Time或者自定義的time.Time或者int,int64等int類型。
    		在Insert(), InsertOne(), Update()方法被調用時,updated標記的字段將會被自動更新為當前時間
    		*/
    
    		var user1 User
    		has, err = engine.Id(2).Get(&user1)
    		if err != nil {
    			log.Fatal(err)
    			return
    		}
    		if has {
    			fmt.Println("更新時間Updated,初始的userName:", user1.Name, "  初始的version:", user1.Version, "更新時間:", user1.UpdatedAt)
    		}
    		affected, err = engine.Id(2).Update(&user1)
    		if err != nil {
    			log.Fatal(err)
    			return
    		}
    		fmt.Println("更新時間Updated,改變了的數據庫記錄數:", affected, "  改變后的userName:", user1.Name,
    			"  改變后的version:", user1.Version, "更新時間:", user1.UpdatedAt)
    
    
    	/*	如果你希望臨時不自動插入時間,則可以組合NoAutoTime()方法:
    		engine.NoAutoTime().Insert(&user)
    		這個在從一張表拷貝字段到另一張表時比較有用。
    	*/
    
    		var user2 User
    		has, err = engine.Id(3).Get(&user2)
    		if err != nil {
    			log.Fatal(err)
    			return
    		}
    		if has {
    			fmt.Println("臨時不自動插入時間,初始的userName:", user2.Name, "  初始的version:", user2.Version, "更新時間:", user2.UpdatedAt)
    		}
    		affected, err = engine.Id(3).NoAutoTime().Update(&user2)
    		if err != nil {
    			log.Fatal(err)
    			return
    		}
    		fmt.Println("臨時不自動插入時間,改變了的數據庫記錄數:", affected, "  改變后的userName:", user2.Name,
    			"  改變后的version:", user2.Version, "更新時間:", user2.UpdatedAt)
    
    
    /*輸出:
    	樂觀鎖,初始的userName: version2Name   初始的version: 2 更新時間: 2019-05-28 14:41:24 +0800 CST
    	樂觀鎖,改變了的數據庫記錄數: 1   改變后的userName: version2Name   改變后的version: 3 更新時間: 2019-05-28 14:44:02.386965 +0800 CST
    	更新時間Updated,初始的userName: u1   初始的version: 2 更新時間: 2019-05-28 14:41:24 +0800 CST
    	更新時間Updated,改變了的數據庫記錄數: 1   改變后的userName: u1   改變后的version: 3 更新時間: 2019-05-28 14:44:02.395314 +0800 CST
    	臨時不自動插入時間,初始的userName: u2   初始的version: 2 更新時間: 2019-05-28 14:41:24 +0800 CST
    	臨時不自動插入時間,改變了的數據庫記錄數: 1   改變后的userName: u2   改變后的version: 3 更新時間: 2019-05-28 14:41:24 +0800 CST
    */
    
    }
    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM