专栏首页coder修行路ent orm笔记2---schema使用(下)

ent orm笔记2---schema使用(下)

Indexes 索引

在前两篇的文章中,其实对于索引也有一些使用, 这里来详细看一下关于索引的使用

Indexes方法可以在一个或者多个字段上设置索引,以提高数据检索的速度或者定义数据的唯一性

在下面这个例子中,对user表的field1field2 字段设置了联合索引;对first_namelast_name设置了联合唯一索引; 对field3 设置了唯一索引。

这里需要注意对于单独的字段设置唯一索引,在Fields中定义字段的时候通过Unique方法即可

package schema

import (
	"github.com/facebook/ent"
	"github.com/facebook/ent/schema/field"
	"github.com/facebook/ent/schema/index"
)

// User holds the schema definition for the User entity.
type User struct {
	ent.Schema
}

// Fields of the User.
func (User) Fields() []ent.Field {
	return []ent.Field{
		field.String("field1"),
		field.String("field2"),
		field.String("field3").Unique(),
		field.String("first_name"),
		field.String("last_name"),
	}
}

// Edges of the User.
func (User) Edges() []ent.Edge {
	return nil
}

func Indexes() []ent.Index {
	return []ent.Index{
		// non-unique index.
		index.Fields("field1", "field2"),
		// unique index
		index.Fields("first_name", "last_name").Unique(),
	}
}

查看一下生成的表的信息:

CREATE TABLE `users` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `field1` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `field2` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `field3` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `first_name` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `last_name` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `field3` (`field3`),
  UNIQUE KEY `user_first_name_last_name` (`first_name`,`last_name`),
  KEY `user_field1_field2` (`field1`,`field2`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

Index On Edges

在建立表关系的时候也可以对相应的字段设置索引,主要实在特定关系下设置字段的唯一性

在这个例子中,我们有一个有许多街道的城市,我们希望在每个城市下设置街道名称是唯一的。

ent/schema/city.go

package schema

import (
   "github.com/facebook/ent"
   "github.com/facebook/ent/schema/edge"
   "github.com/facebook/ent/schema/field"
)

// City holds the schema definition for the City entity.
type City struct {
   ent.Schema
}

// Fields of the City.
func (City) Fields() []ent.Field {
   return []ent.Field{
      field.String("name"),
   }
}

// Edges of the City.
func (City) Edges() []ent.Edge {
   return []ent.Edge{
      edge.To("streets", Street.Type),
   }
}

ent/schema/street.go

package schema

import (
   "github.com/facebook/ent"
   "github.com/facebook/ent/schema/edge"
   "github.com/facebook/ent/schema/field"
)

// Street holds the schema definition for the Street entity.
type Street struct {
   ent.Schema
}

// Fields of the Street.
func (Street) Fields() []ent.Field {
   return []ent.Field{
      field.String("name"),
   }
}

// Edges of the Street.
func (Street) Edges() []ent.Edge {
   return []ent.Edge{
      edge.From("city", City.Type).
         Ref("streets").
         Unique(),
   }
}

在上一篇文章中这种用法我们已经见过,我们看一下这样创建的表信息,主要是看streets这个表:

CREATE TABLE `streets` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `city_streets` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `streets_cities_streets` (`city_streets`),
  CONSTRAINT `streets_cities_streets` FOREIGN KEY (`city_streets`) REFERENCES `cities` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

ent/schema/street.go 添加索引的信息后,再次查看streets表的信息,其实这里我们就是通过添加约束,使得一个城市中每个街道的名称是唯一的

func (Street) Indexes() []ent.Index {
   return []ent.Index{
      index.Fields("name").
         Edges("city").
         Unique(),
   }
}
CREATE TABLE `streets` (
  `id` bigint(20) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) COLLATE utf8mb4_bin NOT NULL,
  `city_streets` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  UNIQUE KEY `street_name_city_streets` (`name`,`city_streets`),
  KEY `streets_cities_streets` (`city_streets`),
  CONSTRAINT `streets_cities_streets` FOREIGN KEY (`city_streets`) REFERENCES `cities` (`id`) ON DELETE SET NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin

Config

可以使用Table选项为类型提供自定义表名,如下所示:

package schema

import (
    "github.com/facebook/ent"
    "github.com/facebook/ent/schema/field"
)

type User struct {
    ent.Schema
}

func (User) Config() ent.Config {
    return ent.Config{
        Table: "Users",
    }
}

func (User) Fields() []ent.Field {
    return []ent.Field{
        field.Int("age"),
        field.String("name"),
    }
}

Mixin

Mixin允许您创建可重用的ent.Schema代码。ent.Mixin 接口如下:

Mixin interface {
    // Fields returns a slice of fields to add to the schema.
    Fields() []Field
    // Edges returns a slice of edges to add to the schema.
    Edges() []Edge
    // Indexes returns a slice of indexes to add to the schema.
    Indexes() []Index
    // Hooks returns a slice of hooks to add to the schema.
    // Note that mixin hooks are executed before schema hooks.
    Hooks() []Hook
}

Mixin的一个常见用例是将一些常用的通用字段进行内置,如下:

package schema

import (
    "time"

    "github.com/facebook/ent"
    "github.com/facebook/ent/schema/field"
    "github.com/facebook/ent/schema/mixin"
)

// -------------------------------------------------
// Mixin definition

// TimeMixin implements the ent.Mixin for sharing
// time fields with package schemas.
type TimeMixin struct{
    // We embed the `mixin.Schema` to avoid
    // implementing the rest of the methods.
    mixin.Schema
}

func (TimeMixin) Fields() []ent.Field {
    return []ent.Field{
        field.Time("created_at").
            Immutable().
            Default(time.Now),
        field.Time("updated_at").
            Default(time.Now).
            UpdateDefault(time.Now),
    }
}

// DetailsMixin implements the ent.Mixin for sharing
// entity details fields with package schemas.
type DetailsMixin struct{
    // We embed the `mixin.Schema` to avoid
    // implementing the rest of the methods.
    mixin.Schema
}

func (DetailsMixin) Fields() []ent.Field {
    return []ent.Field{
        field.Int("age").
            Positive(),
        field.String("name").
            NotEmpty(),
    }
}

// -------------------------------------------------
// Schema definition

// User schema mixed-in the TimeMixin and DetailsMixin fields and therefore
// has 5 fields: `created_at`, `updated_at`, `age`, `name` and `nickname`.
type User struct {
    ent.Schema
}

func (User) Mixin() []ent.Mixin {
    return []ent.Mixin{
        TimeMixin{},
        DetailsMixin{},
    }
}

func (User) Fields() []ent.Field {
    return []ent.Field{
        field.String("nickname").
            Unique(),
    }
}

// Pet schema mixed-in the DetailsMixin fields and therefore
// has 3 fields: `age`, `name` and `weight`.
type Pet struct {
    ent.Schema
}

func (Pet) Mixin() []ent.Mixin {
    return []ent.Mixin{
        DetailsMixin{},
    }
}

func (Pet) Fields() []ent.Field {
    return []ent.Field{
        field.Float("weight"),
    }
}

Builtin Mixin

Mixin提供了一些内置的Mixin,可用于将create_time和update_time字段添加到schema中。

为了使用它们,将 mixin.Time mixin 添加到schema,如下所示:

package schema

import (
    "github.com/facebook/ent"
    "github.com/facebook/ent/schema/mixin"
)

type Pet struct {
    ent.Schema
}

func (Pet) Mixin() []ent.Mixin {
    return []ent.Mixin{
        mixin.Time{},
        // Or, mixin.CreateTime only for create_time
        // and mixin.UpdateTime only for update_time.
    }
}

延伸阅读

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • ent orm笔记2---schema使用(上)

    在上一篇关于快速使用ent orm的笔记中,我们再最开始使用entc init User 创建schema,在ent orm 中的schema 其实就是数据库模...

    coders
  • ent orm笔记1---快速尝鲜

    前几天看到消息Facebook孵化的ORM ent转为正式项目,出去好奇,简单体验了一下,使用上自己感觉比GORM好用,于是打算把官方的文档进行整理,也算是学习...

    coders
  • Docker的镜像

    镜像是容器的运行基础,容器是镜像运行后台的形态 镜像的概念 镜像是一个包含程序运行必要依赖环境和代码的只读文件,它采用分层的文件系统,将每一次改变以读写层的形式...

    coders
  • SAP 利润中心维护操作笔记

    利润中心组是在标准层次的基础上对各利润中心进行组合,以便可以从不同维度进行统计分析。

    用户5495712
  • 知乎几条不错的想法

    作者:大狐狸 链接:https://www.zhihu.com/question/36426051/answer/76031743 来源:知乎 著作权归作...

    bear_fish
  • 《贝佐斯的数字帝国》6 模块5 决策机制:既要质量,更要速度

    自推出以来,Prime会员服务成了亚马逊业务增长的重要引擎。截至2018年底,亚马逊的全球会员已超过1亿。亚马逊会员的平均花费是非会员的2.7倍,而且会员业务已...

    yeedomliu
  • nodejs的事件处理机制以及事件环机制

    ES6标准发布后,module成为标准,标准的使用是以export指令导出接口,以import引入模块,但是在我们一贯的node模块中,我们采用的是Common...

    Dream城堡
  • 协议-应用层的协议分类

    1.超文本传输协议HTTP:  这是一种最基本的客户机/服务器的访问协议。浏览器向服务器发送请求,而服务器回应相应的网页。 

    秋日芒草
  • Linux 逻辑卷管理(LVM)使用方法总结

    管理磁盘空间对系统管理员来说是一件重要的日常工作。一旦磁盘空间耗尽就需要进行一系列耗时而又复杂的任务,以提升磁盘分区中可用的磁盘空间。它也需要系统离线才能处理。...

    砸漏
  • 3分钟短文|Laravel命令行调用控制器方法,你会几个?

    有时候为了不重写代码,避免冗余无用重复的代码在程序内到处都是。我们总是想方设法 把写过的逻辑拿过来使用。

    程序员小助手

扫码关注云+社区

领取腾讯云代金券