PART-III
(PUBLISHED IN DEVELOPER IQ - September2005)
Now we will move on to the main process of any enterprise application: Data Persistence. For this we have to initialize our data access framework, manage resources, handle various exceptions and if anything goes wrong, we must roll-back so as to save the existing data.
Spring comes with a family of data access frameworks that integrates well will variety of data access technologies like JDBC, Java Data Objects and Object Relational Mapping (ORM) tools like Hibernate, OJB, iBatis etc.,
Many J2EE application servers and even web servers provide a 'dataSource' via Jndi name. To configure the spring bean with the Jndi name of our 'dataSource' and use its connection pooling facility 'JndiObjectFactoryBean' is used. When a DataSource is not present, we need a connection pooling bean that implements 'dataSource'. For this purpose we use 'dbcp.BasicDataSource' is used. By using this we can have a 'dataSource' with connection pooling independent of application server.
To perform unit-tests in our data access code, spring comes with a very lightweight 'dataSource' implementation class: 'DriverManagerDataSource'. This class can be easily configured for unit tests as,
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(driver);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
These properties can be configured in the spring configuration file also.
----------------------------------------------
Spring comes with its own data access framework. Spring separates the fixed and variant parts of data access process into two distinct classes : template and callback. Template manages the fixed part of our framework like data connection, managing resources, controlling transaction etc., while the Callback defines the things that are specific to our application like creating statements, binding parameters etc.,
The template class of Spring is 'JdbcTemplate'. A 'dataSource' is provided inside JdbcTemplate.
An example of database connection using 'JdbcTemplate' is shown below. Here we are using 'MySql' database. The MySql database can be downloaded from http://www.mysql.com. Download mysql4.1 and MyODBC-3.51 (ODBC Connector) install these in the hard disk. For Mysql give a username('root') and a password ('sql').
Then start the 'My Sql Console Line Client' from programs and type the password.
The prompt will be changed to mysql,
mysql> show databases;
Two databases will be present default: mysql and test.
mysql> use test;
We will get message as 'Database changed'. Next create table in test database as follows
mysql> create table table1(name text, place text);
We will get the message 'Query OK, 0 rows affected'. Now we have created a table in mysql database, set the path and classpath as before and edit the program
----- f:\sprindemo\datacon.java
import javax.sql.*;
public interface datacon
{
public DataSource dbcon();
}
----------------------------------------
f:\sprindemo\dataconimpl.java
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.*;
import org.springframework.jdbc.support.*;
import javax.sql.*;
public class dataconimpl implements datacon
{
private DataSource dataSource;
public void setDataSource(DataSource ds)
{
dataSource = ds;
}
public DataSource dbcon()
{
return dataSource;
}
}
----------------------------------------
f:\sprindemo\datacon.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>sun.jdbc.odbc.JdbcOdbcDriver</value>
</property>
<property name="url">
<value>jdbc:odbc:test</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value>sql</value>
</property>
</bean>
<bean id="datacon" class="dataconimpl">
<property name="dataSource">
<ref local="dataSource"/>
</property>
</bean>
</beans>
----------------------------------------
f:\sprindemo\springservlet.java
import java.io.*;
import javax.sql.*;
import java.sql.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.xml.*;
import org.springframework.core.io.*;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.*;
import org.springframework.jdbc.support.*;
public class springservlet extends HttpServlet
{
public void doPost(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException
{
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
String a = req.getParameter("text1");
String b = req.getParameter("text2");
String c = req.getParameter("combo1");
String d = req.getParameter("combo2");
try
{
System.out.println("Wait...");
Resource res = new ClassPathResource("datacon.xml");
BeanFactory factory = new XmlBeanFactory(res);
datacon bean1 = (datacon)factory.getBean("datacon");
DataSource ds=bean1.dbcon();
if(d.equals("add"))
{
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("insert into table1 values('"+a+"','"+b+"') ");
out.println("Record Added");
}
if(d.equals("delete"))
{
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("delete from table1 where name='"+a+"' ");
out.println("Record Deleted");
}
if(d.equals("find"))
{
List list1;
JdbcTemplate jt = new JdbcTemplate(ds);
list1=jt.queryForList("select * from table1 where name='"+a+"'");
Iterator i=list1.iterator();
while(i.hasNext())
{
Object ob = i.next();
out.println(ob.toString());
}
}
if(d.equals("update"))
{
if(c.equals("name"))
{
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("update table1 set table1.place='"+b+"'where
table1.name='"+a+"' ");
}
if(c.equals("place"))
{
JdbcTemplate jt = new JdbcTemplate(ds);
jt.execute("update table1 set table1.name='"+a+"'where
table1.place='"+b+"' ");
}
out.println("Record Updated");
}
}
catch(Exception e1)
{System.out.println(""+e1);}
}
}
----------------------------------------
f:\sprindemo\springservlet.htm
<html>
<body bgcolor="pink">
<form method=post
action="http://localhost:8080/
servlet/springservlet">
Name : <input type=text name="text1"> <br><br>
Place : <input type=text name="text2"> <br><br>
Criterion :
<select name="combo1" size=1>
<option value="name">Name
<option value="place">Place
</select> <br><br>
<select name="combo2" size=1>
<option value="add">Add
<option value="delete">Remove
<option value="find">Find
<option value="update">Update
</select> <br><br>
<input type=submit>
</form>
</body>
</html>
The deployment procedure is same as before compile the all the files datacon.java, dataconimpl.java and springservlet.java and copy all the class files and the xml file datacon.xml to g:\tomcat5\webapps\root\web-inf\classes. Copy the html file to g:\tomcat5\webapps\root. Add entry to web.xml file.
Start Tomcat server and open browser
and type url as http://localhost:8080/ servletclient.htm. We will get a two textboxes, two comboboxes and a 'submit' button. Type name and place in textboxes, select 'add' from combobox and click 'submit' button. We will get message as 'Record Added'
---------------------------------------- Spring provides integration for many of the ORM frameworks like Hibernate, JDO, Apache OJB and iBATIS SQL Maps.
For mapping the hibernate resources, an instance of 'SessionFactory' is needed, 'LocalSessionFactoryBean' is used for this purpose and its properties 'hibernateProperties', 'mappingResources' and 'mappingDirectoryLocation' are set. Like Spring's DAO framework, here we have 'HibernateTemplate' to create an object of 'SessionFactory'. To access the data with 'HibernateTemplate' 'execute(HibernateCallback)' method is used.
Similar to the 'SessionFactory' of hibernate, JDO has 'PersistenceManager Factory'. It can be configured by using 'LocalPersistenceManagerFactoryBean'. Also 'JDOTemplate' to create an object of 'PersistenceManagerFactory'. To access the data with 'JDOTemplate' 'execute(JDOCallback)' method is used.
For iBATIS, we have to configure a 'SQLMapClient' by using 'SQLMapClientFactoryBean' and its properties 'configLocation' and 'dataSource' are set. Here also we have 'SQLMapClientTemplate'.
To access the data 'execute(SQLMapClientCallback)' method is used.
The only property that we need to change to integrate Spring with OJB is 'ConnectionFactoryClass' and it is done by using 'LocalDataSourceConnectionFactory'.
In the next article we shall see how to use a RMI service in Spring and how to export any Spring managed bean as RMI.
---------------------------------------------
|