• 更新数据使用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. 移动端ios针对input虚拟键盘挡住的问题

    写移动端的时候发现input的虚拟键盘对Ios的手机不是很友好 我的是苹果6 点击的时候经常会挡住input框 针对这个问题找了很多发现都没效果 最后发现用下面这段js就可以解决了 $("i ...

  2. jquery ajax一个坑爹的问题

    问题描述: jquery ajax dataType为json时,如果json数据不严格,不进入success方法,控制台也不会报错. data.json {"result":&q ...

  3. vue 进入页面与离开页面触发事件

    1.切换进入当前路由之前的钩子函数 beforeRouteEnter <script> export default { beforeRouteEnter(to, form, next) ...

  4. OpenFOAM——具有压差的平行平板间流动(泊肃叶流动)

    本算例翻译整理自:http://the-foam-house5.webnode.es/products/chapter-1-plane-parallel-plates-case/ 这个算例中两平板间没 ...

  5. edusoho上传视频弹出abort之解决方案

    错误描述:edusoho上传如avi.mp4等容量大的图片(如100m以上或500m等)弹出abort提示框 原因:是因为web服务器apache默认上传文件有限制导致的 解决办法如下: (1)首先修 ...

  6. #C++初学记录(set进阶#acm cf 190802 B. Subsegments)

    B. Subsegments#set进阶 Programmer Sasha has recently begun to study data structures. His coach Stas to ...

  7. Linux Shell:根据指定的文件列表 或 map配置,进行文件位置转移

    读取配置文件,进行文件位置转移 在whenb.csv中指定了需要从/home/root/cf/下移除到/home/root/cf_wh/下文件列表,whenb.csv中包含记录如下: enb- enb ...

  8. 005 vue路由

    一:元素的获取 1.ref元素获取 可以通过ref获取DOm,也可以获取组件的引用 <!DOCTYPE html> <html lang="en"> < ...

  9. C#发起Http请求,调用接口

    //方法1. Post 异步请求,普通的异步请求,传输普通的字符串等,对于有html代码的字段值的传输支持不好,如果需要传输html,二进制等数据的传输,请使用下面第二个方法,即使用UploadDat ...

  10. windows10 dos窗口输出卡住

    https://blog.csdn.net/u013866090/article/details/82790864 原本每间隔一秒就会输出一次数据,但是当鼠标点击窗口的其他区域后输出就停止了,在点击键 ...