zoukankan      html  css  js  c++  java
  • gorm 更新数据时,0值会被忽略

    原文: https://www.tizi365.com/archives/22.html

    --------------------------------------------------------

    一、前言

    为方便描述教程例子,这里给出mysql表结构定义和golang结构体定义。

    下面是教程用到的foods表结构定义:

    CREATE TABLE `foods` (
      `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '商品id',
      `title` varchar(100) NOT NULL COMMENT '商品名',
      `price` float DEFAULT '0' COMMENT '商品价格',
      `stock` int(11) DEFAULT '0' COMMENT '商品库存',
      `type` int(11) DEFAULT '0' COMMENT '商品类型',
      `create_time` datetime NOT NULL COMMENT '商品创建时间',
      PRIMARY KEY (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    下面是foods表对应的golang结构体类型

    //商品
    type Food struct {
    	Id         int
    	Title      string
    	Price      float32
    	Stock      int
    	Type       int
    	//mysql datetime, date类型字段,可以和golang time.Time类型绑定, 详细说明请参考:gorm连接数据库章节。
    	CreateTime time.Time
    }
    
    //为Food绑定表名
    func (v Food) TableName() string {
    	return "foods"
    }

    二、gorm更新记录常用方法

    1. Save

    用于保存模型变量的值。

    提示: 相当于根据主键id,更新所有模型字段值。

    food := Food{}
    //先查询一条记录, 保存在模型变量food
    //等价于: SELECT * FROM `foods`  WHERE (id = '2') LIMIT 1
    db.Where("id = ?", 2).Take(&food)
    
    //修改food模型的值
    food.Price = 100
    
    //等价于: UPDATE `foods` SET `title` = '可乐', `type` = '0', `price` = '100', `stock` = '26', `create_time` = '2018-11-06 11:12:04'  WHERE `foods`.`id` = '2'
    db.Save(&food)

    2. Update

    更新单个字段值

    //例子1:
    //更新food模型对应的表记录
    //等价于: UPDATE `foods` SET `price` = '25'  WHERE `foods`.`id` = '2'
    db.Model(&food).Update("price", 25)
    //通过food模型的主键id的值作为where条件,更新price字段值。
    
    
    //例子2:
    //上面的例子只是更新一条记录,如果我们要更全部记录怎么办?
    //等价于: UPDATE `foods` SET `price` = '25'
    db.Model(Food{}).Update("price", 25)
    //注意这里的Model参数,使用的是Food{},新生成一个空白的模型变量,没有绑定任何记录。
    //因为Food{}的id为空,gorm库就不会以id作为条件,where语句就是空的
    
    //例子3:
    //根据自定义条件更新记录,而不是根据主键id
    //等价于: UPDATE `foods` SET `price` = '25'  WHERE (create_time > '2018-11-06 20:00:00') 
    db.Model(Food{}).Where("create_time > ?", "2018-11-06 20:00:00").Update("price", 25)

    3. Updates

    更新多个字段值

    //例子1:
    //通过结构体变量设置更新字段
    updataFood := Food{
    		Price:120,
    		Title:"柠檬雪碧",
    	}
    
    //根据food模型更新数据库记录
    //等价于: UPDATE `foods` SET `price` = '120', `title` = '柠檬雪碧'  WHERE `foods`.`id` = '2'
    //Updates会忽略掉updataFood结构体变量的零值字段, 所以生成的sql语句只有price和title字段。
    db.Model(&food).Updates(&updataFood)
    
    //例子2:
    //根据自定义条件更新记录,而不是根据模型id
    updataFood := Food{
    		Stock:120,
    		Title:"柠檬雪碧",
    	}
    	
    //设置Where条件,Model参数绑定一个空的模型变量
    //等价于: UPDATE `foods` SET `stock` = '120', `title` = '柠檬雪碧'  WHERE (price > '10') 
    db.Model(Food{}).Where("price > ?", 10).Updates(&updataFood)
    
    //例子3:
    //如果想更新所有字段值,包括零值,就是不想忽略掉空值字段怎么办?
    //使用map类型,替代上面的结构体变量
    
    //定义map类型,key为字符串,value为interface{}类型,方便保存任意值
    data := make(map[string]interface{})
    data["stock"] = 0 //零值字段
    data["price"] = 35
    
    //等价于: UPDATE `foods` SET `price` = '35', `stock` = '0'  WHERE (id = '2')
    db.Model(Food{}).Where("id = ?", 2).Updates(data)

    提示: 通过结构体变量更新字段值, gorm库会忽略零值字段。就是字段值等于0, nil, "", false这些值会被忽略掉,不会更新。如果想更新零值,可以使用map类型替代结构体。

    4. 更新表达式

    UPDATE foods SET stock = stock + 1 WHERE id = '2'
    这样的带计算表达式的更新语句gorm怎么写?

    gorm提供了Expr函数用于设置表达式

    //等价于: UPDATE `foods` SET `stock` = stock + 1  WHERE `foods`.`id` = '2'
    db.Model(&food).Update("stock", gorm.Expr("stock + 1"))
  • 相关阅读:
    saolei
    Hibernate中表与表之间的关联多对多,级联保存,级联删除
    Hibernate中表与表之间的关联一对多,级联保存和级联删除
    Hibernate中的Query对象查询所有记录
    Hibernate缓存
    hibernate简单实现连接数据库,并实现数据的操作
    Navicat注册码
    用jdbc连接数据库并简单执行SQL语句
    JDBC中的DriverManager.getConnection(url)中的参数url
    spring进行事务管理
  • 原文地址:https://www.cnblogs.com/oxspirt/p/11240527.html
Copyright © 2011-2022 走看看