热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

xorm-Update,乐观锁,更新时间updated,NoAutoTime()

更新数据使用Update方法Update方法的第一个参数为需要更新的内容,可以为一个结构体指针或者一个Map[string]interface{}类型。当传入的为结构体指
  • 更新数据使用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
    */
    
    }

推荐阅读
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • Spring特性实现接口多类的动态调用详解
    本文详细介绍了如何使用Spring特性实现接口多类的动态调用。通过对Spring IoC容器的基础类BeanFactory和ApplicationContext的介绍,以及getBeansOfType方法的应用,解决了在实际工作中遇到的接口及多个实现类的问题。同时,文章还提到了SPI使用的不便之处,并介绍了借助ApplicationContext实现需求的方法。阅读本文,你将了解到Spring特性的实现原理和实际应用方式。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了OC学习笔记中的@property和@synthesize,包括属性的定义和合成的使用方法。通过示例代码详细讲解了@property和@synthesize的作用和用法。 ... [详细]
  • 本文介绍了如何在给定的有序字符序列中插入新字符,并保持序列的有序性。通过示例代码演示了插入过程,以及插入后的字符序列。 ... [详细]
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • C# 7.0 新特性:基于Tuple的“多”返回值方法
    本文介绍了C# 7.0中基于Tuple的“多”返回值方法的使用。通过对C# 6.0及更早版本的做法进行回顾,提出了问题:如何使一个方法可返回多个返回值。然后详细介绍了C# 7.0中使用Tuple的写法,并给出了示例代码。最后,总结了该新特性的优点。 ... [详细]
  • sklearn数据集库中的常用数据集类型介绍
    本文介绍了sklearn数据集库中常用的数据集类型,包括玩具数据集和样本生成器。其中详细介绍了波士顿房价数据集,包含了波士顿506处房屋的13种不同特征以及房屋价格,适用于回归任务。 ... [详细]
  • 关键词:Golang, Cookie, 跟踪位置, net/http/cookiejar, package main, golang.org/x/net/publicsuffix, io/ioutil, log, net/http, net/http/cookiejar ... [详细]
  • 个人学习使用:谨慎参考1Client类importcom.thoughtworks.gauge.Step;importcom.thoughtworks.gauge.T ... [详细]
  • Java学习笔记之面向对象编程(OOP)
    本文介绍了Java学习笔记中的面向对象编程(OOP)内容,包括OOP的三大特性(封装、继承、多态)和五大原则(单一职责原则、开放封闭原则、里式替换原则、依赖倒置原则)。通过学习OOP,可以提高代码复用性、拓展性和安全性。 ... [详细]
author-avatar
手机用户2502934541
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有