Active Record活跃记录
Active Record Pattern 活跃记录模式
Active Record is a design pattern first proposed by Martin Fowler.
According to Martin Fowler, an active record object represents a row in a
database table. Contrary to J2EE's Value Object pattern which is an object
having only data fields but no behavior, and to the popular DAO pattern which
only has data access behavior but no data, the Active Record pattern describes a
rich object which has both data fields and data access behavior.
活跃记录是Martin Fowler首先推荐的一种设计模式,根据他的想法,一个活跃记录对应着一个数据库表的一行。相反,J2EE的一个值对象模式是一个只包含数据字段没有方法的对象,流行的DAO模式之包含数据访问方法但没有数据,活跃记录模式描述了一个同时包含数据字段和数据访问方法的富对象。
Scooter Framework's ActiveRecord class is an implementation of Active Record
pattern. All domain objects, if they want to take advantage of functionalities
of ActiveRecord, must become a subclass of this class.
Scooter框架的活跃记录类是一个活跃记录模式的实现。所有的域对象,如果它们想利用ActiveRecord的功能,必须先成为这个ActiveRecord类的子类。
For example, a Post class which represents a blog post record in
database, can be implemented as follows:
比如说,一个Post类对应着数据库里一个博客的帖记录,应该像下面这样实现:
public class Post extends ActiveRecord {
}
Even though this class only has one code line (omitting import and package
statement lines), it is already very powerful as it inherits many methods from
its super class. It also has knowledge of posts table meta data
information such as name and properties of all columns including primary key
column(s).
虽然这个类只包含一行代码(省略import和package等状态行),它已经非常强大,因为它从它的父类继承了很多方法。它也知道post表的元数据信息,比如所有列的名字和属性包括主键列。
By default, the Post class in singular form above maps to a table
named posts in plural form in database. This can be changed by the
use.plural.table.name property in the database.poperties file.
There are some other properties in that file related to table naming
conventions. For example, if names of all your tables start with a prefix of
"CRM_", you simply use the global.table.naming.prefix
property.
CRUD Made Easy
CRUD is an abbreviations of four common operations of data acess: create,
read, update and delete. CRUD is easy with Scooter Framework's ActiveRecord.
Create
Create a record in database:
ActiveRecord post = new Post();
post.setData("title", "Happy Java Programming");
post.setData("body", "Java programming is fun.");
post.create();
The last line above is equivalent to the following sql statement:
insert into posts (title, body) values ('Happy Java Programming', 'Java programming is fun.');
It will create a new record in a posts table.
Read
For a single ActiveRecord instance, it can refresh itself with the
latest data in database:
ActiveRecord post = ...;
post.reload();
The last line above is equivalent to the following sql statement, assuming 8
is the primary key value of the record:
select * from posts where id = 8;
Update
Update a record in database:
ActiveRecord post = postHome.find("title=Happy Java Programming");
post.setData("title", "Scooter Rocks!");
post.update();
The last line above is equivalent to the following sql statement:
update posts set title='Happy Java Programming',
body='Java programming is fun.'
where id=8;
It will update the title of the record with id 8--assuming 8 is the value of
the primary key, in the posts table.
The update() method will list all columns of the posts
table in the update statement. Since we only edited the title
column, we can use updateChanged():
ActiveRecord post = postHome.find("title=Happy Java Programming");
post.setData("title", "Scooter Rocks!");
post.updateChanged();
The last line above is equivalent to the following sql statement which uses
only those columns whose data are changed:
update posts set title='Happy Java Programming'
where id=8;
Scooter Framework's ActiveRecord is smart enough to track which
fields are changed and only use those fields in the update sql
statement.
Delete
Delte a record in database:
ActiveRecord post = postHome.find("title=Happy Java Programming");
post.delete();
The last line above is equivalent to the following sql statement:
delete from posts where id=8;
ActiveRecord Home Instance
In Scooter Framework, each domain object has a single instance called home
instance which acts as a gateway to a database table. This is an
implementation of Martin Fowler's Table Data
Gateway pattern. Each home instance provides more methods for data retrieval
and muniplation in its domain. It also provides meta data for the domain.
Obtain a home instance:
ActiveRecord postHome = ActiveRecordUtil.getHomeInstance(Post.class);
Retrieve
ActiveRecord uses overloaded find() methods to retrieve a
record:
//returns the one record we just created above.
ActiveRecord post = postHome.find("title=Happy Java Programming");
The above code is equivalent to the following sql statement:
select * from posts where title='Happy Java Programming';
ActiveRecord uses overloaded findAll() methods to retrieve
a list of records:
//returns all records satisfying the conditions required
List posts = postHome.findAll("title=Happy Java Programming", "conditions_sql: id in (1, 2, 3);order_by: last_name desc");
The above code is equivalent to the following sql statement:
select * from posts
where title='Happy Java Programming'
and id in (1, 2, 3)
order by last_name desc;
Dynamic Retrieval
You can simulate Ruby On Rails' dynamic finder by using ActiveRecord's
findBy() and findAllBy() methods.
//The class
class Employee extends ActiveRecord {}
//retrieve the employee whose first name is John, last name is Doe
ActiveRecord john = employeeHome.findBy("firstName_and_lastName", {"John", "Doe"});
//retrieve the employee whose first name is John, last name is Doe and age is 29.
ActiveRecord john = employeeHome.findBy("firstName_and_lastName_and_age", {"John", "Doe", new Integer(29)});
//retrieve all employees who live in LA
List employees = employeeHome.findAllBy("city", {"LA"});
Back to SQL
ActiveRecord is SQL friendly. You can drop back to SQL if you rely
on complicated or historical sql queries. ActiveRecord provides
findBySQL(), deleteBySQL(), updateBySQL() mehods. If
the sql statement is in external file sql.properties, you can use the
corresponding findBySQLKey(), deleteBySQLKey(),
updateBySQLKey() mehods.
//retrieve all employees who live in LA
List employees = employeeHome.findBySQL("select * from employees where city = 'LA'");
Some Tips
Specifying Table Name Directly
You can set the corresponding table name of an ActiveRecord class directly as
follows:
public class Post extends ActiveRecord {
public String getTableName() {
return "blogs";
}
}
Using Non-database Fields
ActiveRecord implicitly pulls fields of a model from database. Therefore, you
do not need to list database table fields in the class. However, what if you
want to have some non-database fields in the model only? This kind of fields is
called extraField in ActiveRecord. You can deal with them as
follows:
public class User extends ActiveRecord {
protected void declaresExtraFields() {
//declare two extra fields
setExtraFields("nickName, formerName");
}
}
//Then you can use them as you use any other fields
ActiveRecord david = new User();
david.setData("nickName", "Dave");
System.out.println(david.getField("nickName"));
Using Protected Fields
Protected fields are those table columns that you do not want users to change
in an application. They can only be changed through database tools. For example,
you may declare username and password as protected fields.
Once they are entered in database, you would not allow users to change them.
public class User extends ActiveRecord {
protected void declaresProtectedFields() {
//declare two protected fields
setProtectedFields("username, password");
}
}
//Then operations like clearAndSetData() and setData() will have no effects on
//the protected fields
ActiveRecord david = new User();
david.setData("username", "IJustChangedYou");
System.out.println(david.getField("username"));//should still print out unchanged database record.
相关推荐
01_the-basics-of-convnets_exam.html
### 【MongoDB Basics ( v6.x )】mongodb-basics-master.zip **内容概要:** `mongodb-basics-master` 是一个全面的 MongoDB 基础教程项目,特别针对 MongoDB 6.x 版本。该项目包含了多个示例和练习,涵盖了 ...
标题 "sinatra-hello-world-basics-onl01-seng-ft-090820-master.rar" 提供的信息表明,这是一个关于Sinatra框架的基础教程项目,可能包含了一个在线课程或者工作坊的内容,时间可能是在2009年8月20日。Sinatra是一...
【标题】"NPM-Basics-master(2)_matlab_" 提到的是一个关于NPM基础知识的项目,结合了MATLAB的元素。NPM(Node Package Manager)是JavaScript开发中的一个核心工具,主要用于管理Node.js项目的依赖包。在MATLAB这个...
计算机组成原理、计算机网络、数据结构、操作系统思维导图_-Computer-Basics-Notes
链接: http://www.cis.upenn.edu/~jean/math-basics.pdf 这本书讲了什么? 这本书的主要目的是介绍线性代数和最优化理论的基础知识以及这些知识在机器学习、机器人学、计算机视觉等领域的应用。 该书包含以下 10...
【描述】:“web-automation-basics-源码.rar”的描述简洁明了,暗示着这个压缩包可能包含了用于教学或实践的Web自动化测试代码。这可能包括使用流行的自动化框架(如Selenium WebDriver)进行页面对象模式、数据...
Stress-Matrix-and-MATLAB-basics-HomepagesPPT文档.pptx 该PPT文档主要介绍了计算固体力学、计算生物医学工程和MATLAB基础知识三个方面的内容。 计算固体力学 在计算固体力学领域,文档中提到了以下几个关键概念...
这个“clojure-basics-源码.rar”压缩包很可能是包含了一些基本Clojure编程概念的示例代码或者教程。虽然没有具体的标签提供额外的信息,但我们可以从文件名推测其内容可能涵盖了Clojure的基础知识。 Clojure的基本...
标题与描述:“TopNotchThemes-basics-guide” 此标题与描述指向一份由TopNotchThemes提供的基础指南,旨在帮助用户了解如何使用其主题构建Drupal网站。这份指南详细介绍了从安装主题到配置网站、创建内容以及调整...
mkdir assignment--dom-manipulations-basics cd assignment--dom-manipulations-basics 3-下载.zip文件并解压缩: curl ...
of-flight basics 时间飞行原理(Time-of-Flight, TOF)是一种用于测量物体距离的技术,广泛应用于各种领域,如深度感应、3D成像、安全系统等。本应用笔记将深入探讨TOF的基本概念,包括其工作原理、关键组件、性能...
本资源"the-basics-image-process-code.zip_The Process"包含了一系列图像处理的编程实践,主要用C++语言实现。以下是这些图像处理技术的详细讲解: 1. 边缘检测:图像的边缘是图像特征的重要组成部分,它可以帮助...
"java-basics-源码.rar"文件显然包含了关于Java基础知识的源代码示例,这为我们提供了深入理解语言机制的机会。让我们逐一探讨这些核心概念。 1. **类与对象**:Java是一种面向对象的编程语言,一切皆为对象。类是...
网络基础知识2:第3周的作业 该任务将涵盖第一周和第二周JavaScript... cd web-basics-2-week-3-[your-username] 创建一个新的本地分支以与主分支( master )分开工作: git checkout -b assignment 最后,在代码编辑
网络基础知识2:第1周的作业 该作业将涵盖以下JavaScript主题: 在终端中执行代码 使用变量存储和跟踪信息 ... cd web-basics-2-week-1-[your-username] 创建一个新的本地分支以与主分支( master )分
网络基础知识2:第1周的作业 该作业将涵盖以下JavaScript主题: 在终端中执行代码 使用变量存储和跟踪信息 ... cd web-basics-2-week-1-[your-username] 创建一个新的本地分支以与主分支( master )分
在这个Java实现的项目“Genetic-Algorithms-in-Java-Basics-master”中,我们将深入探讨遗传算法的基本原理以及如何在实际问题中应用它来优化课程时间表。 1. **遗传算法基本概念**: - **种群(Population)**:...
基于Pytorch架构的一些深度学习基础项目,包括通用功能,核心训练模块,以及图像生成,分割,超分等模型
BASICS OF COMPUTER SCIENCE