【Ruby on Rails全栈课程】3.2 配置数据库以及数据库操作知识

本文涉及的产品
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: 1、创建一个databasemysql我们已经在1.3节安装过了。连接远程,在项目目录下连接mysql,创建一个database数据库。如果你在1.3节启动项目时碰到了mysql错误并且解决了,那可以跳过1、2步,因为你已经配置好了。

1、创建一个database


mysql我们已经在1.3节安装过了。连接远程,在项目目录下连接mysql,创建一个database数据库。如果你在1.3节启动项目时碰到了mysql错误并且解决了,那可以跳过1、2步,因为你已经配置好了。


vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ mysql -u root -p
#输入你在1.3节配置的数据库密码
Enter password:
#创建一个名为data_system数据库
mysql> create database data_system;
#系统返回信息
Query OK, 1 row affected (0.09 sec)
#再输入show databases;展示当前数据库的名字,data_symtem数据库就是我们刚刚创建的。
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| data_symtem        |
| information_schema |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)


2、配置config/database.yml文件


根据下面代码示例配置你的database.yml文件,其中password是你安装mysql时配置的密码。将development:下面数据库名改成咱们刚刚创建的数据库名database: data_system。test:和production:下面的代码不需要改动


# SQLite version 3.x
#   gem install sqlite3
#
#   Ensure the SQLite 3 gem is defined in your Gemfile
#   gem 'sqlite3'
#
default: &default
  adapter: mysql2
  encoding: utf8
  pool: 5
  username: root   #mysql名称,默认为root
  password: xzn123xzn  #安装mysql时设置的密码
  host: localhost
development:
  <<: *default
  database: data_system #我们建立database的名称
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
#下面信息是默认的,初学的我们暂时不需要改动
test:
  <<: *default
  database: db/test.sqlite3
production:
  <<: *default
  database: db/production.sqlite3


3、创建映射文件,在data数据库中添加表


(1)我们先写一下这个表需要哪些字段,表结构如下:


image.png


(2)创建映射文件rails g model …


在项目目录下输入rails g model account name:string email:string password:string role:integer status:integer。会产生一个映射文件db/migrate/20180915153542_create_accounts.rb


#创建account表
/vagrant/data_symtem$ rails g model account name:string email:string password:string role:integer status:integer
#系统返回信息
create    db/migrate/20180915153542_create_accounts.rb
create    app/models/account.rb
invoke    test_unit
create      test/models/account_test.rb
create      test/fixtures/accounts.yml


(3)将映射文件映射到数据库rake db:migrate


#运行rake db:migrate,将映射文件映射到数据库中,此操作会在数据库建立account表以及在表中建立相应的字段
/vagrant/data_symtem$ rake db:migrate
== 20181127085433 CreateAccounts: migrating ===================================
-- create_table(:accounts)
   -> 0.0150s
== 20181127085433 CreateAccounts: migrated (0.0164s) ==========================


可能出现的错误:


Mac系统中,如果没有安装vagrant,直接在mac系统创建项目并运行rails g model…,可能会出现以下错误:


/Users/xuzhaoning/.rvm/rubies/ruby-2.4.4/lib/ruby/gems/2.4.0/gems/activerecord-
5.1.1/lib/active_record/connection_adapters/connection_specification.rb:188
:in `rescue in spec': Specified 'mysql2' for database adapter, but the gem is 
not loaded. Add `gem 'mysql2'` to your Gemfile (and ensure its version is at 
the minimum required by ActiveRecord). (Gem::LoadError)


解决方法:


项目在mac电脑上直接运行可能出现这个错误,我们的解决方案是在Mac电脑上安装vagrant(1.1章中有讲),在Ubuntu环境中启动项目


4、进入控制台,查看数据


#进入控制台
/vagrant/data_symtem$ rails c 
#查看创建的accounts表
irb(main):001:0> Account.new  
=> #<Account id: nil, name: nil, email: nil, password: nil, role: nil, status: 0, created_at: nil, updated_at: nil>


5、数据库操作知识


Rails中的数据库操作用的是Active Record(活动记录),是一种领域模型模式,特点是一个模型类对应关系型数据库中的一个表,而模型类的一个实例对应表中的一行记录。


比如:Account这个模型类对应了mysql数据库中的accounts表,Account类的一个实例对象对应accounts表中的一条数据。


我们在项目目录下,输入rails c进入控制台,在控制台中操作数据库


(1)创建数据

#a是一个Accoun类的实例对象。
irb(main):001:0>  a = Account.create(name: "猫宁", email: "12345@qq.com")
#相当于mysql代码。当我们创建或者修改数据时,created_at字段和updated_at字段都会自动改变。
INSERT INTO accounts (name, email, created_at, updated_at) VALUES ('猫宁', '12345@qq.com', '2018-12-26 15:55:30', '2018-12-26 15:55:30')
#再创建一个name为“狗宁”,email为"23456@qq.com"的实例对象
irb(main):002:0> Account.create(name: "狗宁", email: "23456@qq.com")

可能出现错误:


ActiveRecord::StatementInvalid: Mysql2::Error: Incorrect string value: ‘\xE7\x8C\xAB\xE5\xAE\x81’ for column ‘name’ at row 1: INSERT INTO accounts (name, email, created_at, updated_at) VALUES (‘猫宁’, ‘12345@qq.com’, ‘2018-12-30 04:54:18’, ‘2018-12-30 04:54:18’)


此错误是向MySQL中插入中文时才会出现,原因是MySQL的字符集不是utf-8,所有不支持中文,我们需要exit退出控制台,登录mysql进行以下操作:


#登录mysql
vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ mysql -u root -p
#输入你在1.3节配置的数据库密码
Enter password:
#修改data_system数据库,accounts表的字符集;
mysql> ALTER TABLE data_system.accounts CONVERT TO CHARACTER SET utf8;
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0
#重新在数据库中映射accounts表,注意这一步数据库数据会损坏,需要进行数据备份。我们目前没有添加过数据,就不备份了。
vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ rake db:drop
vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ rake db:create
vagrant@vagrant-ubuntu-trusty-64:/vagrant/data_system$ rake db:migrate
(2)查找数据


1)查找第一条数据,返回我们创建的第一个Account对象


irb(main):001:0> a1 = Account.first
=> #<Account id: 1, name: "猫宁", email: "12345@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-26 15:55:30", updated_at: "2018-12-26 15:55:30">
#相当于mysql代码
SELECT * FROM accounts ORDER BY id ASC LIMIT 1


2)查找最后一条数据,返回我们创建的第二个Account对象


irb(main):002:0> a2 = Account.last
=> #<Account id: 2, name: "狗宁", email: "23456@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-28 09:31:22", updated_at: "2018-12-28 09:31:22">
#相当于mysql代码
SELECT * FROM accounts ORDER BY id DESC LIMIT 1

3)查找出所有数据,返回Account对象集合,里面包含我们创建的所有对象。


如果数据较多,在实际项目中不建议用.all拿出所有数据,因为这样会耗费很多的内存。数据量大,用分页或者where查询缩小范围。


irb(main):003:0> a3 = Account.all
=> #<ActiveRecord::Relation [#<Account id: 1, name: "猫宁", email: "12345@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-26 15:55:30", updated_at: "2018-12-26 15:55:30">, #<Account id: 2, name: "狗宁", email: "23456@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-28 09:31:22", updated_at: "2018-12-28 09:31:22">]
#相当于mysql代码
SELECT  * FROM accounts


4)通过id查找数据,这样会返回对应id的Account对象。


需要注意的是,如果没有此id,会报错,所以我们再实际项目中,在不确定该id存在的情况下,一般不会用find查找,而是用find_by替代,下面会讲。


irb(main):006:0> Account.find(2)
=> #<Account id: 11, name: "狗宁", email: "23456@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-28 09:31:22", updated_at: "2018-12-28 09:31:22">
#相当于mysql代码
SELECT * FROM accounts WHERE id = 2

5)通过条件查找数据,这样会得到Account对象集合,具体对象实例根据集合索引获取。


如果没有对应的条件,会返回一个空集合。


where不管查出多少条数据都是一个对象集合。


#查找name为"猫宁"的数据,得到一个对象的集合。
irb(main):008:0> accs = Account.where(name:"猫宁")
=> #<ActiveRecord::Relation [#<Account id: 1, name: "猫宁", email: "12345@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-26 15:55:30", updated_at: "2018-12-26 15:55:30">]>
#获取集合中第一个name为"猫宁"的对象
irb(main):009:0> acc = accs.first
=> #<Account id: 1, name: "猫宁", email: "12345@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-26 15:55:30", updated_at: "2018-12-26 15:55:30">
#然后获取该对象的邮箱,即accounts表中的email字段
irb(main):010:0> email = acc.email
=> "12345@qq.com"
#上面3步可以整合成一句
irb(main):011:0> email = Account.where(name:"猫宁").first.email
=> "12345@qq.com"
#也等同于,find_by相当于where().first
irb(main):012:0> email = Account.find_by(name:"猫宁").email
=> "12345@qq.com"
#如果没有相对应的条件会返回一个nil对象
irb(main):013:0> accounts = Account.find_by(name:"猫宁喵喵喵")
=> nil
#对nil进行.first.email操作会报错
irb(main):014:0> email = Account.where(name:"猫宁喵喵喵").first.email
NoMethodError: undefined method `email' for nil:NilClass
  from (irb):14

(3)修改数据


修改一个对象用update,修改对象集合用update_all


#将name为"猫宁"的对象,修改name为"可爱的猫宁"
#如果知道这个对象的id,那直接用find找出对象修改即可
irb(main):018:0> Account.find(1).update(name:"可爱的猫宁")
=> true
#查询符合条件的account对象集合,修改名字为"可爱的狗宁"
irb(main):019:0> Account.where(name:"狗宁").update_all(name:"可爱的狗宁")
=> true

(4)删除数据


  • 删除一个对象用delete,删除成功后返回这个被删除的对象


  • 删除对象集合用delete_all,删除成功后返回删除的个数


  • 在实际项目中一般不用delete或者delete_all删除数据,因为这样删除的数据是不可恢复的。


#删除第一个name为"可爱的猫宁"的对象
irb(main):019:0> Account.where(name:"可爱的猫宁").first.delete
=> #<Account id: 1, name: "可爱的猫宁", email: "12345@qq.com", password: nil, role: nil, status: nil, created_at: "2018-12-26 15:55:30", updated_at: "2018-12-28 10:18:34">
#删除符合name为"可爱的狗宁"条件的对象集合。
irb(main):020:0> Account.where(name:"可爱的狗宁").delete_all
=> 1


(5)数据排序


#将查询结果根据创建时间正序排序
Account.where(name:"猫宁").order(created_at: :asc)
#将查询结果根据创建时间倒序排序
Account.where(name:"猫宁").order(created_at: :desc)
#将查询结果先根据创建时间倒序排序,再根据修改时间正序排序
Account.where(name:"猫宁").order(created_at: :desc,updated_at: :asc)


(6)数据分组及相关应用


#将account数据根据email、name的值分组
Account.where(name:"猫宁").group(:email,:name)
#返回一个哈希。key为email name值的数组,value为对应数据的条数
Account.where("name like '%管理员%'").group(:email,:name).count
=> {["123456781@qq.com", "管理员2"]=>1, ["123456782@qq.com", "管理员3"]=>1, ["12345678@qq.com", "管理员1"]=>1}


(7)其他常用方法


1)map,返回对应字段的数组

irb(main):023:0> Account.where("name like '%管理员%'").collect(&:name)
=> ["管理员1", "管理员2", "管理员3"]


2)select,只返回想要展示的字段

irb(main):025:0>  Account.where("name like '%管理员%'").select("name,email")
=> #<ActiveRecord::Relation [#<Account id: nil, name: "管理员1", email: "12345678@qq.com">, #<Account


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
25天前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——TestStu.java
hibernate正向生成数据库表以及配置——TestStu.java
16 1
|
25天前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——Teacher.hbm.xml
hibernate正向生成数据库表以及配置——Teacher.hbm.xml
13 1
|
25天前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——Teacher.java
hibernate正向生成数据库表以及配置——Teacher.java
11 0
|
25天前
|
Java 数据库连接 数据库
hibernate正向生成数据库表以及配置——Student.java
hibernate正向生成数据库表以及配置——Student.java
10 0
|
2月前
|
网络协议 关系型数据库 Linux
Linux系统中如何开启和配置OpenGauss数据库的远程连接
openGauss是一款开源关系型数据库管理系统,采用木兰宽松许可证v2发行。openGauss内核深度融合华为在数据库领域多年的经验,结合企业级场景需求,持续构建竞争力特性.
|
3月前
|
SQL 数据库 HIVE
记录hive数据库远程访问配置问题
记录hive数据库远程访问配置问题
114 0
|
2月前
|
存储 监控 安全
内网屏幕监控软件的数据存储与管理:使用SQLite数据库保存监控记录和配置信息
在当今数字化时代,安全和监控在企业和组织中变得至关重要。内网屏幕监控软件作为一种关键工具,帮助组织监视员工的活动并确保信息安全。这种软件不仅需要高效地记录和管理监控数据,还需要能够方便地进行配置和调整。本文将讨论如何使用SQLite数据库来保存监控记录和配置信息,并介绍如何通过自动化机制将监控到的数据提交到指定网站。
150 2
|
2月前
|
SQL 监控 Java
Java Web应用中数据库连接池的配置与优化
Java Web应用中数据库连接池的配置与优化
|
2月前
|
监控 关系型数据库 MySQL
MySQL技能完整学习列表12、性能优化——1、性能指标和监控——2、优化查询和数据库结构——3、硬件和配置优化
MySQL技能完整学习列表12、性能优化——1、性能指标和监控——2、优化查询和数据库结构——3、硬件和配置优化
143 0
|
3月前
|
SQL NoSQL 关系型数据库
2021你应该会全栈 第1期 数据库概述
2021你应该会全栈 第1期 数据库概述
24 0