首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

ActiveRecord CRUD 操作完全指南:創建、讀取、更新、刪除的核心 API 與進階技巧

     編輯:Java 相關知識

創建與保存

多種創建方式

# 1. new + 屬性賦值 + save
order = Order.new
order.name = "virusswb"
order.email = "asdf@example.com"
order.save

# 2. new + 塊語法
Order.new do |o|
  o.name = "virusswb"
  o.email = "asdf@example.com"
  o.save
end

# 3. new + Hash 參數
order = Order.new(name: "virus", email: "adf@example.com")
order.save

# 4. create:創建並保存(推薦)
order = Order.create(name: "virus", email: "adf@example.com")

# 5. 批量創建
orders = Order.create([
  { name: "virus1", email: "111@123.com" },
  { name: "swb2", email: "222@123.com" }
])
# 返回數組,包含所有創建的對象(含 ID)

# 6. 從表單參數直接創建
@order = Order.new(params[:order])
  • 主鍵 id 默認自增整數,無需手動賦值。
  • save 返回 true/false;save! 失敗拋出 RecordInvalid。
  • create 總返回對象(需檢查 errors 判斷成敗);create! 失敗拋異常。

讀取查詢

主鍵查找

# 拋出 RecordNotFound 異常
order = Order.find(27)

# 返回 nil(推薦控制器用)
order = Order.find_by(id: 27)
order = Order.where(id: 27).first

批量主鍵查找

# 任一 ID 不存在拋異常
orders = Order.find([1, 5, 10])

# 安全版本
orders = Order.where(id: [1, 5, 10])

動態查找器

# 單列
Order.find_by_name("virus")
Order.find_all_by_name("virus")
Order.find_last_by_name("virus")

# 多列
Order.find_by_name_and_email("virus", "a@b.com")
Order.find_all_by_name_and_status("virus", "paid")

# 帶異常版本
Order.find_by_name!("virus")  # 不存在拋 RecordNotFound

等價關係:

Order.find_by_name("virus")           == Order.where(name: "virus").first
Order.find_all_by_name("virus")       == Order.where(name: "virus")
Order.find_by_name_and_email(n, e)    == Order.where(name: n, email: e).first

查找或創建/初始化

# 找到返回,否則 new(不保存)
cart = Cart.find_or_initialize_by_user_id(user.id)
cart.items << new_item
cart.save

# 找到返回,否則 create(直接保存)
cart = Cart.find_or_create_by_user_id(user.id)

SQL 與 ActiveRecord 混合查詢

# 參數化查詢(安全)
name = params[:name]
Order.where("name = ?", name)
Order.where("name = :name", name: name)
Order.where(name: params[:name])  # Hash 直接傳入

# LIKE 模糊查詢
User.where("name LIKE ?", params[:name] + "%")

# 選擇特定列
Order.select("name, email").where(name: "virus")

# 排序、分頁
Order.where(name: "virus").order("name, email DESC").limit(10).offset(20)

# 關聯預加載
Order.includes(:line_items).where(name: "virus")

# 連接查詢
LineItem.select("li.quantity")
        .joins("INNER JOIN products pr ON li.product_id = pr.id")
        .where("pr.title = ?", "Programming Ruby")

# 聚合統計
Order.average(:amount)
Order.maximum(:amount)
Order.minimum(:amount)
Order.sum(:amount)
Order.count

# 分組統計
Order.group(:state).maximum(:amount)
# => [["TX", 123456], ["NY", 3456]]

# 唯讀對象(不可保存)
Order.readonly.where(...)
# 使用 joins/select 自動標記 readonly

執行原生 SQL

orders = Order.find_by_sql("SELECT name, pay_type FROM orders")
order = orders.first
order.attributes        # => {"name"=>"shi", "pay_type"=>"check"}
order.attribute_names   # => ["name", "pay_type"]
order.attribute_present?("address") # => false

重新加載數據

# 併發場景:獲取最新數據
loop do
  puts "Price = #{stock.price}"
  sleep 60
  stock.reload
end

更新操作

# 1. 實例修改 + save
order = Order.find(10)
order.name = "swb"
order.save

# 2. 更新單個屬性(繞過驗證)
order.update_attribute(:name, "newname")

# 3. 更新多個屬性(觸發驗證)
order.update_attributes(name: "newname", email: "newmail")
order.update(name: "newname", email: "newmail")  # Rails 4+ 別名

# 4. 類級別更新
Order.update(12, name: "newname", email: "newmail")

# 5. 批量更新(單條 SQL,繞過驗證/回調)
Order.update_all("price = 1.1 * price", "title LIKE '%java%'")
# 返回受影響行數

刪除操作

方法層級觸發回調/驗證返回值異常處理
delete(id)類❌受影響行數不存在不報錯
delete([1,2,3])類❌受影響行數不存在不報錯
delete_all(conditions)類❌受影響行數無匹配返回 0
destroy(id)實例✅ (before_destroy/after_destroy)對象(凍結)不存在拋 RecordNotFound
destroy_all(conditions)類✅對象數組無匹配返回 []

選擇建議

  • 業務關鍵數據:必須用 destroy,確保驗證、回調、關聯級聯刪除(dependent: :destroy)生效。
  • 性能敏感/臨時數據/無關聯:可用 delete/delete_all 直達 SQL。

save 系列方法行為對比表

方法成功返回失敗返回驗證回調
savetruefalse✅✅
save!true拋 RecordInvalid✅✅
create對象對象(含 errors)✅✅
create!對象拋 RecordInvalid✅✅

總結

ActiveRecord CRUD API 設計兼顧了便利性與安全性:

  1. 優先用 create/update/destroy,自動處理驗證與回調。
  2. 查詢用 where 鏈式調用,告別 find_by_sql 除非極其複雜。
  3. 參數化查詢防注入,永不拼接字符串。
  4. 批量操作權衡性能與一致性:update_all/delete_all 跳過回調,謹慎使用。
  5. 併發場景用 reload 或樂觀鎖(lock_version)保證數據新鮮度。

「讓 ActiveRecord 做它擅長的事:將業務語言翻譯為 SQL,而不是手寫 SQL。」

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved