范文健康探索娱乐情感热点
热点动态
科技财经
情感日志
励志美文
娱乐时尚
游戏搞笑
探索旅游
历史星座
健康养生
美丽育儿
范文作文
教案论文

尝试用golang1。18泛型实现orm

  这几天golang社区对泛型的讨论非常多的,一片热火朝天的景象。对我们广大gopher来说总归是好事。
  泛型很有可能会颠覆我们之前的很多设计,带着这种疑问和冲动,我准备尝试用golang泛型实现几个orm的常见功能。
  本文并没完全实现通用的orm,只是探讨其实现的一种方式提供各位读者做借鉴。创建Table
  虽然golang有了泛型,但是目前在标准库sql底层还没有改造,目前还有很多地方需要用到reflect。func CreateTable[T any](db *sql.DB) { 	var a T 	t := reflect.TypeOf(a) 	tableName := strings.ToLower(t.Name())  	var desc string 	for i := 0; i < t.NumField(); i++ { 		columnsName := strings.ToLower(t.Field(i).Name) 		var columnType string 		switch t.Field(i).Type.Kind() { 		case reflect.Int: 			columnType = "integer" 		case reflect.String: 			columnType = "text" 		} 		desc += columnsName + " " + columnType 		if i < t.NumField()-1 { 			desc += "," 		} 	} 	sqlStmt := fmt.Sprintf(`create table if not exists %s (%s);`, tableName, desc) 	_, err := db.Exec(sqlStmt) 	if err != nil { 		log.Printf("%q: %s ", err, sqlStmt) 		return 	} }
  调用方式 type Person struct { 	ID   int 	Name string 	Age  int }  type Student struct { 	ID   int 	Name string 	No   string }  var db sql.DB //init db //... CreateTable[Person](db) CreateTable[Student](db)
  这个部分跟传统的orm使用上没有太大区别,没办法不使用反射的情况下,泛型的方式可能变得有点繁琐。写入数据func Create[T any](db *sql.DB, a T) { 	//没有办法这边还是得使用反射 	t := reflect.TypeOf(a) 	tableName := strings.ToLower(t.Name())  	var columns []string 	var spacehold []string 	for i := 0; i < t.NumField(); i++ { 		columns = append(columns, strings.ToLower(t.Field(i).Name)) 		spacehold = append(spacehold, "?") 	}  	tx, err := db.Begin() 	if err != nil { 		log.Fatal(err) 	} 	stmt, err := tx.Prepare( 		fmt.Sprintf("insert into %s(%s) values(%s)", 			tableName, 			strings.Join(columns, ","), 			strings.Join(spacehold, ",")))  	if err != nil { 		log.Fatal(err) 	} 	defer stmt.Close()  	v := reflect.ValueOf(a)  	var values []any  	for i := 0; i < t.NumField(); i++ { 		if v.FieldByName(t.Field(i).Name).CanInt() { 			values = append(values, v.FieldByName(t.Field(i).Name).Int()) 		} else { 			values = append(values, v.FieldByName(t.Field(i).Name).String()) 		} 	} 	_, err = stmt.Exec(values...) 	if err != nil { 		panic(err) 	} 	tx.Commit() }
  调用方式var p1 = Person{ 	ID:   1, 	Name: "wida", } Create[Person](db, p1) var s1 = Student{ 	ID:   1, 	Name: "wida", 	No:   "1111", } Create[Person](db, p1) Create[Student](db, s1)
  和创建table类似,写入数据好像比没有之前的orm有优势。读取数据
  读取数据是非常高频的操作,所以我们稍作封装。type Client struct { 	db *sql.DB }  type Query[T any] struct { 	client *Client }  func NewQuery[T any](c *Client) *Query[T] { 	return &Query[T]{ 		client: c, 	} } //反射到struct func ToStruct[T any](rows *sql.Rows, to T) error { 	v := reflect.ValueOf(to) 	if v.Elem().Type().Kind() != reflect.Struct { 		return errors.New("Expect a struct") 	}  	scanDest := []any{} 	columnNames, _ := rows.Columns()  	addrByColumnName := map[string]any{}  	for i := 0; i < v.Elem().NumField(); i++ { 		oneValue := v.Elem().Field(i) 		columnName := strings.ToLower(v.Elem().Type().Field(i).Name) 		addrByColumnName[columnName] = oneValue.Addr().Interface() 	}  	for _, columnName := range columnNames { 		scanDest = append(scanDest, addrByColumnName[columnName]) 	} 	return rows.Scan(scanDest...) }  func (q *Query[T]) FetchAll(ctx context.Context) ([]T, error) { 	var items []T  	var a T 	t := reflect.TypeOf(a)  	tableName := strings.ToLower(t.Name()) 	rows, err := q.client.db.Query("SELECT * FROM " + tableName) 	if err != nil { 		return nil, err 	}  	for rows.Next() { 		var c T 		ToStruct(rows, &c) 		items = append(items, c) 	} 	return items, nil }
  调用方式var client = &Client{ 	db: db, }  { 	query := NewQuery[Person](client) 	all, err := query.FetchAll(context.Background()) 	if err != nil { 		log.Fatal(err) 	} 	for _, person := range all { 		log.Println(person) 	} } { 	query := NewQuery[Student](client) 	all, err := query.FetchAll(context.Background()) 	if err != nil { 		log.Fatal(err) 	} 	for _, person := range all { 		log.Println(person) 	} }
  稍微比原先的orm方式有了多一点想象空间,比如 在[T any]做更明确的约束,比如要求实现Filter定制方法。总结
  鉴于本人能力还认证有限,目前还没有发现泛型对orm剧烈的改进和突破的可能。未来如果go对底层sql做出改动,或者实现诸如Rust那种Enum方式,可能会带来更多的惊喜。

特斯拉又撞死人!丧命事故被查据外媒报道,9月3日,美国汽车安全监管机构透露,他们正在调查7月26日在纽约发生的一起致命车祸,事故涉及一辆特斯拉。事故发生时该车可能使用了驾驶员辅助系统。目前监管机构成立了针对该美团,微粒贷逾期之后的催收美团和微粒贷到今天为止逾期第4天了,美团的催收从逾期第一天就开始给打电话,各种的催,甚至威胁说要到你的户籍所在地铺了解你的具体情况,我这就不理解了,我没在老家,在外地打工,你去我户荣耀7。2英寸大屏新机即将发布!配备6000mAh大电池,价格更亲民近段时间,关于荣耀X20Max的消息越来越多,这也就意味着距离这款新机的发布时间不会太远了。我们都知道荣耀X系列Max新机最大的亮点就是屏幕尺寸大,这也是很多用户选择该系列新机的主北京昌平区政府签约信息科技大学,5G助建科创平台记者9月6日获悉,昌平区政府与北京信息科技大学签署了合作框架协议。在中国移动5G等信息技术助力下,共建重大科技创新平台,促进昌平区高精尖产业创新发展。今后昌平区政府与北京信息科技大长城XR访谈超图集团地理信息驱动数字孪生来源长城网超图集团董事长钟耳顺做客数博会长城新媒体XR虚拟访谈直播间。超图集团董事长钟耳顺做客数博会长城新媒体XR虚拟访谈直播间。长城网记者郑佳洵9月6日,在2021年中国国际数字华为Nova9入网,预装鸿蒙2。0,外观精美,花粉买单吗?华为手机收获了很大的市场好评,从产品本身来看,这些年P系列和Mate系列确实成为了苹果三星在高端市场最强大的竞争对手,从核心技术方面来看,华为掌握的5G技术确实全球领先,这也造就了台式机如何使用无线网?之前帮助一家培训学校升级下电脑配置,当然了硬件配置非常低,勉强办公,没错,就是和我们常见的公司办公用机那种差到令人发指的机器,当然对于处理文档表格类的工作还是可以做的,只要有耐心。手机三星机皇三星galaxynote20ultra搭载了一块6。9英寸30881440分辨率的第二代dynamicamoled120hz自适应屏幕。dynamicamoled和120hz大家都云米AI智能晾衣机Lite2电动升降错层晾晒前半年由于工作变动,重新租了房子。来到这边以后虽然面积大了很多,生活起居不再受约束,也为我日常搞机腾出了宽裕的空间。不过家中小姐姐却经常抱怨,房东原先安装的手摇式晾衣架很不方便,而值得入手的小家电之迷你破壁机家里的豆浆机太大了,功能单一,清洗麻烦,占用空间大都让我耿耿于怀。几次都要换了他,想入手个破壁机,又能研磨豆浆还能制作果汁。aiyouth免滤迷你破壁机引起了我的注意,它小巧轻便小海信电视E5F和E5G对比分析海信目前主力社交电视55E5F正在清理尾货库存,替代机型55E5G在5月初上市培养,强对标华为康德系列,学康德的卖点。主要升级点1CPU从四核A732A532变成四核A73。2自动
苹果11promax和12哪个更值得入手11promax19年的旗舰机皇和去年的12,目前11promax市场还是比较不错的,三摄在苹果领域也是做了跨越。12作为20年苹果第一款5g也是不错的选择,换作你们会选择哪款。1年末换新机?2021年最不值得入手的三款手机,高价低配太坑了年底相信很多小伙伴在考虑换新机,现在智能手机市场的品牌和机型让人眼花缭乱,接下来小编就给大家盘点一下年末千万不要入手的三款手机,希望小伙伴们都擦亮眼睛,稍一不慎就入坑。第一款荣耀V还记得HTC手机品牌吗?曾经的手机巨头,现在已成昨日黄花大家还记得HTC这个手机品牌吗?在智能手机刚刚兴起的那个年代,那可是火遍全球的大品牌,全球的第一部安卓智能手机就是HTC发布的,那就是2008年发布的HTCG1,当时还引起了不小的苹果手机产量不是世界第一,却能拿走行业75利润,凭什么?在竞争日益激烈的智能手机领域,苹果iPhone的产量不是世界第一,却能拿走了行业75的营业收入利润。为什么苹果公司的iPhone,可以做到其他公司没有的高收入呢?苹果公司是一家成功有人说三星手机在中国的市场份额已不足1,对此你怎么看?我们公司百分之七十用三星手机。剩下的用苹果及其他品牌。没有一个用华为手机的。我周边的朋友也仅仅一个用华为手机的。我们公司的平均收入超过一万五人民币。不是说用手机装身份!手机是时时刻如果微信从下月开始收费,每月10元,你还会用吗?如果微信从下月开始收费,每月10元,你还会用吗?这是一个很悲催的提问,微信仅仅只是腾讯公司旗下的一个分支,互联网巨头马化腾是一个大格局的人,这样的蝇头小利根本看不起眼,也根本没有打键盘上最多余的按键,为什么还没被干掉最近机哥刷知乎的时候看到了这样一个问题。说实话,之前还真没有认真思考过这个细节。按照机哥平时用键盘的习惯,输入电话号码账号密码这些,确实更习惯用右边的数字小键盘。如果用字母区上的数2021。12。14最新电脑配置推荐与方向更多关注和咨询的话请微信公众号装机不是程序猿CPUi310150F散热赛普雷冷山白4铜管主板微星H510M爆破弹内存威刚D42666普条8g固态数码映众256GM2NVME显卡七彩账号注销自动化推荐退订难?中消协点名饿了么等23款APP21世纪经济报道记者蔡姝越,诸未静,吴立洋广州报道信息化时代,个人信息保护与大众利益息息相关。个人信息保护法公布已超过一个月,各家APP的具体执行效果如何?12月14日,中国消费者高通出尔反尔,摩托罗拉截胡小米,雷军心里苦多家科技公司之间存在着相互合作的关系。为了成功获得高端芯片,小米公司和高通公司互为股东,高通公司也为小米公司提供高性能的芯片。随着时间的流逝,全球芯片市场迎来了大变化,多家公司纷纷思维导图软件哪个好?推荐两款我最常的思维导图软件,都是国产软件,分别是网页版和安装版。No。1百度脑图软件功能易用指数推荐指数个人觉得这款软件是百度公司少有的优秀产品,以至于不像是百度的风格。在国内,