go语言 xorm框架 postgresql 的用法及详细注解

xorm用于在golang中链接数据库,并完成增删改差操作,不管是orm还是raw方式都十分的新颖简单。

sql语句

postgresql pgadmin

/*表结构*/
CREATE TABLE public.user
(
 id serial primary key,
 name varchar(20)
);
ALTER TABLE public.user ADD COLUMN created timestamp default now();
ALTER TABLE public.user ADD COLUMN class_id integer default 1;
insert into public.user(name) values('ft');
insert into public.user(name) values('ft2');
insert into public.user(name,class_id) values('ft8',2)
CREATE TABLE public.class
(
 id serial primary key,
 name varchar(20)
);
insert into public.class(name) values('高中一班');
insert into public.class(name) values('高中二班');
/*常用到的操作*/
select * from public.class;
select * from public.user;
select u.id,u.name,c.name from public.user as u left join public.class as c on u.class_id=c.id;

main.go

每个功能都使用了if语句来方便开关,测试那块就打开哪块~~~

package main
import (
 _ "github.com/lib/pq"
 "github.com/xormplus/xorm"
 "fmt"
 "time"
 "strconv"
)
//用户表结构
type User struct {
 Id  int  `xorm:"not null pk autoincr INTEGER"`
 Name string `xorm:"VARCHAR(20)"`
 Created time.Time `xorm:"default 'now()' DATETIME"`
 ClassId int  `xorm:"default 1 INTEGER"`
}
//Class表结构
type Class struct {
 Id int `xorm:"not null pk autoincr INTEGER"`
 Name string `xorm:"VARCHAR(20)"`
}
//临时表结构
type UserClass struct{
 User `xorm:"extends"`
 Name string
}
//此方法仅用于orm查询时,查询表认定
func (UserClass) TableName() string {
 return "public.user"
}
func main() {
 //1.创建db引擎
 db, err := xorm.NewPostgreSQL("postgres://postgres:123@localhost:5432/test?sslmode=disable")
 if err != nil {
  fmt.Println(err)
 }
 //2.显示sql语句
 db.ShowSQL(true)
 //3.设置连接数
 db.SetMaxIdleConns(2000)
 db.SetMaxOpenConns(1000)
 cacher := xorm.NewLRUCacher(xorm.NewMemoryStore(), 500)//缓存的条数
 db.SetDefaultCacher(cacher)
 //4.执行插入语句的几种方式
  //4.1 orm插入方式:不好控制,如果仅仅插入的对象的属性是name='ftq',那么其他的零值会一同insert,orm方式对零值的处理有点不太好
  if false {
   user := new(User)
   user.Name = "ftq"
   _, err = db.Insert(user)
   if err != nil {
    fmt.Println(err)
   }
  }
  //4.2 命令插入方式
   //4.2.1 db.Exec():单事务单次提交
   if false{
   sql:="insert into public.user(name) values(?)"
   db.Exec(sql,"ft4")
   }
   //4.2.2 db.SQL().Execute():单事务准备了Statement处理sql语句
   if false{
    sql:="insert into public.user(name) values(?)"
    db.SQL(sql,"ft5").Execute()
   }
   //4.2.3使用sql配置文件管理语句,两种载入配置的方式LoadSqlMap()和RegisterSqlMap(),以及SqlMapClient()替代SQL()
   if false {
    err = db.LoadSqlMap("./sql.xml")
    //err = db.RegisterSqlMap(xorm.Xml("./","sql.xml"))
    if err != nil {
     fmt.Println(err)
    }
    db.SqlMapClient("insert_1","ft7").Execute()
   }
 //5.执行查询的几种方式
  //5.1 orm查询:在user初始化的时候,该orm查询直接通过扫描user类型确定表名;组合使用Where(),Get()
  if false {
   user := new(User)
   boolget ,err2 :=db.Where("id=?",5).Get(user)
   fmt.Println(boolget,err2,user)
  }
  //5.2 orm查询:组合使用Where(),Get(),And()
  if false {
   user := new(User)
   boolget ,err2 :=db.Where("id=?",5).And("name=?","ft7").And("id>?",3).Get(user)
   fmt.Println(boolget,err2,user)
  }
  //5.3 orm查询: AllCols()查询所有列,Cols()查询部分列,Find()解析多行结果,Get()解析单行结果
  if false {
   users := new ([]User)
   err = db.AllCols().Find(users)
   //err = db.Cols("id","name").Find(users)
   if err !=nil {
    fmt.Println(err)
   }
   fmt.Println(users)
  }
  //5.4 orm查询:连接查询Join()
  if false {
   users := new([]UserClass)
   db.Join("INNER","class","user.class_id=class.id").Find(users)
   //db.SQL("select u.id,u.name,c.name from public.user as u left join public.class as c on u.class_id=c.id").Find(users)
   fmt.Println(users)
  }
  //5.5 sql查询略
  if false {
   //和insert类似,Find查找多行结果,Get获取 单行结果
   users := new([]UserClass)
   db.SQL("select u.id,u.name,c.name from public.user as u left join public.class as c on u.class_id=c.id").Find(users)
   fmt.Println(users)
   }
  //5.6 链式查找
  if false {
   //值得一提的是,支持查找某行的某个字段,不过一般在sql语句中就可以完成过滤,如果sql语句过于复杂,可以链式查找过滤
   id := db.SQL("select * from public.user").Query().Results[0]["id"]
   fmt.Println(id)
  }
 //6.执行更新
  //6.1 ORM方式: 只有非0值的属性会被更新,user的id和created都是默认零值,不被处理
  if false {
   user :=new(User)
   user.Name="ftx"
   //[xorm] [info] 2018/02/08 12:04:01.330624 [SQL] UPDATE "user" SET "name" = $1 WHERE "id"=$2 []interface {}{"ftx", 4}
   db.Id(4).Update(user)
  }
  //6.2 SQL方式略,和insert类似
 //7.事务
  //7.1简单事务
  if false {
   session :=db.NewSession()
   defer session.Close()
   session.Begin()
   //业务:新添加学生,并且创建新的班级,如果班级因为主键冲突创建失败,则整个事务回滚
   _,err =session.SQL("insert into public.user(name,class_id) values('ft13',2)").Execute()
   //表中已经有id=3的班级了
   _,err =session.SQL("insert into public.class(id,name) values(3,'高中3班')").Execute()
   if err!=nil {
    session.Rollback()
   }
   session.Commit()
  }
  //7.2嵌套事务
  if false {
   session := db.NewSession()
   defer session.Close()
   session.Begin()
   _,err=session.Exec("insert into public.user(name,class_id) values('ft23',2)")
   if err!=nil {
    session.Rollback()
   }
   _,err=session.Exec("insert into public.user(id,name,class_id) values(1,'ft24',2)")
   if err!=nil {
    session.Rollback()
   }
   tx,_:=session.BeginTrans()
   _,err=tx.Session().Exec("insert into public.user(name,class_id) values('ft25',2)")
   if err!=nil {
    tx.RollbackTrans()
   }
   tx.CommitTrans()
   session.Commit()
  }
 //8.缓存:使用Raw方式修改以后,需要清理缓存
 if true {
   //建立500条数据
   session := db.NewSession()
   defer session.Close()
   if false {
    session.Begin()
    for i := 30; i < 530; i++ {
     value := "ft" + strconv.Itoa(i)
     _, err = session.Exec("insert into public.user(name) values(?)", value)
     if err != nil {
      session.Rollback()
     }
    }
    session.Commit()
   }
   //查询前531条数据,并随意输出其中一条
   users := make([]User,10)
   db.SQL("select * from public.user where id<531 order by id").Find(&users)
   fmt.Println("读第一遍:","id:",users[50].Id,"name:",users[50].Name)
   db.SQL("select * from public.user where id<531 order by id").Find(&users)
   fmt.Println("读第二遍:","id:",users[50].Id,"name:",users[50].Name)
   var step int =1
   stepString := users[50].Name + strconv.Itoa(step)
   session.Exec("update public.user set name=? where id =45",stepString)
   //清理缓存
   db.ClearCache(new(User))
   time.Sleep(5*time.Second)
   session.SQL("select * from public.user where id<531 order by id").Find(&users)
   fmt.Println("读第三遍:","id:",users[50].Id,"name:",users[50].Name)
   //虽然很不好意思,但是就算开启了缓存数据也是脏了
 }
 //9.读写分离
 if false {
 //假设有多台服务器用来响应客户的读请求
 var dbGroup *xorm.EngineGroup
 conns :=[]string {
  "postgres://postgres:123@localhost:5432/test?sslmode=disable",
  "postgres://postgres:123@localhost:5432/test?sslmode=disable",
  "postgres://postgres:123@localhost:5432/test?sslmode=disable",
  "postgres://postgres:123@localhost:5432/test?sslmode=disable",
 }
 //负载均衡策略:(特性自行百度)
  // 1.xorm.RandomPolicy()随机访问负载均衡,
  // 2.xorm.WeightRandomPolicy([]int{2, 3,4})权重随机负载均衡
  // 3.xorm.RoundRobinPolicy() 轮询访问负载均衡
  // 4.xorm.WeightRoundRobinPolicy([]int{2, 3,4}) 权重轮训负载均衡
  // 5.xorm.LeastConnPolicy()最小连接数负载均衡
 dbGroup, err = xorm.NewEngineGroup("postgres", conns, xorm.RoundRobinPolicy())
 //dbGroup使用方法和db一致
   //简单查询
   dbGroup.SQL("inser into public.users(name) values('ft2000')").Execute()
   dbGroup.Exec("inser into public.users(name) values('ft2001')")
   //事务查询
   session :=dbGroup.NewSession()
   defer session.Close()
   session.Begin()
   _,err = session.Exec("inser into public.users(name) values('ft2001')")
   if err!=nil {
   session.Rollback()
   }
   session.Commit()
 }
}
//注意:
//1.postgresql好像不会默认按id增长排序,所以书写sql语句要提前写好order by id ,楼主没怎么写,咳咳
//2. [5.4] postgresql建表会建在public策略的table里,所以查询语句表明写的是public.xxxx,这也造成了连表orm查询会发生前缀报错,比如变成了"SELECT * FROM "public"."user" INNER JOIN "class" ON user.class_id=class.id 这和内部的split有关,
//3.[8.]带的缓存好像很容易失效,在创建500个数据后,经过查查改查的操作,查询到的结果是一样的始终是一样的,本来改值之后应该最后一遍查会变化,然而并没有,缓存功能即使清理了缓存,还是会读到脏的

补充:golang xorm框架对应pg数据库字段类型参照表

1.左边是golang字段类型,右边是pg数据库字段类型

int  integer
time.Time timestamp
int8 smallint
float64 numeric(8,3) (只要是numeric统统使用float64)
string text
string varchar

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • 解决goxorm无法更新值为默认值的问题

    今天遇到个问题,goxorm无法更新某一个字段为0. xxTable := &models.XXTable{Visible: visible} affected, err := eng.Where("id=?", id).Update(xxTable) 这种情况下,因为go的结构初始值都是各自的0值,所以xorm无法识别要更新结构体中的哪个col,如下方法写可以正常解决. xxTable := &models.XXTable{Visible: visible} affe

  • golang中xorm的基本使用说明

    简单的用法 package main import ( _ "github.com/go-sql-driver/mysql" "github.com/go-xorm/xorm" "log" ) //定义结构体(xorm支持双向映射) type User struct { User_id int64 `xorm:"pk autoincr"` //指定主键并自增 Name string `xorm:"unique&quo

  • 使用go xorm来操作mysql的方法实例

    在golang中要实现对数据库的操作, 一个比较好用的方式就是使用XORM,xorm是一个简单而强大的Go语言ORM库,通过它可以使数据库操作非常简便. 在xorm里面,可以同时存在多个ORM引擎,一个ORM引擎称为Engine,一个Engine一般只对应一个数据库. golang的连接池配置 这里初始化一个全局的xorm.Engine对象, xorm.Engine通过调用xorm.NewEngine生成在很多其他的API都需要传入该对象作为参数. 这里需要理解这里设定的3个参数的意义: Set

  • xorm根据数据库生成go model文件的操作

    你懂的,手工翻译表定义到go结构体是很枯燥的. so,用xorm搞定. go get github.com/go-xorm/cmd/xorm 安装以下依赖,用到哪个装哪个. github.com/go-xorm/xorm 驱动 Mysql: github.com/go-sql-driver/mysql Postgres: github.com/lib/pq SQLite: github.com/mattn/go-sqlite3 MSSQL: github.com/denisenkom/go-ms

  • go语言 xorm框架 postgresql 的用法及详细注解

    xorm用于在golang中链接数据库,并完成增删改差操作,不管是orm还是raw方式都十分的新颖简单. sql语句 postgresql pgadmin /*表结构*/ CREATE TABLE public.user ( id serial primary key, name varchar(20) ); ALTER TABLE public.user ADD COLUMN created timestamp default now(); ALTER TABLE public.user AD

  • 易语言关于数据库“置当前库”命令用法

    本命令选择一个已经被打开的数据库为当前数据库,大部分数据库操作命令都针对当前数据库,譬如:记录指针的移动.字段的读写等等.如果指定数据库不存在或者尚未被打开,命令将返回假,否则返回真. 语法: 逻辑型 置当前库 (数据库别名或名称) 参数名 描 述 数据库别名或名称 必需的:文本型.参数值指定一个已经被打开的数据库. 例程: 说明: 使用"置当前库()"命令将当前库设置为组合框中所选数据库,并使用记次循环命令将当前库所有记录的"年龄"显示在列表框中. 注意:易语言中

  • 易语言操作数据库“取索引数”命令用法

    返回当前数据库中已经被打开索引的数目. 语法: 整数型 取索引数 () 例程: 说明: 启动窗口创建完毕后,打开数据库1,同时打开2个索引文件.当点击"显示索引"按钮,使用"取索引数()"命令将当前打开的索引数取出,并用该数值规定"记次循环首()"命令的循环次数,在循环中使用"取索引名()"命令依次将每个索引的名字取出,并添加到列表框中. 以上就是易语言操作数据库"取索引数"命令用法的详细内容,更多关于易语

  • C语言指针详解及用法示例

    新手在C语言的学习过程中遇到的最头疼的知识点应该就是指针了,指针在C语言中有非常大的用处.下面我就带着问题来写下我对于指针的一些理解. 指针是什么? 指针本身是一个变量,它存储的是数据在内存中的地址而不是数据本身的值.它的定义如下: int a=10,*p; p=&a int a=10; int *p=&a; 首先我们可以理解 int* 这个是要定义一个指针p,然后因为这个指针存储的是地址所以要对a取地址(&)将值赋给指针p,也就是说这个指针p指向a. 很多新手都会对这两种定义方法

  • Yii框架中memcache用法实例

    本文实例讲述了Yii框架中memcache用法.分享给大家供大家参考.具体分析如下: 在现在的公司用的是YII的框架,接触到的东西也比较多,可以学到的东西也比较多,在以前的公司没有接触过memcache,只是听过,但是从来没有真正用过.现在终于有机会使用一下了,就以我做的项目为例吧! 我做的项目是一个手机排行榜,但是排行榜每隔15分钟刷新一次啊,排行榜有一个前三名,可能前15分钟这三个人是前三名,也许下一个15分钟又是别人前三名了,产品要求,这些人中只要是前三名的都要发奖品,思考了好久,最终决定

  • GO语言映射(Map)用法分析

    本文实例讲述了GO语言映射(Map)用法.分享给大家供大家参考.具体如下: 映射是一种内置的数据结构,用来保存键值对的无序集合. (1)映射的创建 make ( map [KeyType] ValueType, initialCapacity ) make ( map [KeyType] ValueType ) map [KeyType ] ValueType {} map [KeyType ] ValueType { key1 : value1, key2: value2, ... , key

  • Go语言里的new函数用法分析

    本文实例讲述了Go语言里的new函数用法.分享给大家供大家参考.具体如下: 表达式 new(T) 分配了一个零初始化的 T 值,并返回指向它的指针. var t *T = new(T) 或 t := new(T) 代码如下: 复制代码 代码如下: package main import "fmt" type Vertex struct {     X, Y int } func main() {     v := new(Vertex)     fmt.Println(v)     v

  • Zend Framework教程之MVC框架的Controller用法分析

    本文讲述了Zend Framework教程之MVC框架的Controller用法.分享给大家供大家参考,具体如下: 这里简单讲讲MVC模式中Controller的基本使用方法. 基本使用实例: root@coder-671T-M:/www/zf_demo1/application# tree. ├── Bootstrap.php ├── configs │   └── application.ini ├── controllers │   ├── ErrorController.php │  

  • YII框架行为behaviors用法示例

    本文实例讲述了YII框架行为behaviors用法.分享给大家供大家参考,具体如下: 文件 frontend/libs/FilterTest.php <?php /** * Created by PhpStorm. * Date: 2016/5/27 * Time: 14:16 */ namespace frontend\libs; use Yii; use yii\base\Action; use yii\base\ActionFilter; class FilterTest extends

  • CI框架附属类用法分析

    本文实例讲述了CI框架附属类用法.分享给大家供大家参考,具体如下: 有些时候,你可能想在你的控制器之外新建一些类,但同时又希望 这些类还能访问 CodeIgniter 的资源 任何在你的控制器方法中初始化的类都可以简单的通过 get_instance() 函数来访问 CodeIgniter 资源.这个函数返回一个 CodeIgniter 对象. 通常来说,调用 CodeIgniter 的方法需要使用 $this $this->load->helper('url'); $this->loa

随机推荐