• 更新数据使用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
    */ }

xorm - Update,乐观锁,更新时间updated,NoAutoTime()的更多相关文章

  1. MP(MyBatis-Plus)实现乐观锁更新功能

    实现步骤 step1:添加乐观锁拦截器 MP的其他拦截器功能可以参考官网 @Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { ...

  2. Elasticsearch由浅入深(五)_version乐观锁、external version乐观锁、partial update、groovy脚本实现partial update

    基于_version进行乐观锁并发控制 先构造一条数据出来 PUT /test_index/test_type/ { "test_field": "test test&q ...

  3. “更新时间”字段的:ON UPDATE CURRENT_TIMESTAMP 含义

    "更新时间"字段的:ON UPDATE CURRENT_TIMESTAMP 含义: 表示在数据库数据有更新的时候UPDATE_TIME的时间会自动更新(如果数据库数据值没有变化的话 ...

  4. Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--悲观锁( ...

  5. C# 乐观锁、悲观锁、共享锁、排它锁、互斥锁

    悲观锁(Pessimistic Lock), 顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁.传统的关系型数据 ...

  6. MySQL 乐观锁与悲观锁

    悲观锁 悲观锁(Pessimistic Lock),顾名思义,就是很悲观,每次去拿数据的时候都认为别人会修改,所以每次在拿数据的时候都会上锁,这样别人想拿这个数据就会block直到它拿到锁. 悲观锁: ...

  7. 浅谈Mysql共享锁、排他锁、悲观锁、乐观锁及其使用场景

    浅谈Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景   Mysql共享锁.排他锁.悲观锁.乐观锁及其使用场景 一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁 ...

  8. Mysql共享锁、排他锁、悲观锁、乐观锁

    一.相关名词 |--表级锁(锁定整个表) |--页级锁(锁定一页) |--行级锁(锁定一行) |--共享锁(S锁,MyISAM 叫做读锁) |--排他锁(X锁,MyISAM 叫做写锁) |--间隙锁( ...

  9. MySQL乐观锁为什么可以防止并发

    问题引入 本文介绍的是最常用的也是mysql默认的innoDB引擎 Read committed隔离级别下事物的并发.这种情况下的事物特点是 读:在一个事物里面的select语句 不会受到其他事物(不 ...

随机推荐

  1. BZOJ 5507: [gzoi2019]旧词 LCT

    和之前那个 [LNOI]LCA 几乎是同一道题,就是用动态树来维护查分就行. code: #include <bits/stdc++.h> using namespace std; #de ...

  2. 2019.12.06 java基础

    JRE:运行环境(包含JVM(Java Virtual Machine)- Java虚拟机和核心类库) JDK: JAVA语言的软件开发工具包(Java Development Kit) Dos命令行 ...

  3. windbg在加载模块时下断点

    假设我们希望在加载特定的dll时中断调试器,例如,我想启用一些SOS命令,而clr还没有加载,当您遇到程序中过早发生的异常,并且您不能依赖手动尝试在正确的时间中断时,这尤其有用.例如,在将调试器附加到 ...

  4. graphql-hooks hooks first 的graphql 客户端

    graphql-hooks 是一个hooks first 的graphql 客户端,支持一一些特性 首类hooks api 比较小(5.3Kb) gzip 1.8 kb 完整支持ssr (通过grap ...

  5. 开发框架Express

    一.使用原因 由于nodejs原生的http核心模块在某些方面不足以应对开发需求,所以就需要使用框架来加快开发效率,让代码更高度统一.在nodejs中有许多web开发框架,以下介绍Express的使用 ...

  6. Theano入门笔记1:Theano中的Graph Structure

    译自:http://deeplearning.net/software/theano/extending/graphstructures.html#graphstructures 理解Theano计算 ...

  7. static final与final修饰的常量有什么不同

    最近重头开始看基础的书,对一些基础的概念又有了一些新的理解,特此记录一下 static final修饰的常量: 静态常量(static修饰的全部为静态的),编译器常量,编译时就确定其值(java代码经 ...

  8. 【POJ1573】Robot Motion

    题目传送门 本题知识点:模拟 本题的题意也很简单. 给出一个矩阵,矩阵里面有着东南西北(上下左右)的指示,当机器人走到上面时则会按照指示前进.机器人每次都从最上面一行的某一列进入. 需要判断的是机器人 ...

  9. lintcode-1174.下一个更大的元素 III

    题目描述: 1174. 下一个更大的元素 III 给定一个32位整数n,用同样的数字组成新的32位整数,使得它要比n大,返回最小的这样的数.如果不存在这样的整数,返回-1. 算法思路: 首先将这个数转 ...

  10. IDEA中设置自动build-改动代码,不用重启工程,刷新页面即可

    1.CTRL + SHIFT + A --> 查找Registry --> 找到并勾选compiler.automake.allow.when.app.running   2. FILE ...