怎么使用连接操作的网络(连接如何)

lxf2023-11-16 06:20:01

Ruby操作MySQL

用mysql2连接mysql,操作mysql。

gem install mysql2

连接mysql

建立连接:

require 'mysql2' conn = Mysql2::Client.new({ host: '192.168.200.73', username: 'root', password: 'P@ssword1!' })

接受的连接选项包括:

Mysql2::Client.new( :host, :username, :password, :port, :database, :socket = '/path/to/mysql.sock', :flags = REMEMBER_OPTIONS | LONG_PASSWORD | LONG_FLAG | TRANSACTIONS | PROTOCOL_41 | SECURE_CONNECTION | MULTI_STATEMENTS, :encoding = 'utf8', :read_timeout = seconds, :write_timeout = seconds, :connect_timeout = seconds, :connect_attrs = {:program_name => $PROGRAM_NAME, ...}, :reconnect = true/false, :local_infile = true/false, :secure_auth = true/false, :ssl_mode = :disabled / :preferred / :required / :verify_ca / :verify_identity, :default_file = '$HOME/.my.cnf', #=> 从文件读取连接信息 :default_group = 'my.cfg section', #=> 选择.my.cnf中的section :default_auth = 'authentication_windows_client', :init_command => SQL_Statement #=>主要用于设置本次连接时的某些变量 )

连接建立后,就可以操作数据库了,比如执行SQL语句:

conn. query('create databse mytest') conn.select_ db( 'mytest' ) # conn.query('use mytest' ) conn. query('create table tb(name varchar(1024),age int)') conn. query <<-SQL insert into tb values ('junmajinlong', 23), ( 'woniu', 25), ('fairy', 26) SQL

如果测试与mysql的连接是否断开,可以ping():

conn.ping

如果连接没有断开,ping()返回true如果连接已断开,但启用了自动重新连接,ping()将依次尝试重新连接,如果连接成功,则返回true,否则报告错误。如果连接断开且未启用自动重新连接,则会报告一个错误。

Query()查询和结果处理

Query()用于执行任何允许的SQL语句,比如执行查询语句。

查询结果可以逐行迭代,迭代过程中可以传递查询记录的每一行,可以使用哈希索引的方式查询一个字段的内容(每一行默认保存为哈希类型):

conn.query("show databases").each do |row| pp row end =begin {"Database"=>"information_schema"} {"Database"=>"mysql"} {"Database"=>"mytest"} {"Database"=>"performance_schema"} {"Database"=>"sys"} =end conn.query("select * from mytest.tb").each do |row| pp row pp row["name"] end =begin {"name"=>"junmajinlong", "age"=>23} "junmajinlong" {"name"=>"woniu", "age"=>25} "woniu" {"name"=>"fairy", "age"=>26} "fairy" =end

可以看到,在查询结果中,每一行数据默认都是以哈希格式保存的。

实际上,对于添加、删除、修改的SQL语句,query()的返回值是nil,对于query类的语句,返回值是Mysql2::Result对象

conn.query("create table mytest.t1(id int)") #=> nil res = conn.query("select * from mytest.tb") p res

结果:

#<Mysql2::Result:0x00007fffe833a230 @query_options= {:as=>:hash, :async=>false, :cast_booleans=>false, :symbolize_keys=>false, :database_timezone=>:local, :application_timezone=>nil, :cache_rows=>true, :connect_flags=>2148540933, :cast=>true, :default_file=>nil, :default_group=>nil, :host=>"192.168.200.73", :username=>"root", :password=>"P@ssword1!"}, @server_flags= {:no_good_index_used=>false, :no_index_used=>true, :query_was_slow=>false}>

query()的查询选项和默认查询选项的含义见下。先了解两个:

  • :as项表示它是数组的形式(:as = & gt:数组)或哈希模式(:as = & gt:hash)存储查询结果。

  • :symbolize_keys表示返回哈希结果时,是否将关键字设置为符号类型,默认值为false,即关键字为字符串类型。

    您可以在查询时或每次迭代时指定这些参数,例如:

    conn.query("select * from mytest.tb", symbolize_keys: true).each do |row| pp row end conn.query("select * from mytest.tb").each(symbolize_keys: true) do |row| pp row end

    结果:

    {:name=>"junmajinlong", :age=>23} {:name=>"woniu", :age=>25} {:name=>"fairy", :age=>26}

    虽然大多数时候用hash保存每一行数据更方便,但是有时候你想用数组的方式操作每一行数据,比如连接每个字段的值:

    sql = 'select * from mytest.tb' res = conn.query(sql) res.each(as: :array) do |row| p row.join(",") end

    结果:

    "junmajinlong,23" "woniu,25" "fairy,26"

    Mysql2::Result本身有几个方法:

    #count ⇒ Object (also: #size) #each(*args) ⇒ Object #fields ⇒ Object #free ⇒ Object

    另外,Mysql2::Result已经mix-in了Enumerable模块,所以可以直接使用这个模块中的方法,比如first就是取第一行记录。

    sql = 'select * from mytest.tb' res = conn.query(sql) res.first #=>{"name"=>"junmajinlong", "age"=>23}

    需要注意的是,SQL语句中涉及到的所有值都不是转义的,有时候在执行之前转义是必要的,也是推荐的。

    escaped = conn.escape("gi'thu\"bbe\0r's") results = conn.query("SELECT * FROM users WHERE group='#{escaped}'")

    查询选项和默认查询选项的含义

    query()的默认查询选项可以通过MySQL 2::client . default _ query _ options获得,它是一个哈希结果:

    Mysql2::Client.default_query_options =begin {:as=>:hash, :async=>false, :cast_booleans=>false, :symbolize_keys=>false, :database_timezone=>:local, :application_timezone=>nil, :cache_rows=>true, :connect_flags=>2148540933, :cast=>true, :default_file=>nil, :default_group=>nil} =end

    其中(重要的):

  • :as项表示它是数组的形式(:as = & gt:数组)或哈希模式(:as = & gt:hash)存储查询结果。

  • :symbolize_keys表示返回哈希结果时,是否将关键字设置为符号类型,默认值为false,即关键字为字符串类型。

    :async指示查询是否是异步的,即它是否是非阻塞查询。参考/d/file/04/eg3brr4g2s413131 C api从MySQL服务器查询数据,保存在Ruby的查询结果集中(结果集属于C)。

    Mysql2::Result与C端结果集相关。Mysql2::Result发布时,C端结果集也会是GC。

    当Mysql2需要获取结果集中的数据时(比如每次迭代),会从结果集中构建所需的行,并根据查询选项返回,比如用hash结构构建行,用array结构构建行,构建hash结构时将key转换成符号类型。

    默认情况下,从结果集查询和构建的散列行或数组行在Ruby中缓存,这样下次再次请求该行时(比如再次迭代),可以直接从缓存中检索散列行或数组行。

    比如从MySQL服务器查询100行数据,存储在c的结果集中,第一次会缓存4行hash数据。如果您再次从头开始请求15行,前4行将来自缓存,后11行将来自结果集的临时构造。

    如果:cache_rows没有禁用,Mysql2::Result会在缓存结果集中的所有行时,在C端释放结果集。

    如果可以确保查询的结果集只使用一次,可以禁用:cache_rows,这样可以提高效率。

    :Stream: true表示以流的方式处理查询结果。有时候查询结果数据太大,Ruby不方便存储所有结果。我们可以用stream的方式处理这个查询:在从MySQL服务器取数据放入结果集的同时,也可以从结果集中取数据进行处理(比如迭代)。使用stream时,cache_rows会自动关闭,因为它们是冲突的概念。另外,使用stream模式要求在执行下一个查询之前必须迭代所有数据集,因为一个mysql连接一次只能执行一个操作,在迭代完成之前这个查询操作还没有完成。

    修改MySQL 2::client . default _ query _ options设置默认查询()的查询选项。如果要设置其中一个选项,可以通过哈希合并来设置该选项。

    Mysql2::Client.default_query_options #=> {:as=>:hash, ...} Mysql2::Client.default_query_options.merge!(:as => :array) #=> {:as=>:array, ...}

    prepare()+execute()

    除了直接使用query()执行SQL语句来查询数据库之外,还可以使用prepare()方法将字符串准备成要执行的SQL语句,其中可以使用?充当占位符。

    prepare之后的语句是一个Mysql2::Statement对象,它有一个execute()方法,可以用来执行准备好的语句。它可以指定查询选项,返回值与query()相同:nil用于添加、删除、修改操作,Mysql2::Result result对象用于查询操作。

    res_sql = conn.prepare('select * from mytest.tb where age >= ? and name like ?') res = res_sql.execute(20, '%junma%', as: :array) res.first

    处理多个结果集

    一些存储过程可能包含多个查询结果集,或者有时一行SQL可能包含多个select语句并同时返回多个结果集。Mysql2可以很好的处理多个结果集的问题。

    要处理多个结果集,您必须在连接到mysql时指定一个标志:

    conn = Mysql2::Client.new({ host: "192.168.200.73", username: "root", password: "P@ssword1!", flags: Mysql2::Client::MULTI_STATEMENTS })

    然后使用多个结果集执行多个查询语句:

    res = conn.query('select 1;select 2;select 3')

    虽然这个query()涉及到多个select语句,但是Mysql2也保存了这三个select的查询结果集(保存在结果集队列中),但是这个query()方法的返回值只是第一个结果集,所以第一个结果集的内容保存在RES中。

    res.first #=> {"1"=>1}

    要获取剩余的结果集,可以通过conn.next_result将结果集偏移量指针移动到下一个结果集,然后通过conn.store_result获取下一个结果集,以此类推,直到没有剩余的结果集,conn.next_result返回false。可以用more_results?()方法确定是否还有剩余的结果集。

    conn.next_result res = conn.store_result res.first #=> {"2"=>2} conn.next_result res = conn.store_result res.first #=> {"3"=>3} conn.next_result #=> false

    因此,可以遍历多个结果集:

    res = conn.query('select 1;select 2;select 3') loop do p res.first break unless conn.next_result res = conn.store_result end # 或者 p res.first while conn.next_result res = conn.store_result p res.first end

    输出结果:

    {"1"=>1} {"2"=>2} {"3"=>3}

    需要注意的是,开启多行语句(即多个结果集)功能后,查询得到的所有结果集必须已经处理完毕(严格来说,存储结果集的队列已经是空)才能继续执行后续的SQL语句(实际上经过测试,在结果集队列不是空的情况下执行其他SQL语句,会导致mysql直接断网)。可以用放弃_结果!()方法强制丢弃所有剩余的结果集,使Mysql2立即恢复正常状态:sql语句可以发送到Mysql服务器。

    # res和res1都只保存第一个结果集 # 但结果集队列中保留的是select 5和select 6的结果集 res = conn.query('select 1;select 2;select 3') conn.abandon_results! # 丢弃所有剩余结果集 res1 = conn.query('select 4;select 5;select 6')

    另外,如果多个查询语句中的一个查询语句报错,会影响后续的语句不被执行,从而无法获得后续的结果集。

    res = conn.query('select 1;select 2;select A;select 3') loop do p res.first break unless conn.next_result res = conn.store_result end

    结果:

    {"1"=>1} {"2"=>2} Mysql2::Error: Unknown column 'A' in 'field list'

    Mysql2的事件机器

    Mysql2支持EM,可以执行异步查询()。此外,它可以在查询()成功或失败时指定回调语句块:

    require 'mysql2/em' EM.run do client1 = Mysql2::EM::Client.new defer1 = client1.query "SELECT sleep(3) as first_query" defer1.callback do |result| puts "Result: #{result.to_a.inspect}" end client2 = Mysql2::EM::Client.new defer2 = client2.query "SELECT sleep(1) second_query" defer2.callback do |result| puts "Result: #{result.to_a.inspect}" end end

    ORM:续集

    主动:记录应该是最知名的orm了,功能极其丰富。

    另一个轻量级ORM是Sequel,支持ADO、JDBC、MySQL、MySQL 2、ODBC、Oracle、PostgreSQL、SQLite3等。

    例如:

    require 'sequel' # 创建数据库实例 DB = Sequel.connect( adapter: :mysql2, user: 'root', password: 'P@ssword1!', host: '192.168.200.73', port: 3306, database: 'mytest' ) # 创建数据集,数据集表示的是一张表或表部分数据 # 此时不会去查询数据,会推迟到需要数据时才查询 dataset = DB[:tb] # 迭代表数据 dataset.each do |row| pp row end # 条件查询 pp dataset.where(name: 'junmajinlong', age: 23).first pp dataset.where { name =~ "junmajinlong" and age =~ 23 }.first

    以上是Ruby如何使用Mysql2 connection操作Mysql的细节。更多详情请关注AdminJS.cn其他相关文章!

    adminjs.cn是一个以CSS、JavaScript、Vue、HTML为核心的前端开发技术网站。我们致力于为广大前端开发者提供专业、全面、实用的前端开发知识和技术支持。 在本网站中,您可以学习到最新的前端开发技术,了解前端开发的最新趋势和最佳实践。我们提供丰富的教程和案例,让您可以快速掌握前端开发的核心技术和流程。 Adminjs.cn还提供一系列实用的工具和插件,帮助您更加高效地进行前端开发工作。我们提供的工具和插件都经过精心设计和优化,可以帮助您节省时间和精力,提升开发效率。 在Adminjs.cn中,您可以找到您需要的一切前端开发资源,让您成为一名更加优秀的前端开发者。欢迎您加入我们的大家庭,一起探索前端开发的无限可能!