Ruby怎么使用Mysql2连接操作MySQL

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,如果连接已断开但已启用auto-reconnect,则ping()会尝试依次reconnect,连接成功则返回true,否则报错。如果连接已断开,且未启用auto-reconnect,则报错。

query()查询和结果处理

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

查询结果可使用each进行迭代,迭代时传递查询到的每一行记录,可使用hash索引的方式(默认以hash类型保存每一行)查询某个字段的内容:

conn.query("show databases").each do |row| pp row end=begin{"Database"=>"information_schema"}{"Database"=>"mysql"}{"Database"=>"mytest"}{"Database"=>"performance_schema"}{"Database"=>"sys"}=endconn.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

可见,查询结果中,每一行数据默认以hash格式保存。

实际上,对于增删改的SQL语句,query()的返回值为nil,对于查询类的语句,其返回值以Mysql2::Result对象返回

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

结果:

#: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=>:array)还是hash方式(:as=>:hash)存储查询结果

:symbolize_keys表示返回hash结果时,其key是否设置为符号类型,默认为false,即key是字符串类型

可在查询时指定这些参数,也可在each迭代时指定这些参数,例如:

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

结果:

{: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()默认的查询选项可以通过Mysql2::Client.default_query_options获取,它是一个hash结果:

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=>:array)还是hash方式(:as=>:hash)存储查询结果

:symbolize_keys表示返回hash结果时,其key是否设置为符号类型,默认为false,即key是字符串类型

:async表示查询是否异步模式,即是否非阻塞的查询,参考https://github.com/brianmario/mysql2#async

:cast指示MySQL的查询结果转换为Ruby数据时是否进行类型转换,如果确定本次查询的字段类型和Ruby的类型完全对应,可禁用casting功能提升效率

:database_timezone指示Ruby接收MySQL返回的日期时间数据时的时区,mysql2将先以该时区创建日期时间对象来保存对应字段的值。仅支持:local:utc两个值

:application_timezone指示最终Mysql2::Result中的日期时间的时区,即程序端的时区。因此,mysql2先以”无损”的时区从MySQL获取日期时间数据,并根据application_timezone将其转换成程序端时区的日期时间对象

九歌 九歌

九歌–人工智能诗歌写作系统

九歌 322 查看详情 九歌

:cache_rows指示是否缓存构建出来的hash行或array行

Mysql2处理查询结果的流程:

Mysql2的MySQL C api从MySQL服务端查询数据,并保存在Ruby的查询结果集(结果集属于C)

Mysql2::Result和C端结果集是关联的,当释放Mysql2::Result,也会对C结果集进行GC

Mysql2在需要取得结果集中的数据时(比如each迭代),才从结果集中根据查询选项构建所需行并返回,比如构建hash结构的行,构建数组结构的行,构建hash结构时将key转换为Symbol类型等

默认情况下,从结果集中查询并构建出来的hash行或array行会缓存在Ruby中,使得下次再次请求这一行时(比如再次迭代),可用直接从缓存中取得hash行或array行

比如从MySQL服务端查询了100行数据保存在C的结果集中,第一次以hash方式请求其中4行,这4行hash数据会缓存起来,如果下次再从头开始以hash方式请求15行,则前4行来自于缓存,后11行来自于结果集的临时构建

如果:cache_rows未禁用,当结果集中的所有行都被缓存,Mysql2::Result将会去释放C端的结果集

如果能确保查询的结果集只使用一次,可禁用:cache_rows,这会提升效率

:stream: true表示以Stream的方式处理查询结果。有时候查询结果数据量非常大,Ruby端不方便存放所有结果,可采用stream的方式去处理本次查询:一边从MySQL服务端取数据放进结果集,一边从结果集中取数据进行处理(比如迭代)。使用stream时,会自动关闭cache_rows,因为它们是互相冲突的概念。此外,使用stream模式要求必须迭代完所有数据集才会执行下一条查询,因为一个mysql连接在某一时刻只能执行一个操作,在迭代完之前,本次查询操作还尚未完成。

修改Mysql2::Client.default_query_options可以设置默认query()的查询选项。如果想要设置其中某选项,可以通过hash合并的方式来设置该选项。

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结果对象。

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时必须指定一个flag:

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_resultres = conn.store_resultres.first #=> {"2"=>2}conn.next_resultres = conn.store_resultres.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_resultend# 或者p res.firstwhile conn.next_result  res = conn.store_result  p res.firstend

输出结果:

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

需注意,开启多行语句(即多结果集)功能后,所查询得到的所有结果集必须已经处理完成(严格来说,是存放结果集的队列已经为空),才能继续执行后续的SQL语句(事实上,经测试,结果集队列未空的情况下执行其它SQL语句会导致直接断开mysql连接)。可使用abandon_results!()方法强行丢弃所有剩余结果集,使得Mysql2马上回归正常状态:可向MySQL服务端发送SQL语句。

# 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_resultend

结果:

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

Mysql2的EventMachine

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

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}"  endend

ORM之:Sequel

Active:Record应该是最为人熟知的orm,其功能极其丰富。

另一个轻量级的ORM是Sequel,它支持ADO, JDBC, MySQL, Mysql2, 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 rowend# 条件查询pp dataset.where(name: 'junmajinlong', age: 23).firstpp dataset.where { name =~ "junmajinlong" and age =~ 23 }.first

以上就是Ruby怎么使用Mysql2连接操作MySQL的详细内容,更多请关注创想鸟其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 chuangxiangniao@163.com 举报,一经查实,本站将立刻删除。
发布者:程序猿,转转请注明出处:https://www.chuangxiangniao.com/p/1029280.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2025年12月2日 03:01:12
下一篇 2025年12月2日 03:01:33

相关推荐

  • 网络进化!

    Web 应用程序从静态网站到动态网页的演变是由对更具交互性、用户友好性和功能丰富的 Web 体验的需求推动的。以下是这种范式转变的概述: 1. 静态网站(1990 年代) 定义:静态网站由用 HTML 编写的固定内容组成。每个页面都是预先构建并存储在服务器上,并且向每个用户传递相同的内容。技术:HT…

    2025年12月24日
    000
  • 为什么多年的经验让我选择全栈而不是平均栈

    在全栈和平均栈开发方面工作了 6 年多,我可以告诉您,虽然这两种方法都是流行且有效的方法,但它们满足不同的需求,并且有自己的优点和缺点。这两个堆栈都可以帮助您创建 Web 应用程序,但它们的实现方式却截然不同。如果您在两者之间难以选择,我希望我在两者之间的经验能给您一些有用的见解。 在这篇文章中,我…

    2025年12月24日
    000
  • CSS如何实现任意角度的扇形(代码示例)

    本篇文章给大家带来的内容是关于CSS如何实现任意角度的扇形(代码示例),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。 扇形制作原理,底部一个纯色原形,里面2个相同颜色的半圆,可以是白色,内部半圆按一定角度变化,就可以产生出扇形效果 扇形绘制 .shanxing{ position:…

    2025年12月24日
    000
  • html中怎么运行sql语句_html中运行sql语句方法【教程】

    必须通过后端服务执行SQL操作。一、PHP与MySQL交互:使用PHP脚本在服务器端连接数据库,执行查询并嵌入HTML输出,避免硬编码凭证。二、Ajax调用API:前端通过JavaScript向后端API发送请求,服务端执行SQL并返回JSON数据,前端动态渲染结果。三、SQLite与JavaScr…

    2025年12月23日
    000
  • html手机怎么运行_手机运行html方法【教程】

    1、使用手机浏览器可直接打开本地HTML文件,只需通过文件管理器点击文件并选择浏览器打开即可预览;2、借助Spck Editor等专用编辑器应用能实现实时编辑与预览,适合开发调试;3、对于含JavaScript或需服务器支持的动态内容,应安装KSWEB类应用搭建本地服务器,再通过http://loc…

    2025年12月23日
    000
  • html如何连接_连接HTML与数据库或API接口【接口】

    HTML无法直接连接数据库或调用API,需借助JavaScript fetch、PHP中转、Node.js后端或Python Flask等服务端技术实现动态数据交互。 如果您希望在网页中动态获取数据,HTML本身无法直接连接数据库或调用API接口,必须借助服务器端语言或JavaScript等客户端技…

    2025年12月23日
    000
  • HTML如何添加批注功能_评论系统实现方案【教程】

    可实现HTML文本批注功能的四种方案:一、基于HTML5自定义属性与JS的静态批注;二、遵循W3C标准的语义化批注;三、嵌入Utterances或Giscus等第三方评论系统;四、自建AJAX评论后端+前端组件。 如果您希望在HTML页面中为特定文本添加可交互的批注功能,或构建一个轻量级的评论系统,…

    2025年12月23日
    000
  • html怎么在本地服务器运行_本地服务器运html方法【指南】

    使用本地服务器运行HTML文件需通过HTTP协议,可选Python命令启动服务、Node.js的http-server、VS Code的Live Server插件或XAMPP等工具,确保AJAX等功能正常。 要在本地服务器运行HTML文件,不能直接双击打开,因为部分功能(如AJAX、API调用)需要…

    2025年12月23日
    200
  • phpstudy怎么运行本地html_phpstudy运行本地html方法【教程】

    确保Apache或Nginx服务已启动;2. 将HTML文件放入WWW目录;3. 浏览器访问localhost即可运行页面。 在使用 PHPStudy 时,运行本地 HTML 文件非常简单。PHPStudy 是一个集成了 Apache/Nginx、PHP 和 MySQL 的集成环境工具,主要用于本地…

    2025年12月23日
    000
  • HTML页面如何生成短链接_URL压缩转换方法【攻略】

    可借助第三方服务、API调用、Nginx反向代理、PHP脚本或GitHub Pages五种方式将HTML页面URL转为短链接:1.用bit.ly等平台手动缩短;2.调用Bitly API批量生成;3.配置Nginx rewrite规则重定向;4.部署PHP+MySQL实现动态跳转;5.利用GitHu…

    2025年12月23日
    000
  • Java JDBC中SQL INSERT语句的常见语法错误及修复指南

    本文旨在解决java jdbc应用中常见的sql `insert`语句语法错误,特别是因缺少括号而导致的错误。我们将深入分析错误信息,指出问题根源,并提供正确的sql语句范例及java jdbc `preparedstatement`的使用方法。文章还将涵盖jdbc数据库操作的最佳实践、错误处理和调…

    2025年12月23日
    000
  • wampserver怎么运行html程序_wampserver运行html程序方法【教程】

    使用WampServer运行HTML程序需将文件放入www目录,启动Apache服务后通过http://localhost/项目路径访问,确保在本地服务器环境下正确解析运行。 如果您在本地开发网页,但无法正确查看HTML文件的运行效果,可能是由于未通过本地服务器环境进行访问。WampServer 提…

    2025年12月23日
    000
  • 平板怎么运行html代码_平板运行html代码步骤【指南】

    可在平板上通过四种方式查看HTML效果:一、用浏览器直接打开本地.html文件;二、使用JSFiddle等在线编辑器实时预览;三、安装Acode等编程应用离线编写并预览;四、通过KSWEB搭建本地服务器运行含动态内容的页面。 如果您希望在平板设备上查看或测试HTML代码的效果,但不确定如何操作,则可…

    2025年12月23日
    000
  • html上怎么运行php代码吗_html中运行php代码方法【教程】

    要使PHP代码在HTML中执行,必须通过支持PHP的服务器环境。首先将文件保存为.php格式并部署到配置好PHP模块的服务器(如Apache)根目录,通过http://localhost访问;或修改服务器配置(如.htaccess)令.html文件解析PHP;推荐使用.php文件混合HTML与PHP…

    2025年12月23日
    000
  • html怎么用sublime运行php_sublime运行html中php方法【教程】

    可在Sublime Text中通过配置PHP环境变量并创建Build System运行PHP代码,或使用PHP内置服务器、XAMPP等集成环境结合浏览器预览实现解析与调试。 如果您在使用Sublime Text编辑HTML或PHP文件时,希望直接运行PHP代码并查看输出结果,但发现无法像在浏览器中那…

    2025年12月23日
    000
  • PHP表单提交后防止页面刷新并保留数据与错误提示的教程

    本教程旨在解决php表单提交时页面刷新、用户输入数据丢失以及错误提示显示不佳的问题。核心方法是利用服务器端php的`$_post`变量,在表单提交并进行服务器端验证失败后,不进行页面重定向,而是直接在当前页面重新渲染表单,同时回填用户之前输入的数据并显示验证错误信息,从而显著提升用户体验。 引言:优…

    2025年12月23日
    000
  • 如何通过JavaScript/jQuery获取HTML元素内容并与PHP后端交互

    本教程详细阐述了如何利用JavaScript和jQuery从HTML页面中动态获取特定` `标签的文本内容,并进一步探讨了如何将这些前端捕获的数据通过AJAX技术安全地传递给PHP后端进行处理,例如执行SQL查询。文章涵盖了从前端事件触发、数据捕获到后端数据接收、处理及安全防护的全流程,旨在提供一个…

    2025年12月23日
    000
  • php怎么在html5中运行_php在html5中运行方法【教程】

    PHP在服务器端运行,通过嵌入HTML5文件生成动态内容。1. PHP与HTML5协同工作:PHP代码嵌入.html或.php文件,由服务器解析后输出纯HTML至浏览器。2. 创建index.php文件,使用标准HTML5结构,在其中插入等PHP代码,实现动态内容展示。3. 搭建本地环境可选用XAM…

    2025年12月23日 好文分享
    000
  • epp4怎么运行html文件_EPP4运行html文件步骤【指南】

    首先确认EPP4已安装并启动Apache服务,将HTML文件放入www目录后,通过http://localhost/路径访问即可预览页面,确保文件位置与路径正确。 打开EPP4后运行HTML文件并不复杂,只需正确操作即可在浏览器中预览页面效果。EPP4(Easy PHP Pack 4)是一个集成开发…

    2025年12月23日
    000
  • html怎么用浏览器运行php_浏览器运html中php文件方法【教程】

    正确答案是搭建本地开发环境。需安装XAMPP等集成工具,将.php文件放入htdocs目录,通过http://localhost访问,确保服务器解析PHP并返回HTML给浏览器显示。 PHP 是服务器端语言,不能直接通过浏览器像 HTML 那样双击打开运行。你看到的“在浏览器中运行 PHP”其实是指…

    2025年12月23日
    000

发表回复

登录后才能评论
关注微信