CRUD中的一些查询

by 小赓赓。 at over 8 years ago, last updated at over 8 years ago
W

n+1查询

有时查询一条数据时会关联许多数据,会导致内部查询很多很多次,所带来的坏处可想而知,主要就是查询时间过长.解决方法就是使用includes(表名)

find vs find_by

1.find 只能查询用户id.下面可以看出两种都可以同查询出数据,但是如果要查询数据库中没有的数据时,使用find_by则会返回一个nil,而find方法则会抛出异常

2.2.3 :001 > u = User.find 1
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
 => #<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33"> 

2.2.3 :005 > u = User.find_by id:1
  User Load (0.3ms)  SELECT  `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
 => #<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33"> 

2.find_by可以查询任何的数据通过key-value的形式

2.2.3 :007 > u = User.find_by username: "wu"
  User Load (0.8ms)  SELECT  `users`.* FROM `users` WHERE `users`.`username` = 'wu' LIMIT 1
 => #<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33"> 

根据这两点酌情使用

find_by!

! 在ruby中大多是修改数据自身.而在rails不太一样.如在rails console中查询一个不存在的数据,使用find_by!时就会抛出异常,需要我们手动抓取异常

find_by_sql

这个是让我们用原生的sql语句去查询数据的如:

2.2.3 :009 > u = User.find_by_sql "select * from users"
  User Load (0.6ms)  select * from users
 => [#<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33">, #<User id: 2, username: "wu2", password: "123456", created_at: "2016-06-03 07:32:59", updated_at: "2016-06-03 07:32:59">]
#  可以看出其实是把数据封装成一个数组,所以也可以用下面的方式查询
2.2.3 :010 > u.first.id
 => 1 

用于非常复杂的数据查询,但有可能会有sql注入的不安全隐患.另外,我们使用这种方式查询时,model和user或者其他的表没有对应关系,也就是可以查询其他随意一张表,但会把其封装成此model的对象.还有如果出现同名表的情况,那只能访问从前往后的第一个,后面访问不到(as:声明别名).

where

类似嵌入一些ruby的语法去查询,如:

# 使用数组
2.2.3 :011 > u = User.where(["id = ?",2])
  User Load (1.0ms)  SELECT `users`.* FROM `users` WHERE (id = 2)
 => #<ActiveRecord::Relation [#<User id: 2, username: "wu2", password: "123456", created_at: "2016-06-03 07:32:59", updated_at: "2016-06-03 07:32:59">]> 
# 使用hash
2.2.3 :012 > u = User.where(id:2)
  User Load (0.6ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 2
 => #<ActiveRecord::Relation [#<User id: 2, username: "wu2", password: "123456", created_at: "2016-06-03 07:32:59", updated_at: "2016-06-03 07:32:59">]> 

where其实是把查询的数据封装成一个对象,但是在我们没有使用each,to_a等方法之前他并没有将操作传递给数据库,所以我们可以一直利用这个对象继续查询,他会把所有查询过的数据全部封装为一个对象

2.2.3 :019 > w = User.where(id:1)
  User Load (0.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1
 => #<ActiveRecord::Relation [#<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33">]> 

2.2.3 :021 > w = w.where(username: "wu")
  User Load (0.5ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 AND `users`.`username` = 'wu'
 => #<ActiveRecord::Relation [#<User id: 1, username: "wu", password: "123456", created_at: "2016-06-03 07:32:33", updated_at: "2016-06-03 07:32:33">]>