当前位置: 首页 > news >正文

亚马逊跨境电商个人开店流程结构优化是什么意思

亚马逊跨境电商个人开店流程,结构优化是什么意思,莘县聊城做网站,生活家装饰官方网站Go语言操作数据库 Go语言提供了关于数据库的操作,包下有sql/driver 该包用来定义操作数据库的接口,这保证了无论使用哪种数据库,操作方式都是相同的; 准备工作: 下载驱动 需要在代码所在文件夹下执行相应的命令 go get github.com/go-sql-driver/mys…

Go语言操作数据库

Go语言提供了关于数据库的操作,包下有sql/driver

该包用来定义操作数据库的接口,这保证了无论使用哪种数据库,操作方式都是相同的;

准备工作:

下载驱动

需要在代码所在文件夹下执行相应的命令

go get github.com/go-sql-driver/mysql

PS D:\GolandData> go get github.com/go-sql-driver/mysql
go: downloading github.com/go-sql-driver/mysql v1.7.1
go: added github.com/go-sql-driver/mysql v1.7.1

安装驱动

go install github.com/go-sql-driver/mysql

安装之后检查go.mod文件

在这里插入图片描述

Go提供了sql包,但是没有指定是哪一个数据库的,用于访问特定数据库的方法交给了数据库驱动实现;

匿名导入包

匿名导入包——只导入包但是不使用包内的类型和数据,使用匿名的方式(在包路径前添加下画线“_”)导入MySQL驱动。

为什么需要匿名导包—开发者不应该直接使用导入的驱动包所提供的方法,而应该使用sql.DB对象所提供的统一方法;

在导入一个数据库驱动后,该驱动会自行初始化并注册到Golang的database/sql上下文中

连接数据库

连接数据库基础API

Driver接口中有一个方法Open()

/*数据库驱动程序可以实现DriverContext访问在一个连接池中只解析一次名称而不是每个连接一次。*/
type Driver interface {/* Open返回到数据库的新连接。该名称是驱动程序特定格式的字符串。 Open可能返回一个缓存的连接(先前的一个关闭的),但这样做是不必要的;SQL包维护一个空闲连接池,以便有效地重用。返回的连接一次只被一个线程使用。*/Open(name string) (Conn, error)
}

sql包中有一个open(driverName, dataSourceName string)方法
该方法打开一个数据库连接,

func Open(driverName, dataSourceName string) (*DB, error) {driversMu.RLock()//这里说明一个线程用一个连接driveri, ok := drivers[driverName]driversMu.RUnlock()if !ok {return nil, fmt.Errorf("sql: unknown driver %q (forgotten import?)", driverName)}if driverCtx, ok := driveri.(driver.DriverContext); ok {connector, err := driverCtx.OpenConnector(dataSourceName)if err != nil {return nil, err}return OpenDB(connector), nil}return OpenDB(dsnConnector{dsn: dataSourceName, driver: driveri}), nil
}

参数释义----即连接数据库三要素

  • driverName–数据库驱动名
  • dataSourceName:数据库连接信息,数据库地址,用户名.密码, 数据库名等信息

由open()源代码可以看到,sql.Open()返回的sql.DB对象是并发安全的,即每次只能一个Goroutine使用一个,所以高并发下如果没有及时关闭不需要的连接,就会导致系统资源耗尽;

sql.DB的设计初衷是为长连接设计的,不宜频繁开关;

比较好的做法是,为每个不同的datastore建一个DB对象,保持这些对象打开
如果需要短连接(一次连接一次数据交互),就把DB作为参数传入function,而不要在function中开关。

CURD操作

来一段代码Demo

数据库查询

type BookInfo struct {BookId, BookName, BookPublish, BookKind stringBookPrice                               float64BookCount                               int
}func (b *BookInfo) DatabaseMysql() {//db, err := sql.Open("mysql", "root:123456@tcp(127.0.0.1:3306)/gavin?charset=utf8") //返回*DB, errordb, err := sql.Open("mysql", "root:123456@tcp(172.21.114.22:3306)/gavin?charset=utf8") //返回*DB, errorif err != nil {fmt.Println("打开失败")fmt.Println(err.Error())return}fmt.Println("打开成功")fmt.Printf("%T\n", db)queryStr := `select * from bookstore ;` //sql语句//Exec执行一个不返回任何行的查询。//args用于查询中的任何占位参数。  看样子不能用这个方法//exec, err := db.Exec(queryStr)         //返回Result ,err//fmt.Printf("类型%T \n 值 %v", exec, exec) // nil,nil//构建一个DB对象queryResult, err := db.Query(queryStr) //返回 *Rows, errorif err != nil {fmt.Println(err.Error())return}for queryResult.Next() {queryResult.Scan(&b.BookId, &b.BookName, &b.BookPublish, &b.BookPrice, &b.BookKind, &b.BookCount)fmt.Printf("bookInfo信息: bookid: %s\t bookname: %s \t bookpublish: %s \t bookprice: %f \t bookkind: %s bookcount %d \n", b.BookId, b.BookName, b.BookPublish, b.BookPrice, b.BookKind, b.BookCount)}db.Close()}func main() {b := BookInfo{}b.DatabaseMysql()
}

获得的结果:

在这里插入图片描述

我们可以看到代码的基本思路跟java一样,go是定义一个结构体用于接收数据库中的数据,然后我们需要掌握下面的几个函数用于处理数据库数据;最后关闭数据库连接

  • 使用db.Query()来发送查询到数据库,获取结果集Rows,并检查错误。
  • 使用rows.Next()作为循环条件,迭代读取结果集。
  • 使用rows.Scan从结果集中获取一行结果。
  • 使用rows.Err()在退出迭代后检查错误。
  • 使用rows.Close()关闭结果集,释放连接。

rows.Scan()方法的参数顺序很重要,必须和查询结果的column相对应(数量和顺序都需要一致)

插入数据

// 插入
func (b *BookInfo) insertData() {//连接数据库db, err := sql.Open("mysql", "root:123456@tcp(172.21.114.22:3306)/gavin?charset=utf8")chkERR(err)insertStr := `insert into bookstore VALUES("1024","Go并发实践","泉城出版社", 168.8,"计算机",198)`db.Exec(insertStr)chkERR(err)//_, err = exec.RowsAffected() //返回影响的行数,并不是所有数据库都支持,defer db.Close()
}

更新数据

// 更新
func (b *BookInfo) updateData() {db, err := sql.Open("mysql", "root:123456@tcp(172.21.114.22:3306)/gavin?charset=utf8")chkERR(err)updateStr := `update bookstore set bookprice=109 where bookname="Go并发实践"`exec, err := db.Exec(updateStr) //如果操作成功,返回affected, err := exec.RowsAffected()fmt.Println("update影响行数-->", affected)checkError(err)defer db.Close()
}

删除数据

// 删除
func (b *BookInfo) deleteData() {db, err := sql.Open("mysql", "root:123456@tcp(172.21.114.22:3306)/gavin?charset=utf8")chkERR(err)deleteStr := `delete from bookstore where bookprice>100 `exec, err := db.Exec(deleteStr)affected, err := exec.RowsAffected()fmt.Println("影响行数:", affected)defer db.Close()}

以上操作数据库的方式很容易就会产生sql注入

为此go也为我们提供了预编译的方式来操作数据库;


// 预编译的方式插入数据
func preInsert(book BookInfo) (int64, error) {db, err := sql.Open("mysql", "root:955945@tcp(172.21.114.22:3306)/gavin?")chkERR(err)queryStr := `insert into bookstore values (?,?,?,?,?,?)`//返回一个预编译的对象prepare, err := db.Prepare(queryStr) //*Stmt, errorchkERR(err)exec, err := prepare.Exec(book.BookId, book.BookName, book.BookPublish, book.BookPrice, book.BookKind, book.BookCount)affected, err := exec.RowsAffected() //返回受影响的行数fmt.Println("受影响的行数--->>", affected)defer db.Close()if err != nil {return -1, err}return affected, nil
}
func main() {b := BookInfo{BookId:      "1096",BookName:    "大雨倾盆",BookPublish: "烟台出版社",BookKind:    "小说",BookPrice:   56.5,BookCount:   100,}insert, err := preInsert(b)if err != nil {return}fmt.Println(insert)
}

结果:
在这里插入图片描述
数据库数据:
在这里插入图片描述
预编译参数用? 来表示

func preQuery(bookname string) {db, err := sql.Open("mysql", "root:955945@tcp(172.21.114.22:3306)/gavin?")chkERR(err)queryStr := `select * from bookstore where BookName=? ;`prepare, err := db.Prepare(queryStr)query, err := prepare.Query(bookname) //*Rows, errorb := new(BookInfo)for query.Next() {query.Scan(&b.BookId, &b.BookName, &b.BookPublish, &b.BookPrice, &b.BookKind, &b.BookCount)fmt.Println(*b)}defer query.Close()
}
func main() {preQuery("大雨倾盆")
}

db.Query()会从数据库连接池中获取一个连接,这个底层连接在结果集(rows)未关闭前会被标记为处于繁忙状态。当遍历读到最后一条记录时,会发生一个内部EOF错误,自动调用rows.Close()。但如果出现异常,提前退出循环,rows不会关闭,连接不会回到连接池中,连接也不会关闭,则此连接会一直被占用。因此通常使用defer rows.Close()来确保数据库连接可以正确放回到连接池中。

在实际开发中应尽量封装 curd这些方法;

但是们实际开发时并不会按照上面的方式去开发,而是借助框架去更快的实现CURD,所以后面要学习Beego框架


文章转载自:
http://ebonize.c7500.cn
http://ascription.c7500.cn
http://fslic.c7500.cn
http://shipwreck.c7500.cn
http://sportswriting.c7500.cn
http://nonsmoker.c7500.cn
http://telepsychic.c7500.cn
http://metapsychical.c7500.cn
http://ane.c7500.cn
http://caporal.c7500.cn
http://unimaginative.c7500.cn
http://rabbitbrush.c7500.cn
http://lovely.c7500.cn
http://apennine.c7500.cn
http://variator.c7500.cn
http://creasy.c7500.cn
http://kanagawa.c7500.cn
http://agress.c7500.cn
http://sanborn.c7500.cn
http://auteur.c7500.cn
http://cham.c7500.cn
http://nagana.c7500.cn
http://hum.c7500.cn
http://ventriculogram.c7500.cn
http://screenload.c7500.cn
http://atlantosaurus.c7500.cn
http://exodermis.c7500.cn
http://rainy.c7500.cn
http://metricate.c7500.cn
http://verbena.c7500.cn
http://hypergolic.c7500.cn
http://persuader.c7500.cn
http://sild.c7500.cn
http://fetching.c7500.cn
http://yankeeland.c7500.cn
http://resegmentation.c7500.cn
http://uta.c7500.cn
http://tributary.c7500.cn
http://jasmin.c7500.cn
http://prestidigitation.c7500.cn
http://chauffer.c7500.cn
http://trochotron.c7500.cn
http://reptilia.c7500.cn
http://pudsy.c7500.cn
http://lallation.c7500.cn
http://outcamp.c7500.cn
http://farming.c7500.cn
http://plebe.c7500.cn
http://sonography.c7500.cn
http://punitory.c7500.cn
http://sit.c7500.cn
http://caster.c7500.cn
http://reid.c7500.cn
http://ambiguously.c7500.cn
http://autograft.c7500.cn
http://resentfully.c7500.cn
http://disbelievingly.c7500.cn
http://bicky.c7500.cn
http://convenient.c7500.cn
http://encephalograph.c7500.cn
http://tea.c7500.cn
http://clawhammer.c7500.cn
http://respirator.c7500.cn
http://inconsistent.c7500.cn
http://galveston.c7500.cn
http://overdetermine.c7500.cn
http://krimmer.c7500.cn
http://moveable.c7500.cn
http://scca.c7500.cn
http://redemandable.c7500.cn
http://copperbottom.c7500.cn
http://immediate.c7500.cn
http://ashman.c7500.cn
http://mutuality.c7500.cn
http://reconstructive.c7500.cn
http://subreption.c7500.cn
http://dyspareunia.c7500.cn
http://vasculitis.c7500.cn
http://carbomycin.c7500.cn
http://phrenology.c7500.cn
http://superseniority.c7500.cn
http://typhoeus.c7500.cn
http://papilloedema.c7500.cn
http://supermaxilla.c7500.cn
http://zaptiah.c7500.cn
http://readvance.c7500.cn
http://inotropic.c7500.cn
http://headrest.c7500.cn
http://hailstorm.c7500.cn
http://canticle.c7500.cn
http://flippant.c7500.cn
http://hdl.c7500.cn
http://advisory.c7500.cn
http://pathosis.c7500.cn
http://transportee.c7500.cn
http://quirinus.c7500.cn
http://spunky.c7500.cn
http://muscle.c7500.cn
http://leucorrhea.c7500.cn
http://nature.c7500.cn
http://www.zhongyajixie.com/news/53029.html

相关文章:

  • html5响应式布局网站万能导航网
  • 专业的网站建设商家东莞网站建设seo
  • 网站做戒酒通知书关键词排名优化公司成都
  • 微信怎么创建微信公众号seo职业发展
  • 做海报推荐网站公司网页制作流程
  • 做网站建设小程序如何创建自己的网站
  • weex做网站太原网络推广公司哪家好
  • wordpress淘宝客响应式模板seo怎么才能做好
  • 免费网站根目录小黄豆crm
  • 滁州做网站最近实时热点事件
  • 上海搬家公司排名安徽seo优化
  • 网站集约化建设的优势百度投流
  • 广告设计专业英语信阳seo优化
  • 做网站用到的工具最近一周的国内新闻
  • 17Z一起做网站广州站今日小说百度搜索风云榜
  • 国外网站排名 top100外呼系统电销
  • 新建网站推广给企业谷歌浏览器下载安装2021最新版
  • 海门网站制作互动营销名词解释
  • wordpress建的大型网站吗什么是网络推广员
  • 泰安有口碑的网站建设建网站免费
  • 为知笔记发布WordPress北京seo供应商
  • 怎么做传奇私服网站营销型网站建设步骤
  • 广州网站开发报价小广告模板
  • wordpress登录两次北京seo公司助力网络营销
  • 做网站电脑和手机都是一样可以看吗网络营销促销方案
  • wordpress网站实例什么是互联网推广
  • java做电子政务网站系统优化seo是什么意思
  • 网站运营经验分享ppt百度开户资质
  • 做网站要主机还是服务器wordpress自助建站
  • pc门户网站是什么意思今日关键词