zoukankan      html  css  js  c++  java
  • Rails 数据库操作

    数据库元被影射成对象 
    (object-relational mapping (ORM)层) 

    Ruby代码  收藏代码
    1. table<=>class  
    2. row<=>object  
    3. column<=>object attribute  



    class和table的命名对应关系实例: 

    Ruby代码  收藏代码
    1. Order<=>orders  
    2. TaxAgency<=>tax_agencies  
    3. Person<=>people  
    Ruby代码  收藏代码
    1. #复数形式关闭方法config/environment.rb:  
    2. ActiveRecord::Base.pluralize_table_names = false  
    3. #自定义表格名称方法:  
    4. class Sheep < ActiveRecord::Base  
    5. set_table_name "sheep"  
    6. end  



    Ruyb数据类型和SQL数据类型对应关系表: 

    Ruby代码  收藏代码
    1. int,integer<=>Fixnum  
    2. float,double,decimal,numeric<=>Float  
    3. interval,date<=>Date  
    4. datetime,time<=>Time  
    5. char,varchar,string,clob,blob,text<=>String  
    6. boolean<=>see text...  



    访问属性(数据库列): 

    Ruby代码  收藏代码
    1. account[:balance#=> 返回当前值  
    2. account[:balance] = 0.0 #=> 指定数值  



    Ruby代码  收藏代码
    1. #修正数据库列的取值范围的方法:  
    2. class Account < ActiveRecord::Base  
    3. def balance=(value)  
    4.    raise BalanceTooLow if value < MINIMUM_LEVEL  
    5.    self[:balance] = value  
    6. end  
    7. end  



    访问属性(数据库列)更方便的方法: 
    account.balance #=> 返回当前值 
    account.balance = 0.0 #=> 指定数值 

    以上方式得到的数据库数据将是ruby按自身的数据类型格式化好的,如果要得到原始数据,可用以下形式代码: 
    account.balance_before_type_cast #=> "123.4", 字符串 
    account.release_date_before_type_cast #=> "20050301" 

    是非属性 
    在ruby中只有false或nil才被判断为false 
    通常用以下代码判断: 

    Ruby代码  收藏代码
    1. user = Users.find_by_name("Dave")  
    2. if user.superuser?  
    3. grant_privileges  
    4. end  


    superuser?将以下结果判断为false: 
    1.数字0 
    2.字符"0", "f", "false", 或""(空字符) 
    3.nil 
    4.常量false 

    自定义判断原则的方法: 

    Ruby代码  收藏代码
    1. class User < ActiveRecord::Base  
    2. def superuser?  
    3.    self.superuser == 'J'  
    4. end  
    5. # . . .  
    6. end  



    数据库主键(Primary Keys) 
    Ruby on Rails默认以id为主键 

    自定义主键的方法: 
    class BadBook < ActiveRecord::Base 
    set_primary_key "isbn" 
    end 

    数据创建,读取,更新和删除(CRUD:Create, Read, Update, Delete) 

    创建新数据 

    实例: 

    Ruby代码  收藏代码
    1. an_order = Order.new  
    2. an_order.name ="Dave Thomas"  
    3. an_order.email = "dave@pragprog.com"  
    4. an_order.address = "123 Main St"  
    5. an_order.pay_type = "check"  
    6. an_order.save #在save()之前所有数据只存在内存中  



    用以下方式可以减少产生一个an_order变量: 

    Ruby代码  收藏代码
    1. Order.new do |o|  
    2. o.name = "Dave Thomas"  
    3. # . . .  
    4. o.save  
    5. end  



    当数据来自HTML表单时,可以考虑用以下方式: 

    Ruby代码  收藏代码
    1. an_order = Order.new(  
    2. :name =>"Dave Thomas",  
    3. :email =>"dave@pragprog.com",  
    4. :address => "123 Main St",  
    5. :pay_type =>"check")  
    6. an_order.save  



    使用create()代换new()可直接保存到数据库,省去an_order.save: 

    Ruby代码  收藏代码
    1. an_order = Order.create(  
    2. :name => "Dave Thomas",  
    3. :email =>"dave@pragprog.com",  
    4. :address =>"123 Main St",  
    5. :pay_type => "check")  



    可以使用hash同时保存多组数据: 

    Ruby代码  收藏代码
    1. orders = Order.create(  
    2.    [ { :name =>"Dave Thomas",  
    3.      :email => "dave@pragprog.com",  
    4.      :address =>"123 Main St",  
    5.      :pay_type =>"check"  
    6.     },  
    7.     { :name =>"Andy Hunt",  
    8.      :email =>"andy@pragprog.com",  
    9.      :address =>"456 Gentle Drive",  
    10.      :pay_type => "po"  
    11.     } ] )  



    new()或create()也可以直接接参数: 
    order = Order.create(params) 

    读取数据 

    Ruby代码  收藏代码
    1. an_order = Order.find(27) # 直接找出id = 27的数据  
    2. # 从一个表单读取product id列表,然后计算这些商品的总价:  
    3. product_list = params[:product_ids]  
    4. total = 0.0  
    5. Product.find(product_list).each {|prd| total += prd.total}  



    Ruby代码  收藏代码
    1. 带条件的读取:  
    2. pos = Order.find(:all,  
    3. :conditions => "name = 'dave' and pay_type = 'po'")  



    不安全的表单参数传递读取数据库: 

    Ruby代码  收藏代码
    1. name = params[:name]  
    2. # 此方法有被SQL注入方式入侵的风险!!!  
    3. pos = Order.find(:all,  
    4. :conditions =>"name = '#{name}' and pay_type = 'po'")  
    5. #注意上面单双引号的使用及变量的传递方法  


    更安全的方法: 

    Ruby代码  收藏代码
    1. name = params[:name]  
    2. pos = Order.find(:all,  
    3. :conditions => ["name = ? and pay_type = 'po'", name])  



    你也可以这样: 

    Ruby代码  收藏代码
    1. name = params[:name]  
    2. pay_type = params[:pay_type]  
    3. pos = Order.find(:all,  
    4. :conditions => ["name = :name and pay_type = :pay_type",  
    5. {:pay_type => pay_type, :name => name}])  



    终极简化版: 

    Ruby代码  收藏代码
    1. pos = Order.find(:all,  
    2. :conditions => ["name = :name and pay_type = :pay_type", params])  



    排序和查找第3(?)至13(?)列的方法: 

    Ruby代码  收藏代码
    1. orders = Order.find(:all,  
    2. :conditions =>"name = 'Dave'",  
    3. :order =>"pay_type, shipped_at DESC",  
    4. :limit => 10  
    5. :offset => 2)  



    联合数据表的查找方法(一般用不上): 

    Ruby代码  收藏代码
    1. LineItem.find(:all,  
    2. :conditions => "pr.title = 'Programming Ruby'",  
    3. :joins =>"as li inner join products as pr on li.product_id = pr.id")  


    查找有序一列的方法: 

    Ruby代码  收藏代码
    1. order = Order.find( :first,  
    2. :conditions =>"name = 'Dave Thomas'",  
    3. :order => "id DESC")  



    直接使用sql语句的查询方法: 

    Ruby代码  收藏代码
    1. items = LineItem.find_by_sql("select *, quantity*unit_price as total_price,products.title as title from line_items, products where line_items.product_id = products.id ")  
    2. li = items[0]  
    3. puts "#{li.title}: #{li.quantity}x#{li.unit_price} => #{li.total_price}"  
    4. #你可以使用"as".  



    在这里你也可以传递参数: 

    Ruby代码  收藏代码
    1. Order.find_by_sql(["select * from orders where amount > ?",  
    2. params[:amount]])  



    计算行数 

    Ruby代码  收藏代码
    1. c1 = Order.count  
    2. c2 = Order.count(["name = ?""Dave Thomas"])  
    3. c3 = LineItem.count_by_sql("select count(*) from line_items, orders   where line_items.order_id = orders.id and orders.name = 'Dave Thomas' ")  
    4. puts "Dave在#{c2}个定单里一共定了#{c3} 件商品 (目前定单总数:#{c1})"  



    动态查询 

    Ruby代码  收藏代码
    1. order = Order.find_by_name("Dave Thomas")#只查一列  
    2. orders = Order.find_all_by_name("Dave Thomas")  
    3. order = Order.find_all_by_email(params['email'])  



    可同时查多个条件,如: 

    Ruby代码  收藏代码
    1. user = User.find_by_name_and_password(name, pw)  



    重载数据库 

    Ruby代码  收藏代码
    1. stock = Market.find_by_ticker("RUBY")  
    2. loop do  
    3. puts "Price = #{stock.price}"  
    4. sleep 60  
    5. stock.reload  
    6. end  



    更新数据 
    使用save() 

    Ruby代码  收藏代码
    1. order = Order.find(123)  
    2. order.name = "Fred"  
    3. order.save  
    4.   
    5. orders = Order.find_by_sql("select id, name, pay_type from orders where id=123")  
    6. first = orders[0]  
    7. first.name ="Wilma"  
    8. first.save  


    使用update_attribute() 

    Ruby代码  收藏代码
    1. order = Order.find(123)  
    2. order.update_attribute(:name,"Barney")  
    3. order = Order.find(321)  
    4. order.update_attributes(:name => "Barney",  
    5. :email =>"barney@bedrock.com")  



    使用更快捷的update() 

    Ruby代码  收藏代码
    1. order = Order.update(12, :name => "Barney":email => "barney@bedrock.com")  



    使用update_all() 

    Ruby代码  收藏代码
    1. result = Product.update_all("price = 1.1*price""title like '%ruby%'")  



    Ruby代码  收藏代码
    1. save()和save!()  
    2. save()  
    3. if order.save  
    4. # 成功  
    5. else  
    6. # 保存失败则...  
    7. end  



    Ruby代码  收藏代码
    1. save!()  
    2. begin  
    3. order.save!  
    4. rescue RecordInvalid => error  
    5. # 保存失败RecordInvalid exception  
    6. end  



    数据锁(防止数据保存撞车) 
    加段:lock_version int default 0, 


    删除数据 

    Ruby代码  收藏代码
    1. delete()删除  
    2. Order.delete(123)  
    3. User.delete([2,3,4,5])  
    4. Product.delete_all(["price > ?"@expensive_price])  



    destroy()冻结(在model层面) 

    Ruby代码  收藏代码
      1. order = Order.find_by_name("Dave")  
      2. order.destroy  
      3. # ... order将被冻结  
  • 相关阅读:
    MySQL 存储过程
    linux iptables 相关设置
    Ubuntu iptables 设置
    Mac OS 10.12
    解决:cc1.exe: sorry, unimplemented: 64-bit mode not compiled in
    go get golang.org/x/net 安装失败的解决方法!
    Ubuntu16.04
    Ubuntu16.04
    Ubuntu16.04
    在Ubuntu16.04里面安装Gogland!
  • 原文地址:https://www.cnblogs.com/rywx/p/2559396.html
Copyright © 2011-2022 走看看