Thursday, October 05, 2006
HQL : Hibernate Query Language
Why Use HQL?
1. Representing SQL queries in form of Objects: HQL allows you to write and run the SQL queries using objects. Thus your object oriented code more readable and homogeneous.
2. Ready made resultset Objects: When hibernate enabled applications run the HQL, the result that u get is a ready-made object ready to be used and thus eleminating the need to first create an object and then populate it using the query result set.
3. Support for Advance Features: HQL contains many advance features such as pagination, fetch join with dynamic profiling, Inner/outer/full joins, Cartesian products. It also supports Projection, Aggregation (max, Avis) and grouping, Ordering, Sub queries and SQL function calls.
4. Database Independency: Queries written in HQL are database independent (If database supports the underlying feature).
5. SubQuery Support: HQL also supports sub queries in case the underlying database supports it.
Note: While using HQL, you always need to keep in mind that the feature that you are going to use is supported by the underlying database. It will be better if u use such features that are supported dby all the databases to keep your application database independent.
Understanding HQL Syntax
Any Hibernate Query Language like SQL queries consists of following three elements:
1. Clauses : Clauses in the HQL are: (a) from (b) select (c) where (d) order by (e) group by
2. Aggregate functions : (a) avg, sum, min, max (b) count(*) (c) count(...), count(distinct ...), count(all...)
3. Subqueries : Subqueries are nothing but its a query within another query. Hibernate supports Subqueries if the underlying database supports it.
Let us explore each clause with an example. For this let us go step by step as follows:
Step 1 : Create Table order
CREATE TABLE "order" ( "order_id" int(11) NOT NULL default '0', "order_name" varchar(50) default NULL, "order_price" int(11) default NULL, "order_date" datetime default NULL, "order_period" int(2) default 1, PRIMARY KEY ("orderid")) TYPE=MyISAM;
Step 2 : Populate order Table
Now let us put some dummy data in this table to be used in examples later as follows:
insert into "order" values (1,'Domain Registration',10,'2006-01-05 00:00:00',1);
insert into "order" values (2,'Managed DNS',100,'2006-10-01 00:00:00',1);
insert into "order" values (3,'Domain Fwd',500,'2006-10-15 00:00:00',1);
insert into "order" values (4,'Email Hosting',2500,'2006-01-01 00:00:00',1);
insert into "order" values (5,'Windows Hosting',500,'2005-01-01 00:00:00',1);
insert into "order" values (6,'Domain Registration',20,'2006-01-05 00:00:00',2);
insert into "order" values (7,'Windows Hosting',1000,'2006-01-05 00:00:00',2);
insert into "order" values (8,'Email Hosting',5000,'2006-01-05 00:00:00',2);
Step 3 : Create Plain Old Java Object (POJO) persistent class Order.java mapping to the order table
Following is the java code for the Order.java class:
package myproject.HQL.tutorial;import java.util.Date;
/** * This Java Class maps to the order table */
public class Order
{
private long orderid;
private String ordername;
private int orderprice;
private Date orderdate;
private int orderperiod;
// Now write the getter setter methods for each of the instance variables. This class is a standard JavaBean.
public long getOrderId()
{
return orderid;
}
public void setOrderId(long orderid)
{
this.orderid = orderid;
}
public String getOrderName()
{
return ordername;
}
public void setOrderName(String ordername)
{
this.ordername = ordername;
}
public Date getOrderDate()
{
return orderdate;
}
public void setOrderDate(Date orderdate)
{
this.orderdate = orderdate;
}
public int getOrderPrice()
{
return orderprice;
}
public void setOrderPrice(int orderprice)
{
this.orderprice = orderprice;
public int getOrderPeriod()
{
return orderperiod;
}
public void setOrderPrice(int orderperiod)
{
this.orderperiod = orderperiod;
}
}
Step 4: Adding mappings into order.hbm.xml file
Now we need to map the class Order.java class to the order table, so write the following code in the order.hbm.xml file:
<class name="myproject.HQL.tutorial" table="order">
<id name="orderid" type="long" column="order_id" >
<generator class="increment"/>
</id>
<property name="ordername">
<column name="order_name" />
</property>
<property name="orderprice">
<column name="order_price" />
</property> <property name="orderdate">
<column name="order_date" />
</property>
<property name="orderperiod">
<column name="order_period" />
</property>
</class>
Step 5: Using HQL Clauses
Now we have done with a table in our database and a POJO class that maps to the table and the mapping file also. Time to go and fire some HQL query on the database and get some useful information from it, so here we go exploring each clause one by one:
The HQL From Clause
The From clause is the simplest one. Let us say we want to select all the order present in the order table. for that we just need to write the following code in the java file:
from Order as order
or
from Order order
(the as keyword is optional)
The first word "Order" indicates the name of the class which maps to the table from which you want to fetch the rows (here the orders table). The second word "order" gives a alias to the resultset. This is the handle using which you can iterate through the records and perform whatever operation you want to perform on them. For example let us assume that we want to fetch all the orders present in the order table and then print them one by one. For this in your java file you can write the following code:
try
{
// The line below reads the hibernate.cfg.xml and prepare hibernate for use.
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
Session session =sessionFactory.openSession();
String query ="from Order as order";
Query hqlquery = session.createQuery(query);
System.out.println("=============================================\n");
System.out.println("Printing All the Orders\n\n");
for(Iterator it=query.iterate();it.hasNext();)
{
Order order = (Order)it.next(); // as each row fetched is an object of the corresponding POJO class.
System.out.println("ORDER ID: " + order.getOrderId());
System.out.println(" ORDER NAME: " + order.getOrderName()+"\n"); // The resultset contains every other column value also which we can print, but I am just mentioning first two here for the sake of space and time. You can print other column values also in the similar manner if you want.
}
System.out.println("=============================================\n"); session.close();
}
catch(Exception e)
{
System.out.println(e.getMessage());
}
Note: You would need to import the following lasses in you java file:
org.hibernate.Session
org.hibernate.*
org.hibernate.cfg.*
Output of the above code will be as follows:
=============================================
Printing All the Orders
ORDER ID: 1 ORDER NAME: Domain Registration
ORDER ID: 2 ORDER NAME: Managed DNS
ORDER ID: 3 ORDER NAME: Domain Fwd
ORDER ID: 4 ORDER NAME: Email Hosting
ORDER ID: 5 ORDER NAME: Windows Hosting
ORDER ID: 6 ORDER NAME: Domain Registration
ORDER ID: 7 ORDER NAME: Windows Hosting
ORDER ID: 8 ORDER NAME: Email Hosting
=============================================
Note: You can also perform cross join of two tables in the same clasuse just by mentioning the multiple class names which map to the multiple tables that you want to cross join. For example if you want to cross join two tables Order and Owners then you would write the HQL as follows:
from Order, Owner or from Order as order, Owner as owner
The HQL Select Clause
The select clause is like the from clause only with the difference that you can specify the columns that you want to be selected unlike the from clause which returns all the columns of the table (this is well understood by you I hope if you are familiar with the SQL queries already). For example if we want exactly the same output as of the from clause using the select clause we would replace the string in the above code by the following query:
Select order.orderid,order.ordername from Order as order
The HQL Where Clause
Now you may limit the number of rows selected by the select clause by specifying the condition using the where. For example lwt us say that we want to select only Domain Registration orders, then you wouuld replace the query in the from clause code by the following query:
from Order as order where order.ordername = 'Domain Registration'
The HQL Order By Clause
If you want to order the list returned by your query by any property (instance variable of the POJO class or the column of the table) then the order by clause can be used. For example if you want to sort the orders returned by the from clause according to the order name, order date in ascending order, then you would replace the from query by the following query:
from Order order order by order.ordername asc, order.orderdate asc
The HQL Group By Clause
You can use the group by clause to aggregate values returned in the resultset of the query. For example if you want to see how much reenue you have generated till date on different orders, then you would replace the from query with the following query:
select sum(order.orderprice) from Order order group by order.ordername
So this is it. Simple and powerful No!! Yes no doubt!! Stayed tuened for more stuff on Hibernate.
Till then Happy Reading and Happy Programming !! :-)
Wednesday, October 04, 2006
Hibernate Framework for JAVA
Now a days Object Oriented approach is the most popular. No doubt! But no doubt we need to deal with the database which is mostly based on Relational model. So definitely while building an application that requires interacting with database, the interaction becomes complex when your application is Object Oriented and the database is relational. The complexity in this case arises due to the knots and knaves of cross approach communication.
So when such a need arises where need to make you object orinented application communicate with the relational database, we need a mediator which can make the objects of two different orientations (object oriented and relational) talk to each other. One such good example of this is the Java Database Connectivity (JDBC) API. JDBC allows you to access different databases without much difficulty. But as JDBC is relatively a low level API and provides a low level of abstraction, it can be relied on for the medium or low level projects but for the enterprise level projects. For enterprise level big application, what is more suited is a framework which acts a medisator facilitating the interaction of the objects of Object oriented approach and releational appraoach. Such frameworks ar ecalled Object Relational Mapping (ORM).
Object Relational Mapping:
The process of transformation from a relational approach to an object oriented approach is known as Object Relational Mapping. The Hibernate framework is an ORM : The best example of an ORM framework for Java is Hibernate. But before going further, I would assume that my readers are familier with the object oriented and releational modles :-)
Introduction to Hibernate:
As of now I have made it probabaly clear that what is the need of ORM. ORM reduces our (developer's) task by takig care of how the releational oriented objects will work while working with classes. Although there are various differnet frameworks available in this category, but Hibernate is comparitively simpler and flexible than all others.
Prerequisites to Make Your Application Hibernate Enabled: Following are the three prerequisites to make your web application hibernate enables:
1. Persistence Class: A class is persistent when it is based on the Plain Old Java Object or POJO model. A persistent class is one which has instance variables and getter and setter methods to get and set the variable values. The main function of a persistent class in Hiberation is to to act as a blueprint of the tables in the database with which your web application interacts. So each tables of the database dores have a corresponding class in you application. The instance variables of the class coresponds to the various cloumns of the table. The data-type of the instance variables depend on the data-type of the columns. For example, if there is a column in a particular table in your database whose datatype is varchar(20), the intance variable corresponding to this variable in the blueprint class of the corresponding class will be Stirng. Now guess what each object of this persistence class will represent. Yes you guessed it right, each object of this class will represent a touple (row) in the corresponding table.
Now as we said each tables in the database, will have a corresponding persistence class in your web application, how will the application come to know which class corresponds to which table ? This mapping is mentioned in an XML file called Mapping file.
2. Mapping file: The mapping file contains detailed mapping between the persistence class and the table it represents. The following are the various required attributes of the XML file:
a. Root Element: The root element enclosing all other elements should be hibernate-mapping.
b. Child Elements class: The child elemets of root should be class. The class element, as the name itself indicates is used to map the various persistent classes to the corresponding table names. This element has two attributes. The first attribute is "name", the value of which is the name of a class to be mapped. The name of the class is the fuly qualified name of the class. By fully qualified I mean that the class name should contain the package name also. The second attribute is "table", the value of which specifies the name of the table which the class represents or is a blueprint of. For example, lets assume that u have a persistent class having fully qualified name as "com.myproject.persistent.Entity" which needs to be mapped to the a table named ENTITY, then the class element will be as follows:
<class name="com.myproject.persistent.Entity" table="ORDERS"></class>
Now a table has various columns and the corresponding persistent class has same number of instance variables. So how does the appilication knows which instance variable represents which column ? This mapping is defined by the element property.
c. property: The property element is used to map the varuious columns in a tables to the corresponding instance variables. This element has an attribute named "name" the value of which species the name of the instance variable in the corresponding persistent class which needs to be mapped to a particular column of the table. The name of the column is defined by a child element of this elment named "column". The child element column has an attribute named "name" which specifies the name of the column to which the instance variable is mapped. There are other two attributes of the column element named "length" and and "sql-type" which specify th length and sql-type of the column which is being mapped tothe corresponding instance variable. For example look at the following configuration of the mapping file:
<property name="entityname">
<column name="entityname" sql-type="char(255)" not-null="true"/>
</property>
The above configuration maps an instance variable named "entityname" to a column named "entityname" whose type is char(255).
Now as we know that the primary key always has a special place in a table, so the primary key of the table is mapped using a special element called id.
c. Child Element id: This element is also defined same as the property element. The only differnce lies in the fact that it also contains an extra child element "generator". This element is used to specify if the primary key value can be automatically generated or not. This is specified using an attribute named "class". If the value of the class attribute is "assigned" it tells Hibernate that the application would be used to assign the primarykey vales instaead of auto generating. For example look at the following configuration of the mapping file:
<id name="entityid" type="int" unsaved-value="0">
<column name="entityid" sql-type="integer(2)" not-null="true"/>
<generator class="assigned"/>
</id>
The above configuration tells Hibernate that the name of the primary key is "entityid" and that the type of the column is integer(2) which is mapped to the instance variable "entityid" of the persistence class which is mapped to the instance variable "entityid" of datatype "int". The value "assigned" of the class attribute of the child element generator specifies that the application itself will provide the value of the primary key and therefore it is not auto generated.
So finally if you look at the Mapping File for a persistent class called Entity for a table called entity having two column entityid and date, it would look something like this:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd;
<hibernate-mapping default-cascade="none" default-access="property" auto-import="true">
<class name=" com.myproject.persistent.Entity" table="entity" mutable="true" select- before-update="false" optimistic-lock="version">
<id name="entityid" type="int" unsaved-value="null">
<column name="entityid" sql-type="integer(2)" not-null="true" />
<generator class="assigned" />
</id>
<property name="date" not-null="false" >
<column name="date" sql-type="datetime" not-null="true" />
</property>
</class>
</hibernate-mapping>
The name of the above mapping file is Entity.hbm.xml. All the configuration files are named as
3. Hibernate Configuration file: This file contains the configuration that is required for communication with the underlying database. This file also declares all the mapping files being used by your web application. The root element of this configuration XML file is name as "hibernate-configuration". Following are the two importent elements that are present in this configuration file:
a. property: This element is used to configure various parameters called property parameters, such as the database server type (MySQL, Oracle, PGSQL etc), database URL, username/password to be used to connect to the database, dialect class, etc. All these parameters are defined using the name attribute of the property element. For example, look at the following configuration of the Hibernate Configuration file:
<!-- Database connection settings -->
<property name="connection.driver_class">org.hsqldb.jdbcDriver</property>
<property name="connection.url">jdbc:hsqldb:data/tutorial</property>
<property name="connection.username">sanjeev</property>
<property name="connection.password">qwedsa</property>
</session-factory>
b. mapping: The mapping element of the Hibernate Configuration file is used to declare all the the mapping (hbm ) files. This element has an attribute named "resource" the value of which specifies the path of the hbm file. For example, look at the following configuration of the Hibernate Configuration file:
So the Hibernate Configuration file for a web application where you are using Oracle database, with username scott and password tiger with one connection at a time, the file would look something like this:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC"-//Hibernate/Hibernate Configuration DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd;
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class"> oracle.jdbc.driver.OracleDriver </property>
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl </property>
<property name="connection.username">scott</property>
<property name="connection.password">tiger</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">1</property>
<!-- SQL dialect -->
<property name="dialect"> org.hibernate.dialect.OracleDialect </property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<mapping resource=" com/someorg/persist/Event.hbm.xml"/></session-factory>
</hibernate-configuration>
So this is it !! To get started with hibernate. I personally feel that the concept of Hibernate is not that tough but using it is a bit tricky as you should design your application in sucha a way that you can use Hibernate easily. In the next post releating to hibernate, I will try to give you an idea about how to use Hibernate in real world.
Till then Happy Reading and Happy Programming :-)
Monday, August 21, 2006
Ajax On Rails
Brief Introduction to Ajax and its Use:
Have you ever realize the fact that the Desktop applications that you use are much more responsive than the Web applications available on internet ? Of course you must have if you ever used a Web application. And the reason for the same is very obvious. In the Web applications, most of the time the client server communication happens involving the data to be posted to the server, processing the data at the server side, and then returning the result. Now when communication over network comes in picture, then the network latency also comes in picture. And this latency makes the Web application slow.
Now this is something which cannot be removed fully. But of course we can try to reduce it to the maximum extent we can. How?
The Answer is Ajax or Asynchronous JavaScript + XML. Here I am assuming that you people already know how Ajax exactly works so I am not going in detail. I would rather try to explain How is Rails and Ajax together are making a difference in the developing the real fast Web Applications. However if you would like to refresh the Ajax concepts a bit more before going ahead read this by Jesse James Garrett, who gave this technique a usable name: Ajax.
Implementing Ajax in your Web Application:
You can use Ajax in your Web application in various ways. One is to use the API of the XMLHttpRequest object directly in your own custom JavaScript. The main problem with this method is that you would need to deal with all compatibility issues of different browsers (which is the most hectic and pissing thing according to my own experience). The other way is to use various JavaScript libraries such as DWR, Prototype, Sajax, and Ajax.NET. The JavaScript libraries provide Ajax services and at the same time take care of the differences between various browsers. And the easiest way is to use the Ajax facilities of Ruby on Rails. Ruby on Rails offers you some powerful built-in Ajax features that makes using Ajax in your Web Application no extra burden anymore.
Pros and Cons of using Ajax in your web application:
Pros:
- Optimum use of Bandwidth: Since Ajax makes it possible to render a small portion of the page; therefore you can avoid displaying all the data at the same time by sending heavy request and getting heavy response each time a page loads. Instead, you can send smaller requests and refresh a smaller portion of the page. As the size of the requests (i.e. the data that is being transmitted and received over the network between the client and the server) reduces the bandwidth is also utilized properly.
- Responsiveness: Ajax uses DOM (Document Object Model) to manipulate the page currently displayed in your browser within the browser itself instead of creating the whole loop of sending each request to the server and receiving the response with all the unnecessary data that is finally going to be the same as it is in the current page. Thus the Web applications using Ajax become more responsive.
Cons:
- Unexpected "Back" button behavior: As the Ajax Web applications update the smaller portion of the web page, so if you trigger a few Ajax actions in a page, and expect to return to the previous page with the single Back button click then it might not be possible.
Developers have implemented various solutions to this problem. These solutions can involve using invisible IFRAMEs to invoke changes that populate the history used by a browser's back button. Google Maps, for example, performs searches in an invisible IFRAME and then pulls results back into an element on the visible web page. Although the World Wide Web Consortium (W3C) has not formally deprecated the IFRAME element which was introduced in HTML 4, the standard recommends the OBJECT tag instead. - Problem in Book-marking a page: Since the Ajax web pages are updated dynamically, it becomes difficult to book mark a state of the page.
Steps in which Rails implements the Ajax:
- A page containing some Ajax is loaded in the Browser.
- User triggers an Ajax activity in the Browser by clicking some button, modifying some data on the page, or clicking any link etc.
- The client sends the corresponding data required to be processed at the server side using XMLHttpRequest. This is done by the Ajax engine in between the client and the server. This data transmission is called Asynchronous data transmission because the data is actually not sent by the normal HttpRequest object, rather it is sent by the XMLHttpRequest object and through the Ajax Engine and not directly by your browser.
- The data received and processed at the server side by the corresponding action handler. The handlers generate and send back the response using XMLHttpResponse object. The response may be some HTML fragment, plain text etc.
- The Ajax engine receives the response on the client-side. The JavaScript that is required for this process is auto generated by Rails!! You need not write anything.
- A small portion of the user interface changes with the response. The portion that is updated or replaced in this action is mostly in a <div> tag.
Helper Methods to Implement Ajax in Rails:
Although Rails provides various helper methods that can be used to implement Ajax in the views of you web application, the most simple is the link_to() method. But before you can actually use the Ajax in your views of your web application, you need to activate the JavaScript. You need to include the following single line of code to activate the JavaScript for a view:
<%= javascript_include_tag :defaults %>
before the </head> tag.
Now suppose you have a web application that displays the list of the books that you have in your library, and one of the views in your application is there displaying the list of the books. You want to remove certain books that you know are outdated and are no longer in stock. Suppose you have a template called list.rhtml in the app/views/books directory which is displaying the list of the books you have. Now, to add a link to delete the books, you need to add the following lines of code in the list.rhtml template:
<%= link_to 'Destroy', {:action => 'destroy', :id => book}, :confirm => "Are you sure that the book is no more in stocks and you want to delete it?" %>;
The above code, adds an additional link besides show and edit (show and edit links become available just by scaffolding the books table) links in the lists of the books. On clicking the link, the JavaScript popup windows appear with the message that you have given in the "confirm" parameter. On clicking OK, as expected the corresponding book is deleted from the books database. There is another method similar to link_to() called link_to_remote(). This method differs in the number of parameters that it takes. In addition to the name of the link and the action parameter it also takes a DOM element ID. This element is the one the content of which you want to replace in the view after the corresponding action is performed. So, if you want to reload just the list of the books that you have in your library, instead of the whole page, you can replace the above line of code by the following:
<%= link_to_remote 'Destroy', {:action => 'destroy1', :id => list, :update => 'books'}, :confirm => "Are you sure that the book is no more in stocks and you want to delete it?" %>
Did you note the extra :update parameter ? The difference is now that on clicking the Destroy link now, the server will return an updated list of books. And this new list will be placed in the list DOM object which represents the list of books displayed on the page.
Note: The destroy1 action is yet undefined. So we need to define it in the app/controllers/books_controller.rb as follows:
def destroy1
Book.find(@params[:id]).destroy
render :partial => "books"
end
Let’s see what each does here: The first line deletes the book record from the database. The render method in the second line returns the response to the browser. The partial parameter of the render() method ensures that the webpage is reloaded partially. So here the updated list of the remaining books in the library is returned to the browser and is displayed without any need to reload the whole page.
So this is how the Rails uses the Ajax to build powerful and real fast web applications. Although there is much more to explore in this area and use in live applications for you, I would stop here only for now. I hope you people get motivated to some extent so that you start using it. I have already started. Looking forward to my reader’s comments and suggestions also. I would also be coming up with some more useful methods that you can use while using Ajax with Rails.
Till then "Happy Reading and Happy Programming :-) "
Tuesday, August 15, 2006
Migrations - A Unique Feature Offered By Rails Framework
How many times has it happened to you that you decided to start your site development or any other e-business that required a database backend and then as the time passed and your business grew, you felt that the database selection was not good enough or the features that are offered by the newer database version or some other database are now a days more powerful and well suited to your business than it was few years back? It happens right!! And it is very natural because the technology changes day after day and so do the database management. You always want to move ahead to acquire better and more powerful functionality and features available.
But when it comes to migrating from one database to another, it’s a real "Pain in the ASS!!" I hope you would agree to that. And no wonder that this pain holds you back from going ahead and upgrading your database to the newer version and thus ultimately compromising with the revenue. And this is more serious a problem for smaller e-business where you cannot afford the cost involved.
Is there a way to get rid of all that pain while migrating from one DB to another according to the requirement change from time to time? The Answer after Rails coming to rescue us is YES!!
Rails has provided an in-built support to the Database Migration. Before showing you how, let us define what Migration is.
What is Migration: It is a feature of Rails framework that allows you to define the changes in the database schema of your web-application using the Ruby Language and thus making it possible for you to migrate from one database to another as well as upgrading or downgrading the database versions. This also allows you to keep a version control system to keep your database changes synchronized with core code.
If we list the Advantages of Migration in Rails, we can have the following points:
- Help you achieve Database Independency: No matter what database (MySQL, PostgreSQL or SQLite) you switch to at any point in time, once you have your database schema ready in Ruby, you need not change anything further.
- Cuts the cost of hiring different people having knowledge of the different databases: As the syntax conversion with database change is taken care of internally by the Ruby code.
- Liberty to choose different databases: Allows you to choose the best database suited for your application by trying different ones easily as you can easily switch between different versions of a database.
- Facilitates the synchronization of the same database schema in a team of developers working on a single project: As when someone in your team makes a change to the data abase schema, other just need to update, and execute the command rake migrate. And that's done!!
- Helps you upgrade the database version on the live servers (production servers): While upgrading the database on the production servers you just need to run the command rake migrate. And that's also done!!
If the above discussion makes you think that you should be using the Rails Migration then please go ahead, otherwise just chuck it here itself and wait for the nightmare where you would need to upgrade to a new database!!
Those who realized the impotrence and potential, please come ahead.....
Now that you have realized the impotrence, without wasting a single second let's see how to use Rails Migration in 3 simple steps:
Step 1: Creating Migration using the migration generator: Run the ruby generator, ruby script/generate migration my_migration to create a new migration file. This would create a new file named as versionnumber_migration_file_name.rb in the db/migrations directory of your project. For example, if you want to create a migration file to upgrade the version of the database you are using in which you want to create a new table called entity, then you could run the following command: ruby script/generate migration add_entity_table. A file named as 002_add_entity_table.rb (assuming you already have a migration file, if not the number will be 001 instead of 002) will be created in the db/migrate directory.
Note:
- The Migrations has a naming convention and that is that the name of the migrations that you are creating should either contain underscores (my_migration) or they should be camel-cased (MyMigration)
- The name of a migration should be unique and should not match with the name of any of the existing models class failing which the rake migrate will fail.
Step 2: Writing the migration code: In the newly created migration file in the db/migrations directory, define "self.up" and "self.down" methods. These methods tell the system what to do when a database version is upgraded to next version or is downgraded to a lower version.
Note: The version that we are talking abouit here is not the version of the database exactly. Instead it is the verdsion of the migration that we are maintaining in the project. The version number here are 001, 002, and so on. This is a means of keeping a version control over the database scema changes thoughout the development of the project.
For example, if you open the newly created file, 002_add_entity_table.rb, you would see the following lines of code in it:
class AddEntityTable <>
def self.up
end
def self.down
end
end
Note that there is no code at all in the self.up and self.down methods. Now our need is to create a new table whenever we upgrade the database version, so we will write the create_table query in the self.up method as follows:
class AddEntityTable <>
def self.up
create_table :entity do ¦e¦
e.column :first_name, :string
e.column :last_name, :string
e.column :joining_date, :date
end
def self.down
endend
Still, you can see that the self.down method doesn't have a body. Now suppose our need is to delete the newly created table (most obvious) while downgrading to the current version again, then we need to write a drop_table query in the self.down method as follows:
class AddEntityTable <>
def self.up
create_table :entity do ¦e¦
e.column :first_name, :string
e.column :last_name, :string
e.column :joining_date, :date
end
def self.down
drop_table :entity
end
end
Step 3: Run the rake migrate command: That's it dude!! You are done with the migration part. Mind blowing!! Right?
You can also downgrade the database version in the similar manner. You simply need to run the rake command again with the version number to which you want to downgrade. For example, if we want to rollback to the older version, say version 1, we will run the following command: rake migrate VERSION=1. This command will run the self.down of the 002 version file and your database will be at the version 1 again.
Note: The rake migrate VERSION=versionnumber, command takes the keyword VERSION all in caps only.
Wondering how rake works? Here is the explanation!!
The command, rake migrate VERSION=versionnumber, automatically decides what to do. What I mean to say is, if you run this command passing a version number lower than the version which you are currently in, then it will run the self.down methods of the all the migration files starting from current migration version file up till versionnumber-1 migration file. On the other hand if you run this command passing a version number higher than the version which you are currently in, then it will run the self.up methods of the all the migration files starting from current migration version up till versionnumber-1 migration file.
Thursday, August 10, 2006
Why to Use Generics in JAVA
Even if you are a good programmer then also you must have faced this problem sometimes or the other, and if you are not then of course many a times :-). Actually, it’s not about being a good or bad programmer, but it’s just about how attentive you are while writing the code using Collections. And the Java.lang.ClassCastException occurs while downcasting any java object. i.e. you are actually trying to cast an object which is at a comparatively higher level in the parent-child hierarchy into an object which is at lover level of parent-child hierarchy.
You must be thinking, why the hell I am talking about this java Exception explicitly while discussing the Generics feature. The reason is that Generics are the most useful mans of avoiding this ClassCastException exception while working with Collections. In a way Collections are the main application area of Generics. This is because Collections can store anything i.e. Objects. And when you have objects stored in Collections, such as Hashtable, you obviously need to remember what you inserted and what you have to take out. The main problem is that, when you take the object out, then you need to explicitly cast that object into an appropriate type, depending on what you inserted initially before you can perform any operation specific to the type of the Object.
Let’s look at the following code snippet:
1 public void createCollection () {
2 ArrayList testlist = new ArrayList();
3 testlist.add(new String("sanjeev"));
4 testlist.add(new Integer(9)); // to cause runtime ClassCastException
5 iterateThroughCollection(testlist);
6 }
7
8
9 protected void iterateThroughCollection(Collection collection) {
10 Iterator i = collection.iterator();
11 while (i.hasNext()) {
12 String element = (String) i.next();
13 }
14 }
Here first we declared a Collection ArrayList (using method createCollection()) testlist and put two items in it. Note that one item is an Integer and the other is a String type. Then we are iterating through the collection and taking out each element of it and typecasting it to String object.
So what happens when you actually execute the createCollection() method? Of course you would get a ClassCastException!! This is because; as I mentioned the Collection classes store each element as Object. This is advantageous in terms of providing us the flexibility and abstraction, but looking a little deeper you realize that it requires you doing an extra work of figuring out what Objects were inserted in collection before they can be used in your code after taking them out of the collection.
Let’s see why??
Going back to the code snippet again now, there are two Objects in the testlist collection, an Integer and a String. But as they are "stored" as Objects, we require typecasting them explicitly to the original data types (see line 12 of the code snippet above). And this is something which the developer should take care of as downcasting (Object to whatever type you inserted originally, String or Integer in this case) is not checked by the compiler. In this way there is always chance that the developers forget and a ClassCastException is thrown, as it happens in the above example. The above code will compile successfully but will fail at the runtime throwing ClassCastException at the line 12; while trying to cast the Integer Object to String Object!!
Now, if you can relate any of your past nightmares to this problem and feel that it would be worthy to remove this problem altogether without taking much of an effort and without increasing the complexity of the code, go ahead and read the rest of the post, otherwise just chuck it here itself and wait for the next nightmare to come back to this line again. As I feel eventually you will have to come!!!
Formers please move ahead in every aspect (reading as well as smart coding practice :-))
Using Generics you can avoid such problems while using Collections in JAVA. Before getting into deep explanation, let’s have a proper definition. Here it goes:
Note: If you are a C++ programmer, you can relate Generics to the C++ templates, as it is similar to the C++ templates in syntax and semantics both and comparatively a little simpler. But there is a difference. The difference lies in the fact that templates generate a new class for each specialization while Generics don't. Also Generics, unlike C++ templates, do not permit “template metaprogramming.”
Generics in Java 1.5: Generics in Java is a means of creating parameterized objects, i.e. specifying the objects that a class can work with at the time of declaring the objects. This is done by passing parameters in angular braces <>. These objects are then evaluated at the compile time itself unlike at the run time as is the case without Generics.
OK....I don't think those lines gave you very clear idea.
Let’s look at it with another example:
ArrayList<string> testlist = new ArrayList<string>();
Look at the above declaration. Did you notice
Thus, we achieved the following out of it:
- Eliminated an unsafe cast and a number of extra parentheses form your code.
- Inserted valuable information (that the testlist will only contain the String objects) about the object in the declaration itself.
- Provided ability to the compiler to verify at the compile time that the type constraints are not violated at run time.
- Improved readability and robustness.
So before closing, let's see the above example with Generics:
1 public void createCollection() {
2 ArrayList<string> testlist = new ArrayList<string>();
3 testlist.add(new String("sanjeev"));
4 // testlist.add(new Integer(9)); this line wont compile as the ArrayList is already declared of String Type and here you are trying to put in Integer.
5 iterateThroughCollection(testlist);
6 }
7
8
9 protected void iterateThroughCollection(Collection<string>
10 Iterator<string>
11 while (i.hasNext()) {
12 String element = i.next();
13 }
14 }
At the end, I would like to say the following hoping that you will also agree to this:
In the next post related to Generics, I would like to tell you some rules in generics which if you keep in mind, will help you to use generics efficiently. Till then, Happy Reading and Happy Programming. :-)
Tuesday, August 08, 2006
Time to Get On Rails with Ruby
Before going into the explanation, why we should start using Ruby or start rolling on Ruby with Rails, let us get an idea of what is Ruby and Rails separately. So here we go with the definitions:
Ruby: This is another (not as, "Yet Another!!”) purely Object-oriented programming language originated in Japan in the early 1990s. The main feature that makes it popular among the web application developers or any developer in general is that it offers you cleaner and simper syntax. And a clean and simple syntax of course makes your application far easier to maintain, debug, test, and scale, all which is required to make our life simpler. Ruby is a mixture of good features of various other languages. For example, it is as easy to use and learn as Python, as conceptually elegant as Smalltalk, and as pragmatic as Perl. You can easily get an idea about the growing popularity of Ruby by the fact that now more and more English language books and documentation have become available on Internet about a programming language developed in Japan.
Rails: Rails is another a framework that itself is developed in ruby which is required to web applications with database-backend. So what? Is that the immediate question in your mind? Quite obvious. You need some solid reasons to even thinking of trying something. So here goes the simple reason: The very sentence that makes me go and try the framework immediately is that you actually can develop a web application many a times faster than using any other Java framework available till date and that also without compromising the quality you offer to your end-users!
But how?
Ruby language itself is the partial answer. This is because Ruby offers many a features that are impossible in other languages or too hectic to implement in some languages. And when coordinated with Rails, the advantage is doubled. This is because Rails exploit all the explicit features that Ruby offers to become allow you to develop faster and stronger web applications. Rails is able to exploit the feature because of the two basic principles that it follows: less lines of code and convention over configuration.
Less Software: As the word says means you need to write fewer lines of code to implement maximum of the functionality required by your application. After all which developer doesn't want to write as fewer lines of code as possible to get the maximum work done!! And this is made possible by combined power of the Rails framework and Ruby library. Smaller code in turn reduces the time you waste in debugging, understanding, maintaining, and enhancing your application in future.
We will also have a look at how is that shorter code to get maximum functionality possible with Rails.
Convention over Configuration: Rails do not require you to put hell lot of settings in various configuration files that are required by your current framework to run your application. Rails put an end to the complex XML configuration files. Rails instead believe in few simple conventions. As the conventions are understood by Rails, it automatically picks up the settings it requires to run your web application. This is made possible by utilizing the information that is already contained by your web application code and the backend database.
If it hasn’t clicked in your mind till now that you should explore further or try to use Ruby On Rails to enhance your web applications, then chuck it here itself, otherwise wait for the next post shortly coming up. In the next post, I would try to explain you Ruby On Rails with a small example so that you can try that yourself.