• 更新数据使用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. 异常过滤器的好坏(CLR)

    为什么有些语言支持它们而另一些不支持呢?把它们加到我的新语言里是个好主意吗?我应该什么时候使用过滤器和catch/rethrow?就像很多事情一样,异常过滤器有好的一面也有坏的一面… 什么是异常过滤器 ...

  2. 从TEB到PEB再到SEH(二)

    什么是SEH? SEH( Structured Exception Handling , 结构化异常处理 ) 结构化异常处理(SEH)是Windows操作系统提供的强大异常处理功能.而Visual C ...

  3. 使用go-mysql-server 开发自己的mysql server

    go-mysql-server是一个golang 的mysql server 协议实现包,使用此工具我们可以用来做好多方便的东西 基于mysql 协议暴露自己的本地文件为sql 查询 基于mysql ...

  4. P5110 【块速递推】

    太菜了,不会生成函数,于是用特征方程来写的这道题 首先我们知道,形如\(a_n=A*a_{n-1}+B*a_{n-2}\)的特征方程为\(x^2=A*x+B\) 于是此题的递推式就是:\(x^2=23 ...

  5. [BZOJ1191]超级英雄Hero

    Description 现在电视台有一种节目叫做超级英雄,大概的流程就是每位选手到台上回答主持人的几个问题,然后根据回答问题的 多少获得不同数目的奖品或奖金.主持人问题准备了若干道题目,只有当选手正确 ...

  6. MSSQL手工注入 报错注入方法

    例子:www.kfgtfcj.gov.cn/lzygg/Zixun_show.aspx?id=1[1]首先爆版本:http://www.kfgtfcj.gov.cn/lzygg/Zixun_show. ...

  7. 微信小程序 base64格式图片的显示及保存

    当我们拿到如下base64格式的图片(如下图)时, base64格式的图片数据: 如何显示 ? 使用image标签,src属性添加data:image/png;base64, (注意:若imgData ...

  8. 2019 SDN第三次上机作业

    作业要求: 利用Mininet仿真平台构建给定的网络拓扑,配置主机h1和h2的IP地址(h1:10.0.0.1,h2:10.0.0.2),测试两台主机之间的网络连通性: 利用Wireshark工具,捕 ...

  9. 2015-2016-2《Java程序设计》团队博客2

     简易画图板介绍 一.功能结构图 二.主类设计 1.总体设计:在设计简易画图板时,根据程序功能的分类,包含了十二个文件,包括SimpleDraw.java,MenuContainer.java,Dra ...

  10. 可伸缩性架构常用技术——之数据切分 Data Sharding/Partition

    1. 简介 本来想写一篇可伸缩性架构方面的文章,发现东西太多了,久久未能下笔,这里首先把大家最关注的数据切分(Partition/Sharding)方面的内容先写完,给大家参考. 我们知道,为了应对不 ...