参考:Xorm
![在这里插入图片描述](https://i-blog.csdnimg.cn/blog_migrate/ab731cfeda99f9d4775f9820f7667af9.png)
1、插入数据
1、Orm方式
这边的前提条件是程序的实体和数据库表结构映射已经达成。
1、同一个表插入数据
这边User是一个已经映射好的实体,简化一下这个过程。直接上代码:
//新增一条User表的数据
affected, err := engine.Insert(user)
//根据切片新增多个User表的数据,中间的赋值略过
users := make([]User, 1)
affected, err := engine.Insert(&users)
//这边还可以根据指针的方式进行多条数据的插入,这个和上面的很类似吧,中间的赋值略过
users := make([]*User, 1)
affected, err := engine.Insert(&users)
//这个也是插入多条,但是和上面不同的是:不使用批量插入,此时实际生成多条插入语句
affected, err := engine.Insert(users...)
2、不同的表插入数据
User和Question对应两个不同的表
//各自插入一条数据
affected, err := engine.Insert(user, question)
//插入一条多条或者都是多条数据
affected, err := engine.Insert(&users, &questions)
affected, err := engine.Insert(user, &questions)
3、注意
- 这里虽然支持同时插入,但这些插入并没有事务关系。因此有可能在中间插入出错后,后面的插入将不会继续。此时前面的插入已经成功,如果需要回滚,请开启事物。
- 批量插入会自动生成Insert into table values (),(),()的语句,因此各个数据库对SQL语句有长度限制,因此这样的语句有一个最大的记录数,根据经验测算在150条左右。大于150条后,生成的sql语句将太长可能导致执行失败。因此在插入大量数据时,目前需要自行分割成每150条插入一次。
2、SQL命令方式
1、常规方式
这个就是直接书写sql,然后传入参数即可,感觉还是很简单的。
sql ="insert into config(key,value) values (?, ?)"
res, err := engine.Exec(sql, "OSCHINA", "OSCHINA")
sql_2 := "insert into config(key,value) values (?, ?)"
affected, err := engine.Sql(sql_4, "OSCHINA", "OSCHINA").Execute()
2、sqlMap方式
这边支持直接传入参数,按照对应的sql中?
的顺序来拼接这个参数,或者是传入map的结构,传入map的结构感觉好点,不过注意模板配置的sql和常规的不一样,
//SqlMap中key为 "sql_i_1" 配置的Sql语句为:insert into config(key,value) values (?, ?)
sql_i_1 := "sql_i_1"
affected, err := engine.SqlMapClient(sql_i_1, "config_1", "1").Execute()
//SqlMap中key为 "sql_i_2" 配置的Sql语句为:insert into config(key,value) values (?key, ?value)
sql_i_2 := "sql_i_2"
paramMap_i := map[string]interface{
}{
"key": "config_2", "value": "2"}
affected, err := engine.SqlMapClient(sql_i_2, ¶mMap_i).Execute()
3、SQLTemplates方式
查看原文:执行SQL命令插入数据
3、创建时间和时区问题
参考原文:创建时间Created
2、更新数据
这边User是一个已经映射完成的数据库实体,Id是他的主键字段
1、Orm方式更新
1、结构体更新
这边根据主键为id字段进行更新,正常在实体中有标识pk字段直接传入user对象到Update方法就可以了。
user := new(User)
user.Name = "myname"
affected, err := engine.Id(user.id).Update(user)
2、更新某些字段
这边如果一个对象想要指定他需要更新的属性,只需要把这个字段名传入就行,这边是只更新age字段:
affected, err := engine.Id(id).Cols("age").Update(&user)
3、map方式更新
根据map去更新需要指定对应的结构体对象,不然根据map是没办法找到对应的表(没有标签之类的信息),正常来说感觉这种方式更新不咋地简便:
affected, err := engine.Table(new(User)).Id(id).Update(map[string]interface{
}{
"age":0})
4、乐观锁方式
要使用乐观锁,需要使用version标记 type User struct { Id int64 Name string Version int xorm:“version” }
在Insert时,version标记的字段将会被设置为1,在Update时,Update的内容必须包含version原来的值。
理解乐观锁作用的,这个用来做同步的方式还是挺好的,不过还是得注意一下判断version的方法需要用到同步,整个更新和判断的过程应该是同步的。
var user User
engine.Id(1).Get(&user)
// SELECT * FROM user WHERE id = ?
engine.Id(1).Update(&user)
// UPDATE user SET ..., version = version + 1 WHERE id = ? AND version = ?
5、更新时间
这个感觉没啥说的,用到的可以直接参考原文:更新时间Updated
2、执行sql更新
1、书写sql更新
书写sql更新的方式有两种,其实只是写法上的不同而已
//第一种方式
sql ="update user set age = ? where name = ?"
res