IT人生

  • 首页
  • 归档
  • kafka
  • Java
  • Spring
  • Golang
  • SQL
  • Spark
  • ElasticSearch
  • 关于

  • 搜索
Phoenix HBase Kudu ElasticSearch Spring 数据结构 操作系统 Kettle Azkaban Sqoop Hive Yarn Redis Mybatis Impala Cloudera 大数据 HDFS mycat shell Linux 架构 并发 mysql sql golang java 工具 spark kafka 人生

golang系列(四)在golang中使用gorm

发表于 2019-03-14 | 分类于 golang | 0 | 阅读次数 1568
  1. golang系列(一)在Beego中存取Redis
  2. golang系列(二)基于Redis的分布式锁
  3. golang系列(三)在golang中使用kafka
  4. golang系列(四)在golang中使用gorm
  5. golang系列(五)常见的陷阱和错误

gorm官网已经有了很详细的介绍了,本文总结一些在平时开发中gorm官网所没有提到的问题,GORM 中文文档

1. gorm框架支持mysql json类型

mysql在5.7版本中已经开始支持json数据类型,但是目前gorm还不支持json类型,如下建表语句,定义query_param为json类型,

CREATE TABLE `report` (
  `id` bigint(20) NOT NULL,
  `query_param` json NOT NULL,
  `create_by` varchar(50) DEFAULT NULL COMMENT '创建人',
  `create_date` timestamp NULL DEFAULT NULL COMMENT '创建时间',
  `update_by` varchar(50) DEFAULT NULL COMMENT '修改人',
  `update_date` timestamp NULL DEFAULT NULL COMMENT '修改时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `id_UNIQUE` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

解决办法是自定义一个JSON 的type

package models

import (
    "bytes"
    "errors"
    "database/sql/driver"
)
type JSON []byte
func (j JSON) Value() (driver.Value, error) {
    if j.IsNull() {
        return nil, nil
    }
    return string(j), nil
}
func (j *JSON) Scan(value interface{}) error {
    if value == nil {
        *j = nil
        return nil
    }
    s, ok := value.([]byte)
    if !ok {
        errors.New("Invalid Scan Source")
    }
    *j = append((*j)[0:0], s...)
    return nil
}
func (m JSON) MarshalJSON() ([]byte, error) {
    if m == nil {
        return []byte("null"), nil
    }
    return m, nil
}
func (m *JSON) UnmarshalJSON(data []byte) error {
    if m == nil {
        return errors.New("null point exception")
    }
    *m = append((*m)[0:0], data...)
    return nil
}
func (j JSON) IsNull() bool {
    return len(j) == 0 || string(j) == "null"
}
func (j JSON) Equals(j1 JSON) bool {
    return bytes.Equal([]byte(j), []byte(j1))
}

用法是在定义model的时候定义为:“QueryParam JSON”

type Report struct {
    ID            int64        `json:"id"`
    QueryParam  JSON      `json:"queryParam"`
    CreateBy     string         `json:"createBy"`
    CreateDate     time.Time   `json:"createDate"`
    UpdateBy     string         `json:"updateBy"`
    UpdateDate     time.Time   `json:"updateDate"`
}

2. gorm完成表migrate并定义数据库引擎,表comment和列信息

//定义struct
type RcRegisterHisModel struct {
	ID       		int64 		`gorm:"column:id; type:bigint(20); not null; primary_key; comment:'主键ID';  "`
	CreateTime 		time.Time   `gorm:"column:create_time; type:timestamp; not null; default:current_timestamp; comment:'创建时间'"`
	AppId 			string		`gorm:"column:app_id; type:varchar(10); not null; comment:'设备号';"`
	AccountId 		string		`gorm:"column:account_id; type:varchar(10); comment:'用户ID';"`
	OsType	 		string		`gorm:"column:os_type; type:varchar(10); not null; comment:'系统类型';"`
	DeviceId 		string		`gorm:"column:device_id; type:varchar(50); not null; comment:'设备ID';"`
	PartitionKey	int			`gorm:"column:partition_key; type:int(8); not null; default:0; comment:'分区键'; primary_key; "`
}


func init()  {
	database.GetDB().
		Set("gorm:table_options", "ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='设备注册历史';").
		AutoMigrate(&RcRegisterHisModel{})
}

3. 自定义gorm初始化的表名称

func (RcRegisterHisModel) TableName() string {
	return "rc_register_his"
}

3.gorm定义分区表

修改2中的init方法,增加下面的创建分区键

func init()  {
	database.GetDB().
		Set("gorm:table_options", "ENGINE=InnoDB  DEFAULT CHARSET=utf8 COMMENT='设备注册历史';").
		AutoMigrate(&RcRegisterHisModel{})

	//创建分区键
	database.GetDB().Model(&RcRegisterHisModel{}).Exec("ALTER TABLE `rc_register_his` PARTITION BY RANGE(partition_key) PARTITIONS 1( PARTITION part0 VALUES LESS THAN (20191115)) ;");
}

4.回调BeforeCreate和BeforeUpdate

BeforeCreate和BeforeUpdate可以保证,在创建创建或者更新前对必要的字段,如下的:id,create_time,udpate设置值。这样就不用在每次创建或者更新的时候赋值

func (model *RcMobileModel)BeforeCreate (scope *gorm.Scope) error {
	id,err := snowflake.NewSnowFlake().Generate()
	if err != nil{
		beego.Error("snowflake get id error",err)
		return err
	}
	currentTime := time.Now()
	scope.SetColumn("Id", id )
	scope.SetColumn("CreateTime",currentTime)
	scope.SetColumn("UpdateTime",currentTime)
	return nil
}

func (model *RcMobileModel)BeforeUpdate (scope *gorm.Scope) error {
	currentTime := time.Now()
	scope.SetColumn("UpdateTime",currentTime)
	return nil
}
  • 本文作者: Randy
  • 本文链接: http://www.itrensheng.com/archives/golang_gorm_implement
  • 版权声明: 本博客所有文章除特别声明外,均采用CC BY-NC-SA 3.0 许可协议。转载请注明出处!
# Phoenix # HBase # Kudu # ElasticSearch # Spring # 数据结构 # 操作系统 # Kettle # Azkaban # Sqoop # Hive # Yarn # Redis # Mybatis # Impala # Cloudera # 大数据 # HDFS # mycat # shell # Linux # 架构 # 并发 # mysql # sql # golang # java # 工具 # spark # kafka # 人生
golang系列(三)在golang中使用kafka
golang系列(五)常见的陷阱和错误
  • 文章目录
  • 站点概览
Randy

Randy

技术可以暂时落后,但任何时候都要有上进的信念

80 日志
27 分类
31 标签
RSS
Github E-mail
Creative Commons
© 2021 备案号:沪ICP备19020689号-1
Randy的个人网站