`
wuhuizhong
  • 浏览: 684203 次
  • 性别: Icon_minigender_1
  • 来自: 中山
社区版块
存档分类
最新评论

rails查询

    博客分类:
  • ROR
阅读更多

教程原文http://guides.rubyonrails.org/active_record_querying.html

 

1、获取数据
.获取第一条、最后一条记录

Model.first
Model.first(options)
Model.find(:first, options)

Model.last
Model.last(options)
Model.find(:last, options)

 .通过id获取记录

Model.find(1, 10, options)
Model.find([1, 10], options)

 .find all

Model.all(options)

 .对一组数据进行相同操作

User.all.each do |user|
	NewsLetter.weekly_deliver(user)
end

 如果表记录数比较大,这种方式比较耗资源,因为它会一次载入整个表的数据。改用以下这种方式,它每次只载入1000行,然后逐步yield完整个表

User.find_each do |user|
	NewsLetter.weekly_deliver(user)
end

 自定义方式,find_each接受和find同样的options

User.find_each(:batch_size => 5000, :start => 2000) do |user|
	NewsLetter.weekly_deliver(user)
end

 find_in_batches,和find_each相似,但它yield时传递的是model对象数组,而不是单个model对象

Invoice.find_in_batches(:include => :invoice_lines) do |invoices|
	export.add_invoices(invoices)
end

 

2、查询条件
通过替换?来传递条件值,可避免SQL注入

Client.first(:conditions => ["orders_count = ?", params[:orders])

 

symbol占位条件

Client.all(:conditions => ["created_at >= :start_date AND created_at <= :end_date", {:start_date => params[:start_date], :end_date => params[:end_date] }])

Hash条件

Client.all(:conditions => {:locked => true }) 

有时候为了拼接方便,可以使用hash

 Post.find_by_sql ["SELECT title FROM posts WHERE author = :Author AND created > :Created", {:Author=>"test", :Created=>"test"}]  
   
# Or  
sql = "SELECT title FROM posts WHERE author = :Author AND created > :Created"  
value = Hash.new  
value[:Author] = "test"  
value[:Created] = "test"  
Post.find_by_sql [sql,value]  

带范围条件

Client.all(:conditons => {:created => (Time.now.midnight - 1.day)..Time.now.midnight})

生成sql

SELECT * FROM clients WHERE (clients.created_at BETWEEN '2008-12-21 00:00:00' AND '2008-12-22 00:00:00')

 

范围条件 in(集合)

Client.all(:conditions => ["created_at IN (?)", (params[:start_date].to_date)..(params[:end_date].to_date])

 

生成sql

SELECT * FROM users WHERE (created_at IN ('2007-12-31','2008-01-01','2008-01-02','2008-01-03','2008-01-04','2008-01-05', '2008-01-06','2008-01-07','2008-01-08'))

 如果要生成日期时间,再加上.to_time
params[:start_date].to_date.to_time,生成2007-12-01 00:00:00格式
有上数据库会在以上条件中报错,如Mysql会报查询语句过长的错误,此时可以改成created_at > ? AND created_at < ?的形式

 

集合条件

Client.all(:conditons => {:orders_count => [1,3,5])

生成sql

SELECT * FROM clients WHERE (clients.orders_count IN (1,3,5)) 

 

 

3、查询选项

排序

#单个排序
Client.all(:order => "created_at ASC")
#多个排序
Client.all(:order => "orders_count ASC, created_at DESC")

 

返回指定字段

Client.all(:select => "viewable_by, locked")
#使用函数
Client.all(:select => "DISTINCT(name)")

 

限定和偏移Limit and Offset

Client.all(:limit => 5)
#生成
SELECT * FROM clients LIMIT 5
Client.all(:limit => 5, :offset => 5)
#生成
SELECT * FROM clients LIMIT 5, 5

 

Group分组

Order.all(:group => "date(created_at)", :order => "created_at")

生成sql

SELECT * FROM orders GROUP BY date(created_at)

 

Having

Order.all(:group => "date(created_at)", :having => ["created_at > ?", 1.month.ago)

生成sql

SELECT * FROM orders GROUP BY date(created_at) HAVING created_at > '2009-01-15' 

 

只读

client = Client.first(:readonly => true)
client.locked = false
client.save
#对只读对象进行保存将会触发ActiveRecord::ReadOnlyRecord异常

 

更新时锁定记录
乐观锁Optimistic Locking
为使用乐观锁,须在表里建一个lock_version的字段,每次更新记录时,ActiveRecord自动递增lock_version的值,

c1 = Client.find(1) c2 = Client.find(1) c1.name = "Michael" c1.save c2.name = "should fail" c2.save # Raises a ActiveRecord::StaleObjectError 

 

备注:You must ensure that your database schema defaults the lock_version column to 0.
This behavior can be turned off by setting ActiveRecord::Base.lock_optimistically = false.
指定乐观锁字段名

class Client < ActiveRecord::Base set_locking_column :lock_client_column end 

 

悲观锁Pessimistic Locking
悲观锁定由数据库直接提供

Item.transaction do 
	i = Item.first(:lock => true)
	i.name = 'Jones'
	i.save
end

 

Mysql执行返回

SQL (0.2ms) BEGIN Item Load (0.3ms) SELECT * FROM `items` LIMIT 1 FOR UPDATE Item Update (0.4ms) UPDATE `items` SET `updated_at` = '2009-02-07 18:05:56', `name` = 'Jones' WHERE `id` = 1 SQL (0.8ms) COMMIT 

为特定数据库加入原始的lock声明
为Mysql的锁定声明为共享模式,即锁定时仍然可读 

Item.transaction do  i = Item.find(1, :lock => "LOCK IN SHARE MODE")  i.increment!(:views) end 
 

4、关联表

Client.all(:joins => "LEFT OUTER JOIN address ON addresses.client_id = clients.id')

生成sql 

SELECT clients.* FROM clients LEFT OUTER JOIN addresses ON addresses.client_id = clients.id 

 

使用Array、Hash、Named Associations关联表
有如下model

class Category < ActiveRecord::Base 
	has_many :posts 
end 
class Post < ActiveRecord::Base 
	belongs_to :category  
	has_many :comments  	
	has_many :tags 
end 
class Comments <ActiveRecord::Base 
	belongs_to :post  
	has_one :guest 
end 
class Guest < ActiveRecord::Base 
	belongs_to :comment 
end 
 
#关联一个关系
Category.all :joins => :posts
#关联多个关系
Post.all :joins => [:category, :comments] 
#嵌套关联
Category.all :joins => {:posts => [{:comments => :guest}, :tags]} 
 

为关联查询结果设定条件

time_range = (Time.now.midnight - 1.day)..Time.now.midnight 
Client.all :joins => :orders, :conditions => {'orders.created_at' => time_ran
#或者
time_range = (Time.now.midnight - 1.day)..Time.now.midnight 
Client.all :joins => :orders, :conditions => {:orders => {:created_at => time_range}} 
 

5、优化载入

以下代码,需要执行1 + 10次sql

clients = Client.all(:limit => 10) clients.each do |client| 
	puts client.address.postcode 
end 
 

优化:

clients = Client.all(:include => :address, :limit => 10) 
clients.each do |client| 
	puts client.address.postcode 
end 
 

一次性载入post的所有分类和评论

Post.all :include => [:category, :comments] 

 

载入category为1的所有post和cooment及tag

Category.find 1, :include => {:posts => [{:comments => :guest}, :tags]} 

 

6、动态查询

Client.find_by_name("Ryan")
Client.find_all_by_name("Ryan")

#!方法,没有记录时抛出ActiveRecord::RecordNotFound异常
Client.find_by_name!("Ryan")

#查询多个字段
Client.find_by_name_and_locked("Ryan", true)

#查询不到时就创建并保存
Client.find_or_create_by_name(params[:name])
#查询不到时创建一个实例,但不保存
Client.find_or_initialize_by_name('Ryan')
 

7、find_by_sql

Client.find_by_sql("SELECT * FROM clients INNER JOIN orders ON clients.id = orders.client_id ORDER clients.created_at desc") 
 

8、select_all
和find_by_sql类似,但不会用model实例化返回记录,你会得到一个hash数组

Client.connection.select_all("SELECT * FROM clients WHERE id = '1'") 

 

9、判断记录是否存在

#通过id来查询
Client.exists?(1)

Client.exists?(1, 2, 3)
#or
Client.exists?([1,2,3])

#通过其他条件来查询
Client.exists?(:conditions => "first_name = 'Ryan'")

#没有参数时,则:表是空的 ? false : true
Client.exists?
 

10、计算

#求结果集条数
Client.count(:conditons => "first_name = 'Ryan'")

#求某个字段非空白的条数
Client.count(:age)

#平均值
Client.average("orders_count")

#求最小值
Client.minimum("age")

#求最大值
Client.maximum("age")

#求和
Client.sum("orders_count")
 

 

 

 

 

 

 

 

 

分享到:
评论

相关推荐

    rails查询学习笔记

    标题 "rails查询学习笔记" 涉及的是Ruby on Rails框架中的数据库查询技术。Ruby on Rails,简称Rails,是一款基于Ruby语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,使得开发Web应用更加高效...

    Rails3的ActiveRecord 查询API.doc

    Rails 3.1 及以后版本的 ActiveRecord 查询API发生了重大变化,主要目的是为了提供更清晰、更可维护的代码,并且提高性能。在 Rails 2.x 中,许多使用哈希参数的查询方法如 `:conditions`, `:include`, `:joins` 等...

    Ruby on Rails Guides v2 - Ruby on Rails 4.2.5

    ### Ruby on Rails Guides v2 - Ruby on Rails 4.2.5 #### 一、重要概念及基础假设 - **重要概念**:本指南旨在帮助读者深入理解Ruby on Rails(以下简称Rails)4.2.5版本的核心功能与最佳实践。 - **基础假设**:...

    rails2.3.2

    在这一版本中,Active Record 提供了更强大的查询接口,包括 SQL 方法的集成和更灵活的关系管理。 2. Action Pack:包含了 MVC 架构中的 Controller 和 View 部分。Controller 处理 HTTP 请求并调用 Model,View ...

    Rails进行敏捷Web开发(所有版本的源码rails3.0-4.0)

    在“Rails进行敏捷Web开发(所有版本的源码rails3.0-4.0)”中,包含了Rails从3.0到4.0各个主要版本的源代码,这些版本的变迁反映了Rails框架在不同阶段的发展和改进。 1. Rails 3.0: Rails 3是重大升级,引入了...

    Ruby on Rails入门例子

    - **ActiveRecord查询接口(Query Interface)**:ActiveRecord提供了丰富的查询API,如`User.find(1)`, `Post.where(title: 'Hello')`,用于从数据库检索数据。 - ** erb语法**:在视图文件中,我们可以使用erb...

    Rails 3 in Action

    《Rails 3 in Action》是2011年由Ryan Bigg撰写的一本关于Ruby on Rails框架的权威指南,专门针对当时最新的Rails 3.1版本进行了深入解析。这本书旨在帮助开发者充分利用Rails 3.1的强大功能,提升Web应用开发的效率...

    rails向导打包

    1. **Active Record 查询接口**: Active Record 是 Rails 的核心组件之一,它负责模型和数据库之间的交互。这个文件详细介绍了如何在 Rails 中使用查询语言来检索、过滤和操作数据。这包括基本的查找方法(如 `find`...

    Rails3常用命令行命令

    在控制台中,你可以直接操作应用的数据模型和执行各种Ruby代码,进行数据查询和调试。 为了启动Rails应用的服务,你可以运行: ```bash rails server -p *** ``` 这里的`***`代表你想让服务器监听的端口号。默认...

    RAILS2.1的中文版资料

    Rails 2.1增强了命名范围查询的功能,使其更加灵活且易于使用。 **基于UTC的迁移(UTC-based migrations)** 为了确保数据的一致性和准确性,Rails 2.1现在支持基于协调世界时(UTC)的数据库迁移。这种改进有助于...

    Advanced Rails

    **高级Rails** Rails,全称为Ruby on Rails,是一款基于Ruby编程语言的开源Web应用程序框架,以其MVC(模型-视图-控制器)架构模式而闻名。"Advanced Rails" 涵盖了Rails开发中的高级主题和技术,是Ruby on Rails...

    好用的rails 2.0 Api 文档

    Rails 2.0提供了ActiveRecord查询接口(Query Interface),允许开发者编写复杂的数据库查询。包括find、where、all、exists?等方法,可以进行条件筛选、分组、联接、排序等操作。 **8. Plugins和Gemfile** Rails ...

    rails4.0.0

    Rails 4.0.0中的Active Record进行了优化,提升了查询性能。引入了`find_by`和`find_or_create_by`等简洁的方法,使得数据库操作更加方便。同时,`update_all`和`destroy_all`方法现在可以直接接收SQL片段,提供了...

    Rails 指南

    本文介绍如何开始使用Ruby on Rails,读完本文后,您将学到: 如何安装Rails,创建Rails应用,如何连接数据库; Rails应用的基本文件结构; MVC(模型,视图,控制器)和REST架构的基本原理; 如何快速生成Rails应用...

    ruby on rails 开发环境包(ruby1.8.7,rails2.2.3)

    这些包括ActiveRecord的查询接口增强,使得SQL查询更加简洁;ActionMailer的改进,便于发送邮件;以及支持部分渲染,提高了视图层的性能。此外,2.2.x版本还增强了路由系统,引入了资源路由和命名空间,使得路由配置...

    Ruby+for+Rails

    每个模型类对应数据库表,实例方法对应SQL查询。例如,`Book.find_by(title: '某书名')`会查找标题为指定值的书籍。 9. ** erb模板** ERB(Embedded Ruby)是Rails视图中常用的模板引擎,可以插入Ruby代码到HTML中...

    配置高可用的rails

    优化rails应用的响应时间可以从数据库查询优化、视图渲染优化、静态资源服务优化等多方面着手。 - Web框架基准测试:了解不同Web框架的性能基准,可以帮助我们选择合适的工具和优化手段。基准测试能够提供不同框架...

    RailsSpace

    这部分内容涉及全文搜索的技术实现以及高效的查询优化策略。 ##### 5.4 头像上传功能 第十二章“Avatars”专门讨论了如何实现头像上传功能。这不仅涉及图片的上传和存储,还需要考虑到图片裁剪和缩放等图像处理...

    rails for zombies

    Rails 提供了多种方法来查询数据库: - **根据 ID 查询单个记录**: ```ruby t = Tweet.find(3) ``` - **查询多个记录**: ```ruby # 返回指定 ID 的记录数组 tweets = Tweet.find([3, 4, 5]) # 返回所有...

Global site tag (gtag.js) - Google Analytics