golang使用gorm+postgres

gorm中文文档

安装gorm和数据库驱动

go get -u gorm.io/gorm
//sqlite驱动
go get -u gorm.io/driver/sqlite
//postgresql驱动
go get -u gorm.io/driver/postgres

链接数据库

var dsn = "host=127.0.0.1 port=5432 user=postgres dbname=SH password=123456"
var Connect *gorm.DB

func init() {
	ConnectionPg()
}

func ConnectionPg() {
	var err error
	Connect, err = gorm.Open(postgres.Open(dsn), &gorm.Config{
		DisableForeignKeyConstraintWhenMigrating: true,
		Logger:                                   logger.Default.LogMode(logger.Info),
	})
	if err != nil {
		fmt.Printf("数据库连接失败----err",err)
	}
}

范围查询:

in

//指定字段的范围查询
db.Where("name IN ?", []string{"jinzhu", "jinzhu 2"}).Find(&users)
// SELECT * FROM users WHERE name IN ('jinzhu','jinzhu 2');
// 主键切片条件
db.Where([]int64{20, 21, 22}).Find(&users)
// SELECT * FROM users WHERE id IN (20, 21, 22);

最值查询

根据时间–最新的记录

 config.DbConnect.Last(&record)

分页查询

Db.Offset((pageNum-1)*pageSize).Limit(pageSize).Find(...)

显示每次执行的sql

	sql := config.DbConnect.ToSQL(func(tx *gorm.DB) *gorm.DB {
		return tx.Model(&record).Updates(record)
	})
	fmt.Println("sql=>",sql)
	//sql=> UPDATE "robot_resets" SET "id"=6,"modified_at"='2022-01-06 14:35:05.655',"finish"='0' WHERE "id" = 6

在postgre中给表定义字符串数组类型的字段

import "github.com/lib/pq"
type GeneralOrder struct {
	gorm.Model
	Type  string
	Key   string
	Param pq.StringArray `gorm:"type:text[]"`//定义字符串类型的字段
	Pid   uint
}

查询该字段中包含某个元素的记录

SELECT * FROM "line" WHERE param @> ARRAY[('4')]::text[]

gorm+golang写法

func (lg *lineGrom) GetRecords(companyKey []string) (error, []GeneralOrder) {
	result := []GeneralOrder{}
	return lg.DB.Debug().Where("param @> ARRAY[(?)]::text[]", companyKey).Find(&result).Error, result
}

在这里插入图片描述

根据指定字段值,查询表中某个字段的值,返回结果映射到数组

从表casbin_rule中查询v1等于空的记录,并只返回v0的值,要求返回的是v0组成的数组

	var parentRoles []string
	global.GVA_DB.Table("casbin_rule").Select("v0").Where("v1 = ? ","1").Find(&parentRoles)


var ages []int64
db.Model(&users).Pluck("age", &ages)

var names []string
db.Model(&User{}).Pluck("name", &names)

db.Table("deleted_users").Pluck("name", &names)

将记录按某字段分组,再同时统计每组中的记录数量

统计type为false的记录,并以line_id分组,统计每个line_id有几个数据

查询到map中似乎只能查询一条记录,并且是字段名为key,对应的值为value

func (ag *abnormityGorm) GetRecordsCountByType(abnormityType bool) (error, []map[string]interface{}) {
	var result []map[string]interface{}
	
	err := global.GVA_DB.Model(&do.AbnormityDo{}).Select("line_id","count(*)").Where("type = ? ",abnormityType).Group("line_id").Find(&result).Error
	return err,result
}

根据时间区间,和endpoint数组,查询各个endpoint在这个时间区间中各自最新的那条数据

// 根据时间区间,和endpoint数组,查询各个endpoint在这个时间区间中各自最新的那条数据
func (emdg *ElectricMeterDataGorm) GetLastRecordByEndpointIdListAndTimeBase(endpointIdList []string, start, end string) (error, []do.ElectricMeterDataDo) {
	var result []do.ElectricMeterDataDo
	err := emdg.DB.Raw(`
    WITH ranked_data AS (
        SELECT 
            *,
            ROW_NUMBER() OVER (PARTITION BY endpoint_id ORDER BY time DESC) AS rn
        FROM electric_meter_data
        WHERE time >= ?::timestamp AND time <= ?::timestamp
        AND endpoint_id IN (?)
    )
    SELECT * FROM ranked_data WHERE rn = 1;
`, start, end, endpointIdList).Scan(&result).Error
	return err, result
}

在这个查询中,我们使用了窗口函数 ROW_NUMBER() 来为每个 endpoint 的数据按时间降序排列,并给每行分配一个行号。然后在外部查询中,我们选择行号为 1 的数据,即每个 endpoint 在指定时间区间的最新数据。

将 :start_time、:end_time 和 :endpoint_ids 替换为实际的时间范围和 endpoint 数组。

WITH语句

WITH语句是SQL中的一种常见语法,也被称为"公共表表达式"(Common Table Expression, CTE)。该语法允许您在SQL查询中创建一个临时的命名结果集,然后在后续的查询中引用这个临时结果集。

在这种场景下,WITH ranked_data AS (…) 创建了一个名为 ranked_data 的临时表(或者更准确地说是临时结果集),其中包含了以下查询所生成的结果。在后续的查询中,您可以直接引用 ranked_data,就像它是一个表一样。

这种方法允许您将复杂的查询分解成更易维护和理解的部分,并且有助于提高查询的可读性和可维护性。

postgres时区问题

在容器中的postgres很可能的时区是UTC的或者是etc/utc的。可以通过sql语句查看show time zone;
我们使用golang+gorm往数据库插入数据时使用time.Now()给数据的时间字段赋值时,在数据库看见的就是少8小时的时间。如果要使用这个时间字段做查询,那么正常使用加8小时的北京时间就行。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Golang中的Gin框架提供了一种简单而强大的方法来构建Web应用程序。与此同时,Golang标准库中的"net/http"包提供了构建WebSocket服务器和客户端的功能。 首先,我们来看一下如何使用Gin和WebSocket构建WebSocket服务器。首先,需要导入相关的包: ```go import ( "github.com/gin-gonic/gin" "github.com/gorilla/websocket" ) ``` 接下来,在Gin中创建一个WebSocket处理函数: ```go func WebSocketHandler(c *gin.Context) { upgrader := websocket.Upgrader{ ReadBufferSize: 1024, WriteBufferSize: 1024, } conn, err := upgrader.Upgrade(c.Writer, c.Request, nil) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } for { messageType, message, err := conn.ReadMessage() if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } err = conn.WriteMessage(messageType, message) if err != nil { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } } } ``` 上面的代码创建了一个基本的WebSocket处理函数。它使用WebSocket标准库中的Upgrader结构来处理升级连接并创建一个WebSocket连接。 然后,我们需要在Gin中设置路由来处理WebSocket请求: ```go router := gin.Default() router.GET("/ws", WebSocketHandler) ``` 以上代码将在根路径下创建一个WebSocket处理函数。 接下来,我们来看一下如何使用Golang和Gin构建WebSocket客户端。首先,我们需要导入所需的包: ```go import ( "github.com/gorilla/websocket" "net/http" ) ``` 然后,我们可以使用以下代码来创建一个WebSocket客户端: ```go func main() { c, _, err := websocket.DefaultDialer.Dial("ws://localhost:8080/ws", nil) if err != nil { log.Fatal("dial:", err) } defer c.Close() done := make(chan struct{}) go func() { defer close(done) for { _, message, err := c.ReadMessage() if err != nil { log.Println("read:", err) return } log.Printf("recv: %s", message) } }() ticker := time.NewTicker(time.Second) defer ticker.Stop() for { select { case <-done: return case <-ticker.C: err := c.WriteMessage(websocket.TextMessage, []byte("Hello, Server!")) if err != nil { log.Println("write:", err) return } } } } ``` 上面的代码创建了一个WebSocket客户端,它使用WebSocket标准库中的`DefaultDialer`结构来建立WebSocket连接。 以上就是使用Golang Gin和WebSocket构建WebSocket客户端和服务器的简单示例。这些代码可以帮助我们使用Gin和Golang的标准库来构建强大的Web应用程序,并处理WebSocket通信。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值