NetBeans Database Explorer

May 26, 2011

  1. Are you working on sql queries often?
  2. Are you executing queries with different database servers (MySQL, PostgreSQL, Oracle)?
  3. Are you working on an application which should be tested on multiple databases?

Answer to all the 3 questions is : NetBeans Database Explorer.

Yes, NetBeans Database Explorer is the correct choice for you. Database Explorer is a simple database administrative tool which allows you to manage the live database connections, browse and visualize the database structures represented in the organized hierarchical form.
It allows you to perform common operations on database structures. This includes

  • execute sql statements and queries.
  • create, modify & delete tables
  • add, delete columns, indexes.
  • populating tables data
  • view tables data.
  • grabbing and recreating table structures.

Database Explorer
This blog illustrates how to set up a connection with MySQL database from the NetBeans IDE. Once connected, you can start use the SQL editor to execute queries, view the table data.

Go to Window -> Services(Short cut : Ctrl+5) –  This will open a Services window, select Databases

NetBeans Services Window - Database Explorer

Select New Connection by right click the Databases.

DB New Connection

Database Driver Selection
The IDE comes bundled with drivers for MySQL, PostgreSQL, Oracle database servers. Select an appropriate JDBC drivers from the Driver combo box. NetBeans provides an option New Driver, with this you can import other database JDBC drivers and start interact with them.

New Connection Wizard

Connection Wizard
Driver Name – JDBC Driver used to connect to the database server.
Host – Machine where the database server is running. It can be a remote machine also.
Port – Port number that the db server listens on.
Database – Name of the database you want to connect.(Optional)
Username/Password – Authentication credentials to connect & access the database.

Connection Customize Wizard

Exploring Tables
Once the database connection was succeeded, browse and explore the tables/views present in the database. You can select a particular table and execute in the SQL editor by clicking View Data

Table View Data

Browse and select required columns of the table and view the data.

View Selected Column Data

Query Output Window
This will display the executed query results. From here, you can Insert or Delete Rows.

Query Output Window

SQL Editor
The advantage of this SQL Editor, you can execute multiple queries in a single shot and every query results are shown in tabbed views.

SQL Editor

Multiple SQL Command Editors
With this you can connect and execute queries from different databases in different SQL command editors. Select a required connection db from the Connection combo box to execute the query.

Multiple SQL Command Tab

SQL History
It’s very useful to execute some of the queries which was written previously.

SQL History

Overall, It is a good tool to manage the databases easily. Henceforth no need to go with separate tool for SQL editor, lets use NetBeans as both Java IDE as well as SQL IDE.

This document completely demonstrates with latest version(7.0) 0f  NetBeans. You can download it from here.



Hibernate Basics & Simple Example

April 13, 2011

Hibernate is an open source Object Relational Mapping framework used to transform from object oriented programming to relational databases.

It supports object oriented concepts Association, Polymorphism, Inheritance & Composition through persistent classes. Also Hibernate facilitates to write queries in variant forms,  HQL(Hibernate Query Language), Native SQL, or Criteria API.

The following question may raise while learning about Hibernate.

What’s the difference between JDBC & Hibernate?

JDBC API’s are easy to use for small projects. But Hibernate framework is well suited for enterprise level applications and acts as mediator between object & relational approaches.

Hibernate Architecture
Hibernate performs the following operations;

  • opens a database connection
  • converts HQL statements to database specific statements
  • execute it  & receive data from the database
  • result set being mapped to equivalent java objects to be processed by application.
Hibernate Architecture

Hibernate Architecture

This blog gives you a basic idea about how to connect and use Hibernate with a database.

Simple Application : BookApps

BookApps is an example application. This application main function is to add, update, delete, retrieve books from the database.

Note : This application uses a PostgreSQL database, therefore run an instance of PostgreSQL. Go through this blog, to know the basics of PostgreSQL. Also download and run the same.

Click here to download the hibernate & unzip the file hibernate-distribution-3.6.0.Final-dist.zip

Hibernate configuration file : hibernate.cfg.xml
This will have all the information to connect Hibernate to a database. In this example, PostgreSQL database is used.
Note : Hibernate configurations can also be done through hibernate.properties file.

 <!--<span class="hiddenSpellError" pre=""-->DOCTYPE hibernate-configuration PUBLIC
 "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
 <a href="http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd"</a>>

 <hibernate-configuration>
 <session-factory>
 <!-- Database connection settings -->
 jdbc:postgresql://localhost:5432/postgres
 <property name="connection.driver_class">org.postgresql.Driver</property>
 <property name="connection.username">postgres</property>
 <property name="connection.password">******</property>
 <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>

 <!-- SQL dialect - generate SQL for a particular database -->
 <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>

 <!-- Echo all executed SQL statements -->
 <property name="show_sql">true</property>

 <!-- Enable Hibernate's automatic session context management -->
 <property name="current_session_context_class">thread</property>
<!-- Mapping resource configuration files -->
 <mapping resource="src/com/bookstore/bookapp.hbm.xml"/>
 </session-factory>
 </hibernate-configuration>
 

Property to drop and re-create the database schema on startup

<property name="hbm2ddl.auto">create</property>

By adding this property, hibernate will create tables for you. This will be executed only once ie) after first run comment this code. because every time tables will get dropped.

Hibernate mapping file : bookapp.hbm.xml
For all objects to be persisted in the database,  Hibernate needs this XML file. The mapping file tells Hibernate how to load and store objects, what table in the database it has to access and what columns in the table should use.
This file should be saved with .hbm.xml file extension.

 <?xml version="1.0"?>
 <!--<span class="hiddenSpellError" pre=""-->DOCTYPE hibernate-mapping PUBLIC
 "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 <a href="http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"</a>>

 <hibernate-mapping package="com.bookstore">
 BookDetails" table="BookStore">
 BookId">
 <generator/>
 </id>
 bookName" type="string" column="BookName"/>
 authorName" type="string" column="AuthorName"/>
 bookCost" type="int" column="BookCost"/>
 </class>
 </hibernate-mapping>
 

Persistent class : BookDetails.java
The persistent class works in the form of POJO(Plain Old Java Object) model. It’s a java bean class having getter and setter methods to access the properties of an app.

 package com.bookstore;

 public class BookDetails{
 private int bookId;
 private String bookName;
 private String authorName;
 private int bookCost;

 BookDetails(){
 }

 public int getBookId(){
 return bookId;
 }
 public void setBookId(int bookId){
 this.bookId = bookId;
 }

 public String getBookName(){
 return bookName;
 }
 public void setBookName(String bookName){
 this.bookName = bookName;
 }

 public String getAuthorName(){
 return authorName;
 }
 public void setAuthorName(String authorName){
 this.authorName = authorName;
 }

 public int getBookCost(){
 return bookCost;
 }
 public void setBookCost(int bookCost){
 this.bookCost = bookCost;
 }

 public String toString(){
 StringBuffer sb = new StringBuffer();
 sb.append("BookName : ").append(bookName);
 sb.append(" ,AuthorName : ").append(authorName);
 sb.append(" , BookCost : ").append(bookCost);
 return sb.toString();
 }
 }
 

Hibernate communication with database : HibernateUtil.java
Load the hibernate configuration file and mapping files automatically, create a session factory from the configured object, create a session to execute the HQL query and get the result set of java objects.

 package com.bookstore;

 import org.hibernate.SessionFactory;
 import org.hibernate.cfg.Configuration;

 public class HibernateUtil {

 private static final SessionFactory sessionFactory;

 static {
 try {
 // Create the SessionFactory from hibernate.cfg.xml
 sessionFactory = new Configuration().configure().buildSessionFactory();
 } catch (Throwable ex) {
 // Make sure you log the exception, as it might be swallowed
 System.err.println("Initial SessionFactory creation failed." + ex);
 throw new ExceptionInInitializerError(ex);
 }
 }

 public static SessionFactory getSessionFactory() {
 return sessionFactory;
 }

 }

Application class : BookApp.java
A simple application class which performs CRUD operations in the database through HQL, Persistent Objects, Native SQL & Criteria API.

package com.bookstore;

 import java.util.List;
 import java.util.Iterator;
 import org.hibernate.Session;
 import org.hibernate.Query;
 import org.hibernate.Criteria;
 import org.hibernate.criterion.Restrictions;
 public class BookApp{
 public static void main(String args[]){
 BookMethods bm = new BookMethods();

 //Adding books
 bm.addBook("Professional Hibernate","Eric Pugh, Gradecki", 350);
 bm.addBook("Hibernate in Action","Christian Bauer, Gavin King", 499);
 bm.addBook("Java Persistence With Hibernate","Bauer, Gavin King", 423);
 bm.addBook("Begining Hibernate","Dave Minter, Jeff Linwood", 1500);

 //Listing added books
 bm.listBooks();

 //Getting book details for a particular book name.
 bm.getBookDetails("Hibernate in Action");

 //To see no. of books
 bm.countBook();

 //Update particular book cost
 bm.updateBook("Begining Hibernate",1000);

 //Listing available books
 bm.listBooks();

 //Deleting a book
 bm.deleteBook("Java Persistence With Hibernate");

 //Listing available books After executing delete
 bm.listBooks();
 }
 }

 class BookMethods{
 //Using persistent objects to store data into the database.
 public void addBook(String bookName, String authorName, int bookCost){
 Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 session.beginTransaction();
 BookDetails bd = new BookDetails();
 bd.setBookName(bookName);
 bd.setAuthorName(authorName);
 bd.setBookCost(bookCost);
 session.save(bd);
 session.getTransaction().commit();
 }

 //Using persistence object to delete a row from the database.
 public void deleteBook(String bookName){
 Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 session.beginTransaction();
 List list = session.createQuery("from BookDetails where bookName='"+bookName+"'").list();
 Iterator itr = list.iterator();
 while(itr.hasNext()){
 BookDetails bd = (BookDetails)itr.next();
 System.out.println("delete : "+bd);
 session.delete(bd);
 }
 session.getTransaction().commit();
 }

 //Using Criteria API to update the book cost
 public void updateBook(String bookName, int bookCost){
 Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 session.beginTransaction();
 Criteria cri = session.createCriteria(BookDetails.class);
 cri = cri.add(Restrictions.eq("bookName", bookName));
 List list = cri.list();
 BookDetails bd = (BookDetails)list.iterator().next();
 bd.setBookCost(bookCost);
 session.update(bd);
 session.getTransaction().commit();
 }

 //Using HQL - Hibernate Query Language
 public void getBookDetails(String bookName){
 Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 session.beginTransaction();
 Query q = session.createQuery("from BookDetails where bookName=:bn");
 q.setString("bn", bookName);
 List list = q.list();
 System.out.println("Getting Book Details using HQL. \n"+list);

 //The above query can also be achieved with Criteria & Restrictions API.
 Criteria cri = session.createCriteria(BookDetails.class);
 cri = cri.add(Restrictions.eq("bookName", bookName));
 list = cri.list();
 System.out.println("Getting Book Details using Criteria API. \n"+list);

 session.getTransaction().commit();
 }

 //Aggregate function.
 public void countBook(){
 Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 session.beginTransaction();
 List list = session.createQuery("select count(*) from BookDetails").list();
 System.out.println("Aggregate function count \n"+list);
 session.getTransaction().commit();
 }

 //Native SQL Query
 public void listBooks(){
 Session session = HibernateUtil.getSessionFactory().getCurrentSession();
 session.beginTransaction();
 List list = session.createSQLQuery("select * from BookStore").addEntity(BookDetails.class).list();
 Iterator itr = list.iterator();
 while(itr.hasNext()){
 BookDetails bd = (BookDetails)itr.next();
 System.out.println(bd);
 }
 session.getTransaction().commit();

 }
 }

Compile & Run the simple application : BookApp.

Setting classpath
Following jars are required to compile and run the code. Copy the below code and save it in a file called classpath.bat & run this batch file.

set HIBERNATE_HOME=C:\Hibernate\hibernate-distribution-3.6.0.Final
set CLASSPATH=%HIBERNATE_HOME%\hibernate3.jar;%HIBERNATE_HOME%\lib\required\dom4j-1.6.1.jar;%HIBERNATE_HOME%\lib\required\slf4j-api-1.6.1.jar;%HIBERNATE_HOME%\lib\jpa\hibernate-jpa-2.0-api-1.0.0.Final.jar;%HIBERNATE_HOME%\lib\required\commons-collections-3.1.jar;%HIBERNATE_HOME%\lib\required\javassist-3.12.0.GA.jar;%HIBERNATE_HOME%\lib\required\jta-1.1.jar;%HIBERNATE_HOME%\lib\required\antlr-2.7.6.jar;.;C:\PostgreSQL\postgresql-9.0-801.jdbc3.jar

Compile all the java files

C:\Hibernate\hibernate-distribution-3.6.0.Final\example\booksapp>javac -d . src\com\bookstore\*.java

Run the app

C:\Hibernate\hibernate-distribution-3.6.0.Final\example\booksapp>java com.bookstore.BookApp

Output

SLF4J: Failed to load class “org.slf4j.impl.StaticLoggerBinder”.
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.

Hibernate: select max(BookId) from BookStore
Hibernate: insert into BookStore (BookName, AuthorName, BookCost, BookId) values (?, ?, ?, ?)
Hibernate: insert into BookStore (BookName, AuthorName, BookCost, BookId) values (?, ?, ?, ?)
Hibernate: insert into BookStore (BookName, AuthorName, BookCost, BookId) values (?, ?, ?, ?)
Hibernate: insert into BookStore (BookName, AuthorName, BookCost, BookId) values (?, ?, ?, ?)

Hibernate: select * from BookStore

BookName : Professional Hibernate ,AuthorName : Eric Pugh, Gradecki , BookCost : 350
BookName : Hibernate in Action ,AuthorName : Christian Bauer, Gavin King , BookCost : 499
BookName : Java Persistence With Hibernate ,AuthorName : Bauer, Gavin King , BookCost : 423
BookName : Begining Hibernate ,AuthorName : Dave Minter, Jeff Linwood , BookCost : 1500

Hibernate: select bookdetail0_.BookId as BookId0_, bookdetail0_.BookName as BookName0_, bookdetail0_.AuthorName as AuthorName0_, bookdetail0_.BookCost as BookCost0_ from BookStore bookdetail0_ where bookdetail0_.BookName=?
Getting Book Details using HQL.
[BookName : Hibernate in Action ,AuthorName : Christian Bauer, Gavin King , BookCost : 499]

Hibernate: select this_.BookId as BookId0_0_, this_.BookName as BookName0_0_, this_.AuthorName as AuthorName0_0_, this_.BookCost as BookCost0_0_ from BookStore this_ where this_.BookName=?
Getting Book Details using Criteria API.
[BookName : Hibernate in Action ,AuthorName : Christian Bauer, Gavin King , BookCost : 499]

Hibernate: select count(*) as col_0_0_ from BookStore bookdetail0_
Aggregate function count
[4]

Hibernate: select this_.BookId as BookId0_0_, this_.BookName as BookName0_0_, this_.AuthorName as AuthorName0_0_, this_.BookCost as BookCost0_0_ from BookStore this_ where this_.BookName=?
Hibernate: update BookStore set BookName=?, AuthorName=?, BookCost=? where BookId=?

Hibernate: select * from BookStore
BookName : Professional Hibernate ,AuthorName : Eric Pugh, Gradecki , BookCost : 350
BookName : Hibernate in Action ,AuthorName : Christian Bauer, Gavin King , BookCost : 499
BookName : Java Persistence With Hibernate ,AuthorName : Bauer, Gavin King , BookCost : 423
BookName : Begining Hibernate ,AuthorName : Dave Minter, Jeff Linwood , BookCost : 1000

Hibernate: select bookdetail0_.BookId as BookId0_, bookdetail0_.BookName as BookName0_, bookdetail0_.AuthorName as AuthorName0_, bookdetail0_.BookCost as BookCost0_ from BookStore bookdetail0_ where bookdetail0_.BookName=’Java Persistence With Hibernate’
delete : BookName : Java Persistence With Hibernate ,AuthorName : Bauer, Gavin King , BookCost : 423
Hibernate: delete from BookStore where BookId=?

Hibernate: select * from BookStore
BookName : Professional Hibernate ,AuthorName : Eric Pugh, Gradecki , BookCost : 350
BookName : Hibernate in Action ,AuthorName : Christian Bauer, Gavin King , BookCost : 499
BookName : Begining Hibernate ,AuthorName : Dave Minter, Jeff Linwood , BookCost : 1000

C:\Hibernate\hibernate-distribution-3.6.0.Final\example\booksapp>

Click here to view/download the source of book apps.


PostgreSQL Basics

February 10, 2011

PostgreSQL is an ORDBMS for managing data stored in relations. It offers many features such as complex queries, triggers, transactional integrity, multiversion concurrency control.
Also, PostgreSQL can be extended by the user in many ways, data types, functions,aggregate functions, index methods.

PostgreSQL uses a client/server model.

server : postgres is a database server program, running as a process to perform these actions.,

  • manages the database files.
  • accept database connections from the client applications.
  • performs database actions on behalf of the clients.

client : front end application wants to perform database operations, client applications could be

  • text-oriented tool
  • database maintenance tool
  • a web server that accesses the database to display web pages.

The PostgreSQL server can handle multiple concurrent connections from clients.

Download & Install the PostgreSQL for windows OS, click here.

After completing the installation, open the client SQL Shell(psql) for executing the queries.  Following  snapshots will guide you.

Provide the correct authentication details to login psql

Basic PSQL commands

Learn these basic psql slash commands which will aid you to use SQL Shell easily. Also these commands are completely different from MySQL.

Command
Actions
\l List all databases
\c dbname Connect to new database.
\dt To view list of relations/tables
\d tablename Describe the details of given table.
\h Get a help on syntax of SQL commands
\? Lists all psql slash commands.
\set System variables list.
\q Quit psql

Basic SQL operations in PostgreSQL

Database Creation & Deletion
To create a new database

createdb dbname

Remove the database

dropdb dbname

CRUDCreate Read Update Delete

These are the four basic functions to be performed on relational databases. Almost Postgres CRUD  SQL statements are similar to MySQL statements.

Create – Creating table & inserting the values.
Table Creation : Books

CREATE TABLE Books(BookId int, BookName text, BookCost int);

Table Values Insertion

INSERT INTO Books VALUES(1001, 'Who will cry when you die', 299);
INSERT INTO Books VALUES(1002, 'Practical PostgreSQL', 1722);
INSERT INTO Books VALUES(1003, 'Beginning Databases with PostgreSQL', 1080);

Read – Retrieve table data.

SELECT * FROM Books;

bookid |              bookname               | bookcost
——–+————————————-+———-
1001 | Who will cry when you die           |      299
1002 | Practical PostgreSQL                |     1722
1003 | Beginning Databases with PostgreSQL |     1080
(4 rows)

Update

UPDATE Books SET BookCost=1100 WHERE BookId=1003;
SELECT * FROM Books WHERE BookId=1003;

bookid |              bookname               | bookcost
——–+————————————-+———-
1003 | Beginning Databases with PostgreSQL |     1100
(4 rows)

Delete – Delete row(s) from the relation.

DELETE FROM Books WHERE BookId=1001;
SELECT * FROM Books;

bookid |              bookname               | bookcost
——–+————————————-+———-
1002 | Practical PostgreSQL                |     1722
1003 | Beginning Databases with PostgreSQL |     1100
(3 rows)

Other Significant Features

Inheritance
PostgreSQL allows you to implements table inheritance. This should be defined with a special keyword INHERITS in the table design.

CREATE TABLE BookAuthors(Author1 text, Author2 text) INHERITS (Books);

Table inheritance has certain limits in inserting data into table. As Postgres won’t allow to perform such operations. Lets illustrates the possible fail & success cases.

case 1: You can’t insert directly into BookAuthors table.

INSERT INTO BookAuthors VALUES('Richard','Matthew');

ERROR:  invalid input syntax for integer: “Richard”
LINE 1: INSERT INTO BookAuthors VALUES(‘Richard’,’Matthew’);

case 2: It does not allow to insert into child table columns (Author1, Author2) while inserting data into parent table.

INSERT INTO Books VALUES(1006, 'Greatness Guide', 400, 'Robin','Sharm
a');

ERROR:  INSERT has more expressions than target columns
LINE 1: …T INTO Books VALUES(1006, ‘Greatness Guide’, 400, ‘Robin’,’S…
^

Possible valid insert statements are

case 1: This will insert data into Books table alone.

INSERT INTO Books VALUES(1006, 'Greatness Guide', 400);

case 2: This will insert data into both parent & child tables, Books & BookAuthors.

INSERT INTO BookAuthors VALUES(1005, 'PostgreSQL 9.0 High Performance
', 1500, 'Gregory Smith');

Retrieving the child table BookAuthors will also retrieve the parent table column values.

select * from BookAuthors;

bookid |            bookname             | bookcost |    author1    | author2
——–+———————————+———-+—————+———
1005 | PostgreSQL 9.0 High Performance |     1500 | Gregory Smith |
(1 row)

ONLY Keyword
This keyword indicates that the query should be run only on the specified table(Books) and not tables in the inheritance hierarchy. ie., Insertion done through child table will not be shown here.

Note : ONLY Keyword will be applicable for SELECT, UPDATE & DELETE.

SELECT * FROM ONLY Books;

bookid |              bookname               | bookcost
——–+————————————-+———-
1002 | Practical PostgreSQL                |     1722
1004 | Beginning Databases with PostgreSQL |     1100
(2 rows)

Row(BookId : 1005) is not shown here because this has been inserted through child table BookAuthors.

Composite Types
This represents the structure of a row or record. PostgreSQL allows composite types to be used as the same ways of simple types are used. For instance, a column of a table can be declared as a composite type. See the below example.

Creating two composite types FullName & Address, each has 2 & 3 columns respectively.

 CREATE TYPE FullName AS(FirstName text, LastName text);
 
 CREATE TYPE Address AS(DoorNo text, StreetName text, Place text);
 

\dT command can be used to see the defined composite types.

List of data types
Schema |   Name   | Description
——–+———-+————-
public | address  |
public | fullname |
(2 rows)

Defined composite types FullName & Address being used in the Employee table creation.

CREATE TABLE Employee(EmpId int PRIMARY KEY, EmpName FullName, EmpAddress Address);

Inserting data into the composite column values can be done in two ways.
ROW – expression used to construct composite values
() – Simply include the composite values in the bracket.

 INSERT INTO Employee VALUES(100, ROW('Neil','Matthew'), ROW('No. 6','Vivekanandar Street','Dubai'));
 

Inserted data.

empid |    empname     |              empaddress
——-+—————-+—————————————
100 | (Neil,Matthew) | (“No. 6″,”Vivekanandar Street”,Dubai)
(1 row)

Want to access a field of a composite column, use this notation. (composite_type_name).fieldname. For multi-table queries you can use table name as well, like this (table_name.composite_type_name).fieldname

 select empid, (empname).firstname, (empaddress).place from Employee;
 

empid | firstname | place
——-+———–+——-
100 | Neil      | Dubai
(1 row)

ORDBMS

February 8, 2011

Object Relational Database Management System(ORDBMS) is a database management system acts as a bridge between objects & relational databases.

The main objective of ORDBMS is to achieve the benefits of both the relational and the object models such as scalability, support for oo features & custom types.

It directly supports object oriented paradigms objects, classes, inheritances , polymorphism in the database schemas & query language. Also has the ability to extensible with user-defined types & methods.

Advantages

  • Supports rich data types such as audio, video and image files.
  • Access and manipulate the complex data types in the database without breaking the rule of relational model.

Disadvantages

  • Complexity

ORDBMS vendors in the market : Oracle, SQL Server, PostgreSQL, Informix. Among these, PostgreSQL is an Open Source ORDBMS.

equals & hashcode methods in Java

January 7, 2011

Java Object class allows you to override equals & hashcode methods based on your application requirements. These methods play an essential role in real time applications.

You must have to implement these two methods when objects are stored into collections. Suppose if you are failed to implement or implemented incorrectly then the collections may behave strangely and hard to debug.

Methods have certain principles & contracts to follow while overriding.

public boolean equals(Object obj)

  • Used for comparison between two objects i.e., check whether the passing parameter object is equal to current object.
  • It has some principles to follow for non-null object references, they are reflexing, symmetric, transitive, consistent, null comparison.

public int hashCode()

  • Returns the hashcode of an object, its an integer value of object memory address.
  • This technique is called hashing used to efficiently store and retrieve the enormous data in the collections like Hashtable, HashSet, HashMap.

You can read elaborate description @ java api doc

The most significant contract between equals & hashcode is

If two objects are equal then they must have the same hashcode, however the reverse is not true.

If two objects have the same hashcode does not mean that they are equal.

Note

  • If you override equals method in the class, you must override the hashcode also.
  • If a field is not used in equals(), then it must not be used in hashcode() method.

In the BookStore app, the class Book has two fields bookName & authorName both of them were used in equals & hashcode method to identify the two objects are equivalent. However the following implementation is wrong.

Field bookName only used to identify the equality

public boolean equals(Object obj) {

…..

…..

Book bobj = (Book) obj;

if (bookName == bobj.bookName || (bookName != null && bookName.equals(bobj.bookName))) {

return true;

}

}

return false;

}

Both fields bookName & authorName were used to manipulate hashcode.

public int hashCode() {

int hash = 7;

hash = (37 * hash) + (null == bookName ? 0 : bookName.hashCode());

hash = (37 * hash) + (null == authorName ? 0 : authorName.hashCode());

return hash;

}

Lets see how to override methods in our simple BookStore app.

EqualsHashCodeBookApp.java

Stored the instances of Book class into the collection List and properly implemented the equals & hashcode method to retrieve the correct object data from the List.

import java.util.ArrayList;
import java.util.List;

 class Book {

 String bookName;
 String authorName;

 Book() {
 }

 Book(String bookName, String authorName) {
 this.bookName = bookName;
 this.authorName = authorName;
 }

 @Override
 public boolean equals(Object obj) {
 if (this == obj) {
 return true;
 }

 if (obj == null || (obj.getClass() != this.getClass())) {
 return false;
 }

 Book bobj = (Book) obj;
 if (bookName == bobj.bookName || (bookName != null && bookName.equals(bobj.bookName))) {
 if (authorName == bobj.authorName || (authorName != null && authorName.equals(bobj.authorName))) {
 return true;
 }
 }
 return false;
 }

 @Override
 public int hashCode() {
 int hash = 7;
 hash = (37 * hash) + (null == bookName ? 0 : bookName.hashCode());
 hash = (37 * hash) + (null == authorName ? 0 : authorName.hashCode());
 return hash;
 }

 @Override
 public String toString() {
 StringBuffer sb = new StringBuffer();
 sb.append("bookName=").append(bookName);
 sb.append(",authorName=").append(authorName);
 return sb.toString();
 }
 }

 public class EqualsHashCodeBookApp {

 public static void main(String a[]) {
 Book b1 = new Book("C Programming", "Dennis Ritchie");
 Book b2 = new Book("C++", "Stroustroup");
 Book b3 = new Book("Java", "James Gosling");
 Book b4 = new Book("JavaScript", "Douglas Crockford");
 Book b5 = new Book("OOAD", "Grady Booch");


 boolean b1eqb1 = b1.equals(b1);
 boolean b1eqb2 = b1.equals(b2);
 boolean b2eqnewobj = b2.equals(new Book("C++", "Stroustroup"));
 boolean b1eqnull = b1.equals(null);

 System.out.println("Object b1 equals b1 :: " + b1eqb1);
 System.out.println("Object b1 equals Object b2 :: " + b1eqb2);
 System.out.println("Object b2 equals new Book(\"C++\", \"Stroustroup\") :: " + b2eqnewobj);
 System.out.println("Object b1 equals null :: " + b1eqnull);

 List<Book> list = new ArrayList<Book>();
 list.add(b1);
 list.add(b2);
 list.add(b3);
 list.add(b4);
 list.add(b5);
 System.out.println("List of books : " + list);
 System.out.println("List of books : " + list.size());
 System.out.println("Hashcode of object b1 : " + b1.hashCode());
 System.out.println("System Hashcode of object b1 : " + System.identityHashCode(b1));
 //check whether this book is available in the list.
 boolean b = list.contains(new Book("Java", "James Gosling"));
 System.out.println("Book new Book(\"Java\", \"James Gosling\") : " + b);
 System.out.println("Index of Book(\"Java Programming\", \"James Gosling\") : " + list.indexOf(new Book("Java Programming", "James Gosling")));
 System.out.println("Index of object b3 : " + list.indexOf(b3));
 }
 }

Output

Object b1 equals b1 :: true

Object b1 equals Object b2 :: false

Object b2 equals new Book(“C++”, “Stroustroup”) :: true

Object b1 equals null :: false

List of books : [bookName=C Programming,authorName=Dennis Ritchie, bookName=C++,authorName=Stroustroup, bookName=Java,authorName=James Gosling, bookName=JavaScript,authorName=Douglas Crockford, bookName=OOAD,authorName=Grady Booch]

Hashcode of object b1 : 649340260

System Hashcode of object b1 : 1671711

Book new Book(“Java”, “James Gosling”) : true

Index of Book(“Java Programming”, “James Gosling”) : -1

Index of object b3 : 2

Overridden equals & hashcode method will get invoked while executing the below lines to verify the equivalent object data is present in the collection list.

list.contains(new Book(“Java”, “James Gosling”));

list.indexOf(new Book(“Java Programming”, “James Gosling”)

Returns the hashcode value from the overridden method.

b1.hashCode();

Returns the system hashcode value. i.e., actual memory address of an object

System.identityHashCode(b1);

2010 Year – Learnings & Reviews

December 30, 2010

Learning from experiences can be done in either way.

+ve Learning – Learn from good things happened around you. This enhances your +ve actions or decisions.
-ve Learning – Learn from bad things happened around you. This helps to evade your -ve actions or decisions in the future.

Want success or achieve your goals in life; you should have both technical as well as personal development skills. You have to shape your mind to tackle all the hindrances in the goal path.
I have summarized few points which would be useful for readers.

Our Words
Be careful of your words when you interact or communicate with surrounding people. At any cause your words should not hurt or offend anyone. This includes your parents, sisters, brothers and close friends too.

Perhaps your situations made you react offensively, but you never know this could lead to fragile relationships. Even though they hurt you, don’t repeat the same to them. Always keep this in mind.

Think TWICE before you speak. ~ Mani

Assumption

Assumption is the WORST enemy for us.

Don’t assume things either officially or personally.  Officially, it may navigate to wrong path and end up in rework. Personally, creates a bad rapport with souls around you.

Just spend time to examine and know the factual.

Be Patience
Some ugly moments might stir up anger. Try to control and be rational.

It’s better to be silent instead of uttering hurtful words.

Change

மாற்றங்கள் மனிதர்களுக்கு தேவை. ~ மணி

Change is required for every human being. Yes, it’s hard to accept because our minds can’t accept the change easily. Also, make sure that your change doesn’t affect others and be wary of this decision.

Measure your endurance how flexible are you when conditions, circumstances change suddenly.

Egoism

Leave your ego at the feet before interacting with your friends. ~ Mani

Want to be more successful in life – Remove your egos.
It’s very hard to do it, but this will give you a nice relationship between your friends.

Passion
Drive in the path of your passion or interests, put 100% efforts in interested areas. You can reach the satisfied success in your life. Don’t suppress your feelings instead express it and live your life.

Minimum settings to succeed –

Do not work on anything you are not interested in.

Adaptability
Adaptability is essential for everyone; you have to personalize yourself for the conditions and circumstances. Also, have the ability to respond effectively to the challenging environment.

More precisely, have to somewhat adjust your character to cope up with current situation, this would benefit in long-term.

Audacity
Have the courage to face any actions in your life. Take calculated risk to go to the next level of your life. Do not panic. The more success resides in the risk parts of life.

Year-End Review
It’s time to examine what you have accomplished this year.  Self evaluate with following questions.

  • Career goals – Did I achieve my goals?
  • What I have learned?
  • What new skills/technologies I have learned?
  • Am I happy/satisfy with my current work?
  • What’s my dream – Did I make any progress to achieve?

Once completed the review, you should know yourself where you are, where you have been, where you want to go.

Have some specific goals and action steps to progress next year.

Note: I would suggest readers to add your learning to this blog as comments, in fact will benefit others.

Planning to share more technical info, do track by subscribing.

Wish you Happy New Year 2011.

Coding to Interfaces

December 18, 2010

Coding to an interface rather than to implementation. This makes your software/application easier to extend. In other words, your code will work with all the interface’s subclasses, even ones that have not been created yet.

Anytime if you are writing code that interacts with subclasses, you have two choices either; your code directly interacts with subclasses or interacts with interface. Like this situation, you should always favor/prefer to coding to an interface, not the implementation.

I have created a simple example with JDK classes & interface which demonstrates its benefits.

CodingToAnInterface.java

 import java.util.Hashtable;
 import java.util.LinkedHashMap;
 import java.util.Map;

 public class CodingToAnInterface {

 public static void main(String[] args) {
 // Coding to a class : Creating new instance of Hashtable & Assign it to the class.
 Hashtable subject = new Hashtable();
 CodingToClass c2c = new CodingToClass();
 subject = c2c.addSubject(subject);
 System.out.println("CodingToClass : Hashtable : subject : "+subject);

 // Coding to an interface : Creating new instance of Hashtable & Assign it to the Map interface object.
 Map subj = new Hashtable();
 CodingToIntf c2i = new CodingToIntf();
 subj = c2i.addSubject(subj);
 System.out.println("CodingToInterface : Instantiated Hashtable : subject : "+subj);

 // Now, we have a requirement to show subjects in the order it was inserted. Let’s make a simple change from Hashtable to LinkedHashMap.
 subj = new LinkedHashMap();
 subj = c2i.addSubject(subj);
 System.out.println("CodingToInterface : Instantiated LinkedHashMap : subject : "+subj);
 }
 }

 class CodingToClass{
 // Method argument & return type are defined with class name Hashtable. This allows only Hashtable class as parameter.
 public Hashtable addSubject(Hashtable subject) {
 subject.put("Subject1", 50);
 subject.put("Subject2", 70);
 subject.put("Subject3", 60);
 subject.put("Subject4", 80);
 return subject;
 }
 }

 class CodingToIntf{
 // Method argument & return type are defined with interface Map. This allows to send various possible interface subclasses.
 public Map addSubject(Map subject) {
 subject.put("Subject1", 50);
 subject.put("Subject2", 70);
 subject.put("Subject3", 60);
 subject.put("Subject4", 80);
 return subject;
 }
 }
 

Output

CodingToClass : Hashtable : subject : {Subject4=80, Subject3=60, Subject2=70, Subject1=50}
CodingToInterface : Instantiated Hashtable : subject : {Subject4=80, Subject3=60, Subject2=70, Subject1=50}
CodingToInterface : Instantiated LinkedHashMap : subject : {Subject1=50, Subject2=70, Subject3=60, Subject4=80}

In the above example, initially assigned Hashtable object to interface Map object instead of Hashtable class. Later, we have a requirement to show the subjects in the order we have inserted into it. So we need to change the code and this can be easily achieved here by simply changed the instantiation part from Hashtable to LinkedHashMap without touching addSubject part.
However in coding to class, we have to change all the places where Hashtable is being used.

Instead of your code being able to work with only specific subclass called Hashtable, you are able to work with more generic Map interface. In future, it’s easier to change into some other sub class of Map interface.

Advantages

  • App/Software is easier to extend
  • Adds Flexibility to your App.
  • Helps to maintain the loose coupling of code.

Thread vs Runnable

December 10, 2010

Thread is a block of code which can execute concurrently with other threads in the JVM. You can create and run a thread in either ways; Extending Thread class, Implementing Runnable interface.

Both approaches do the same job but there have been some differences. Almost everyone have this question in their minds: which one is best to use? We will see the answer at the end of this post.

The most common difference is

  • When you extends Thread class, after that you can’t extend any other class which you required. (As you know, Java does not allow inheriting more than one class).
  • When you implements Runnable, you can save a space for your class to extend any other class in future or now.

However, the significant difference is.

  • When you extends Thread class, each of your thread creates unique object and associate with it.
  • When you implements Runnable, it shares the same object to multiple threads.

The following example helps you to understand more clearly.

ThreadVsRunnable.java


class ImplementsRunnable implements Runnable {

 private int counter = 0;

 public void run() {
 counter++;
 System.out.println("ImplementsRunnable : Counter : " + counter);
 }
 }

 class ExtendsThread extends Thread {

 private int counter = 0;

 public void run() {
 counter++;
 System.out.println("ExtendsThread : Counter : " + counter);
 }
 }

 public class ThreadVsRunnable {

 public static void main(String args[]) throws Exception {
 //Multiple threads share the same object.
 ImplementsRunnable rc = new ImplementsRunnable();
 Thread t1 = new Thread(rc);
 t1.start();
 Thread.sleep(1000); // Waiting for 1 second before starting next thread
 Thread t2 = new Thread(rc);
 t2.start();
 Thread.sleep(1000); // Waiting for 1 second before starting next thread
 Thread t3 = new Thread(rc);
 t3.start();

 //Creating new instance for every thread access.
 ExtendsThread tc1 = new ExtendsThread();
 tc1.start();
 Thread.sleep(1000); // Waiting for 1 second before starting next thread
 ExtendsThread tc2 = new ExtendsThread();
 tc2.start();
 Thread.sleep(1000); // Waiting for 1 second before starting next thread
 ExtendsThread tc3 = new ExtendsThread();
 tc3.start();
 }
 }

Output of the above program.

ImplementsRunnable : Counter : 1
ImplementsRunnable : Counter : 2
ImplementsRunnable : Counter : 3
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1
ExtendsThread : Counter : 1

In the Runnable interface approach, only one instance of a class is being created and it has been shared by different threads. So the value of counter is incremented for each and every thread access.

Whereas, Thread class approach, you must have to create separate instance for every thread access. Hence different memory is allocated for every class instances and each has separate counter, the value remains same, which means no increment will happen because none of the object reference is same.

When to use Runnable?
Use Runnable interface when you want to access the same resource from the group of threads. Avoid using Thread class here, because multiple objects creation consumes more memory and it becomes a big performance overhead.

Apart from this, object oriented designs have some guidelines for better coding.

  • Coding to an interface rather than to implementation. This makes your software/application easier to extend. In other words, your code will work with all the interface’s subclasses, even ones that have not been created yet.
  • Interface inheritance (implements) is preferable – This makes your code is loosely coupling between classes/objects.(Note : Thread class internally implements the Runnable interface)

Example: coding to an interface.

Map subject = new HashMap();

Assigning HashMap object to interface Map,  suppose in future if you want to change HashMap to Hashtable or LinkedHashMap you can simple change in the declaration part is enough rather than to all the usage places. This point has been elaborately explained here.

Which one is best to use?

Ans : Very simple, based on your application requirements you will use this appropriately. But I would suggest, try to use interface inheritance i.e., implements Runnable.

Example : 

Map subject = new HashMap();

Assigning HashMap object to interface Map,  suppose in future if you want to change HashMap to Hashtable or LinkedHashMap you can simple change in the declaration area is enough rather than to all the usage places. I will explain this elaborately in the upcoming post.

 

Struts Example

December 7, 2010

Let’s see, how to develop a simple web application using Struts. Prior to this, want to learn about Struts basics go through these blogs Struts Basics & Struts Dispatch Action.
Before starting the application, download Tomcat-6.0.29.zip & Struts-1.3.10.zip

Follow the basic steps to configure struts in tomcat.

  • Unzip the tomcat zip file, you can get the folder apache-tomcat-6.0.29
  • Unzip the struts zip file, from that copy all jars from struts-1.3.10\lib directory to apache-tomcat-6.0.29\lib directory.
  • Copy the struts-1.3.10\src\taglib\src\main\resources\META-INF\tld\struts-html.tld file and place it under apache-tomcat-6.0.29\webapps\examples\WEB-INF directory.

Tomcat zip has the sample examples of jsp/servlet, which has been present under webapps/examples directory. We can use the same for developing our simple struts web application(Books Store).

In this app you are able to view the complete details of available books by accessing the url http://localhost:8080/examples/showbooks.do. From this page, you can do the basic operations like Add/Edit/Delete book.

Following steps are tell you how to implement this web app, what are the settings required to configure and where to place the action classes & jsp files.

web.xml or Deployment Descriptor.
We have to configure about ActionServlet in web application. This can be done by adding the following servlet definition to the apache-tomcat-6.0.29\webapps\examples\WEB-INF\web.xml file.

 <servlet>
 <servlet-name>action</servlet-name>
 <servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
 <init-param>
 <param-name>config</param-name>
 <param-value>/WEB-INF/struts-config.xml</param-value>
 </init-param>
 <init-param>
 <param-name>validate</param-name>
 <param-value>true</param-value>
 </init-param>
 <load-on-startup>1</load-on-startup>
 </servlet>
 

Servlet Mappings tells when the action should be executed.

 <servlet-mapping>
 <servlet-name>action</servlet-name>
 <url-pattern>*.do</url-pattern>
 </servlet-mapping>
 

To use HTML tag lib, you must add the following tag library entries into web.xml file.

 <taglib>
 <taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
 <taglib-location>/WEB-INF/struts-html.tld</taglib-location>
 </taglib>
 

struts-config.xml
This file is used to configure the struts framework details of a web application contains form-bean, action-mappings definitions.Add this file under apache-tomcat-6.0.29\webapps\examples\WEB-INF directory.

 <?xml version="1.0" encoding="ISO-8859-1" ?>
 <!DOCTYPE struts-config PUBLIC
 "-//Apache Software Foundation//DTD Struts Configuration 1.3//EN"
 "http://struts.apache.org/dtds/struts-config_1_3.dtd" >

 <struts-config>
 <!-- Form Bean Definitions -->
 <form-beans>
 <form-bean name="BookForm" type="com.books.BookForm"/>
 </form-beans>

 <!--  Action Mapping Definitions  -->
 <action-mappings>
 <action path="/showbooks"
 type="com.books.ShowBooks"
 validate="false"
 scope="session">
 <forward name="success" path="/jsp/books/books.jsp"/>
 </action>

 <!-- Example of Struts Dispatch Action : has the extra attribute parameter-->
 <action path="/bookaction"
 type="com.books.BookActions"
 parameter="actionMethod"
 name="BookForm"
 validate="false"
 scope="session">
 <forward name="addBook" path="/jsp/books/addbook.jsp"/>
 <forward name="editBook" path="/jsp/books/editbook.jsp"/>
 <forward name="deleteBook" path="/jsp/books/deletebook.jsp"/>
 </action>
 </action-mappings>
 </struts-config>
 

ShowBooks.java
Action class used to show the book details page. In this example, I used class objects to store the book details you can use database to store the content of your app. This class been invoked when you access this url http://localhost:8080/examples/showbooks.do from the web browser.

 package com.books;

 import org.apache.struts.action.ActionForm;
 import org.apache.struts.action.ActionMapping;
 import org.apache.struts.action.ActionForward;
 import org.apache.struts.action.Action;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 public class ShowBooks extends Action
 {
 public ActionForward execute(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Show Books List");
 Books b = Books.getInstance();
 request.setAttribute("booksList", b.getBookList());
 return mapping.findForward("success");
 }
 }
 

Books.java
Class used to store the book details i.e., app data is persisted in jvm memory, this will get lost once you restarted the tomcat server. So you can use databases to store your application data.

 package com.books;

 import java.util.Map;
 import java.util.HashMap;
 import java.util.List;
 import java.util.ArrayList;
 import java.util.Iterator;
 import java.util.Set;

 class Books {

 int bookIdCount = 1000;
 Map<Integer, StoreBook> bookMap = new HashMap<Integer, StoreBook>();
 private static Books books = null;

 private Books() {
 }

 public static Books getInstance() {
 if (books == null) {
 books = new Books();
 }
 return books;
 }

 public void storeBook(String bookName, String authorName, int bookCost) {
 StoreBook sb = new StoreBook();
 bookIdCount++;
 sb.addBook(bookIdCount, bookName, authorName, bookCost);
 bookMap.put(bookIdCount, sb);
 }

 public void updateBook(int bookId, String bookName, String authorName, int bookCost) {
 StoreBook sb = bookMap.get(bookId);
 sb.updateBook(bookName, authorName, bookCost);
 }

 public Map searchBook(int bookId) {
 return bookMap.get(bookId).getBooks();
 }

 public void deleteBook(int bookId) {
 bookMap.remove(bookId);
 }
 // Inner Class used to persist the app data ie) book details.
 class StoreBook {

 private String bookName;
 private String authorName;
 private int bookCost;
 private int bookId;

 StoreBook() {
 }

 public void addBook(int bookId, String bookName, String authorName, int bookCost) {
 this.bookId = bookId;
 this.bookName = bookName;
 this.authorName = authorName;
 this.bookCost = bookCost;
 }

 public void updateBook(String bookName, String authorName, int bookCost) {
 this.bookName = bookName;
 this.authorName = authorName;
 this.bookCost = bookCost;
 }

 public Map getBooks() {
 Map books = new HashMap();
 books.put("BookId", this.bookId);
 books.put("BookName", this.bookName);
 books.put("AuthorName", this.authorName);
 books.put("BookCost", this.bookCost);
 return books;
 }
 }

 public List getBookList() {
 List booksList = new ArrayList();
 Set s = bookMap.keySet();
 Iterator itr = s.iterator();
 while (itr.hasNext()) {
 booksList.add(bookMap.get((Integer)itr.next()).getBooks());
 }
 return booksList;
 }
 }
 


BookForm.java

Form bean class has the getter & setter methods of corresponding form input elements. With this, you can get and set the value of form elements in the Action class.

 package com.books;

 import org.apache.struts.action.ActionForm;

 public class BookForm extends ActionForm {

 private String bookName;
 private String authorName;
 private int bookCost;
 private int bookId;

 public BookForm() {
 super();
 }

 public String getBookName() {
 return bookName;
 }
 public void setBookName(String bookName) {
 this.bookName = bookName;
 }

 public String getAuthorName() {
 return authorName;
 }
 public void setAuthorName(String authorName) {
 this.authorName = authorName;
 }

 public int getBookCost() {
 return bookCost;
 }
 public void setBookCost(int bookCost) {
 this.bookCost = bookCost;
 }

 public int getBookId() {
 return bookId;
 }
 public void setBookId(int bookId) {
 this.bookId = bookId;
 }
 }
 

BookActions.java
It’s an example of struts DispatchAction class, each and every action/function of book has equivalent methods to process it. This class been invoked when you access these url’s from the web browser.
Add Book : http://localhost:8080/examples/bookaction.do?actionMethod=AddBook
Edit Book : http://localhost:8080/examples/bookaction.do?actionMethod=EditBook&bookId=1008
Delete Book : http://localhost:8080/examples/bookaction.do?actionMethod=DeleteBook

 package com.books;

 import org.apache.struts.action.ActionForm;
 import org.apache.struts.action.ActionMapping;
 import org.apache.struts.action.ActionForward;
 import org.apache.struts.actions.DispatchAction;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;

 import java.util.Map;

 public class BookActions extends DispatchAction
 {
 public ActionForward AddBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Add Book Page");
 return mapping.findForward("addBook");
 }

 public ActionForward EditBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Edit Book Page");
 int bookId = Integer.parseInt(request.getParameter("bookId"));

 Books b = Books.getInstance();
 Map bookDet = b.searchBook(bookId);

 //Used form bean class methods to fill the form input elements with selected book values.
 BookForm bf = (BookForm)form;
 bf.setBookName(bookDet.get("BookName").toString());
 bf.setAuthorName(bookDet.get("AuthorName").toString());
 bf.setBookCost((Integer)bookDet.get("BookCost"));
 bf.setBookId((Integer)bookDet.get("BookId"));
 return mapping.findForward("editBook");
 }

 public ActionForward SaveBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Save Book");
 //Used form bean class methods to get the value of form input elements.
 BookForm bf = (BookForm)form;
 String bookName = bf.getBookName();
 String authorName = bf.getAuthorName();
 int bookCost = bf.getBookCost();

 Books b = Books.getInstance();
 b.storeBook(bookName, authorName, bookCost);
 return new ActionForward("/showbooks.do", true);
 }

 public ActionForward UpdateBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Update Book");
 BookForm bf = (BookForm)form;
 String bookName = bf.getBookName();
 String authorName = bf.getAuthorName();
 int bookCost = bf.getBookCost();
 int bookId = bf.getBookId();

 Books b = Books.getInstance();
 b.updateBook(bookId, bookName, authorName, bookCost);
 return new ActionForward("/showbooks.do", true);
 }

 public ActionForward DeleteBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Delete Book");
 int bookId = Integer.parseInt(request.getParameter("bookId"));
 Books b = Books.getInstance();
 b.deleteBook(bookId);
 return new ActionForward("/showbooks.do", true);
 }
 }
 

books.jsp
File used to show the available books in the app store. This page is being forwarded from the ShowBooks action class.

 <%@ page import="java.util.HashMap"%>
 <%@ page import="java.util.Map"%>
 <%@ page import="java.util.List"%>
 <%@ page import="java.util.ArrayList"%>
 <%@ page import="java.util.Iterator"%>
 <html>
 <body>
 <p><b>Struts Example - Simple Book Store App</b></p>
 <b>Available Books</b>
 <form name="bookform" action="/examples/bookaction.do">
 <table style="background-color:#82CAFA;">
 <tr style="color:yellow;"><th>&nbsp;</th><th>Book Name</th><th>Author Name</th><th>Book Cost</th></tr>
 <%List bookList = (ArrayList)request.getAttribute("booksList");
 Iterator itr = bookList.iterator();
 while(itr.hasNext()){
 Map map = (HashMap)itr.next();
 %>
 <tr><td><input type="radio" name="bookId" value='<%=map.get("BookId")%>' onclick="javascript:enableEditDelete();"></td>
 <td><%=map.get("BookName")%></td><td><%=map.get("AuthorName")%></td><td><%=map.get("BookCost")%></td>
 </tr>
 <%}%>
 </table>
 </p>
 <p>
 <table><tr>
 <td><input type="submit" name="actionMethod" value="AddBook" /></td>
 <td><input type="submit" name="actionMethod" id="editbutton" value="EditBook" disabled="true" /></td>
 <td><input type="submit" name="actionMethod" id="deletebutton" value="DeleteBook" disabled="true" onclick="return checkDelete();" /></td>
 </tr></table>
 </form>
 </p>
 <script>
 function checkDelete(){
 return confirm("Are u sure to delete this book..?");
 }
 function enableEditDelete(){
 document.getElementById('editbutton').disabled=false;
 document.getElementById('deletebutton').disabled=false;
 }
 </script>
 </body>
 </html>
 

addbook.jsp
Web page used to add a new book to the app store.

 <%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
 <html>
 <body>
 <p><b>Struts Example - Simple Book Store App</b></p>
 <b>Add Book</b>
 <html:form>
 <table style="background-color:#82CAFA;">
 <tr><td>Book Name</td><td><html:text property="bookName" value=""/></td></tr>
 <tr><td>Author Name</td><td><html:text property="authorName" value=""/></td></tr>
 <tr><td>Book Cost</td><td><html:text property="bookCost" value=""/></td></tr>
 </table>
 </p>
 <p>
 <table><tr>
 <td><input type="submit" name="actionMethod" value="SaveBook" /></td>
 </tr></table>
 </html:form>
 </p>
 </body>
 </html>
 


editbook.jsp

In this page, used HTML tag lib, form bean class(BookForm) will take care of filling the form input elements.

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
 <html>
 <body>
 <p><b>Struts Example - Simple Book Store App</b></p>
 <b>Edit Book</b>
 <html:form>
 <table style="background-color:#82CAFA;">
 <tr><td>Book Id</td><td><html:text property="bookId" disabled="true"/></td></tr>
 <tr><td>Book Name</td><td><html:text property="bookName"/></td></tr>
 <tr><td>Author Name</td><td><html:text property="authorName"/></td></tr>
 <tr><td>Book Cost</td><td><html:text property="bookCost"/></td></tr>
 </table>
 </p>
 <p>
 <table><tr>
 <td><input type="submit" name="actionMethod" value="UpdateBook" /></td>
 </tr></table>
 </html:form>
 </p>
 </body>
 </html>
 

Note:

  • All the jsp files should present under directory apache-tomcat-6.0.29\webapps\examples\jsp\books.
  • Compile all the java files, and place the created class files to apache-tomcat-6.0.29\webapps\examples\WEB-INF\classes

All the codes specified in this blog will compile & work perfectly without any issues. Just download and try it. It’s very easy to learn and build applications in Struts.

Sample Output of Book Store Apps.

Available Books in Store

Add Book Web Page

Add Book

Edit Book Web Page

Edit Book


Struts Dispatch Action

November 29, 2010

DispatchAction provides a mechanism to group related functions/actions into a single Action class. Therefore each and every action has to be specified in separate methods. This eliminates the creation of multiple independent action classes for each function/action.

DispatchAction class itself has the implementation of execute() method and its being used to managed to delegating the request to one of the methods in the derived Action class. This method invocation can be done based on the request “parameter“.

Let’s see an example of DispatchAction.

struts-config.xml

parameter – attribute is used to delegate the request to corresponding method of the BookAction class. So define this value with appropriate name.

 <action path="/books"
 type="com.books.BookAction"
 parameter="actionMethod"
 validate="false"
 scope="request">
 <forward name="addBook" path="/jsp/book/addbook.jsp"/>
 <forward name="editBook" path="/jsp/book/updatebook.jsp"/>
 <forward name="saveBook" path="/jsp/book/save.jsp"/>
 <forward name="deleteBook" path="/jsp/book/deletebook.jsp" />
 </action>
 

BookAction.java

It eliminates the execute method entirely.  Because it directly implements the desired methods, those custom methods have same signature as execute method.

The class BookAction extends org.apache.struts.actions.DispatchAction

 import org.apache.struts.action.ActionForm;
 import org.apache.struts.action.ActionMapping;
 import org.apache.struts.action.ActionForward;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 import org.apache.struts.actions.DispatchAction;

 public class BookAction extends DispatchAction
 {
 public ActionForward addBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Add Book Page");
 return mapping.findForward("addBook");
 }

 public ActionForward editBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Edit Book Page");
 return mapping.findForward("editBook");
 }

 public ActionForward saveBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Save Book Page");
 return mapping.findForward("saveBook");
 }

 public ActionForward deleteBook(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) {
 System.out.println("Delete Book Page");
 return mapping.findForward("deleteBook");
 }
 }
 

bookdetails.jsp

This page has four different links for doing different actions say Add/Edit/Save/Delete books. Every individual action has to be uniquely represented by the request parameter actionMethod.

 <html>
 <head>
 Book Details
 <body>
 <a href="/books.do?actionMethod=addBook">Add Book</a>
 <a href="/books.do?actionMethod=editBook">Edit Book</a>
 <a href="/books.do?actionMethod=saveBook">Save Book</a>
 <a href="/books.do?actionMethod=deleteBook">Delete Book</a>
 </body>
 </head>
 </html>

Note: I didn’t enclosed addBook, editBook, saveBook, deleteBook jsp files with this post. You can design and implement in your own way. Here am just explaining the flow of how DispatchAction class works in Struts.

New to Struts, want to learn Struts Basics. Go here https://manikandanmv.wordpress.com/2010/11/18/struts-basics/

Complete Struts Example, go here  https://manikandanmv.wordpress.com/2010/12/07/struts-example/