Rails Rails 内部是如何保持数据库连接的?

ericguo · 2012年09月01日 · 最后由 zhenjunluo 回复于 2012年09月08日 · 6378 次阅读

在做基于 bootstrap 2.1 上 typeahead 效果的时候,正好后端需要访问其他数据库,以返回 json 成为 type ahead 的前端数据,然后我写了下面的后端代码:

class TypeaheadController < ApplicationController
    def lot
        type_con=OCI8.new('user','passwd','ORA_TNS_NAME')
        q=params[:query]
        a=[]
        rows=type_con.exec("SELECT co.containername FROM container co
            WHERE co.containername LIKE '#{q.upcase}%' AND ROWNUM < 7")
        l = rows.fetch
        while l.present?
            a << l[0]
            l = rows.fetch
        end
        render json: a
    end
end

测试了一下发现,虽然能工作,但是 request/response 的间隔很长,速度很慢,初步判断问题应该是数据库没有缓存连接,因为每次调用都开一次数据库连接肯定慢啦,所以想问问在 Rails 下缓存 type_con 这样的数据库连接,Rails 内部是如何做的?如果我要用,在 initializer 里面写一个正确么?我看 database.yml 文件里面甚至有 pool,连接池的设定,如果能够用上这些基础设施,那就更好啦!

我想抄 Rails 保持数据库连接的代码,但是一看 Rails 代码一大堆,找不到抄哪里。。。

我从 Google 找到办法了,还是StackOverflow 给力啊

第一步:设定目标 database 配置

# config/database.yml
typeahead:
  adapter: oracle_enhanced
  database: ORA_TNS_NAME
  username: user
  password: passwd
  pool: 5
  timeout: 5000

第二步:需要一个 Model 承载 database connection

#  app/models/OtherDb.rb
class OtherDb < ActiveRecord::Base
  # No corresponding table in the DB.
  self.abstract_class = true
  establish_connection("typeahead")
end

最后一步,在 Controller 里面取得 connection

#  app/controllers/typeahead_controller.rb
class TypeaheadController < ApplicationController
    def lot
        q=params[:query]
        rows=OtherDb.connection().select_values("SELECT containername FROM container
            WHERE containername LIKE '#{q.upcase}%' AND ROWNUM < 7", :containername)
        render json: rows
    end
end

这样数据库连接就可以一直保持了!

你这也太菜了吧。看看 rails 的 activerecord 怎么用。

总结的挺好的。加油

establish_connection("typeahead") 直接 model 中加这句貌似也可以

#4 楼 @jjym self.abstract_class = true还是要的,否则会去读 typeahead 数据库里面的 OtherDb 这张表,如果没有,就直接报错了。

#1 楼 @ericguo 你的这个办法是对的,不过我建议你把 controller 中对 Oracle 的操作移动到 Model 中去。

收藏,可能以后会遇到这样的问题

需要 登录 后方可回复, 如果你还没有账号请 注册新账号