Over a million developers have joined DZone.

DB Queries in spring's application-context.xml.

·

While solving one of my assignment, I realize the age long practice of writing db queries in java class file is really a big pain. They are difficult to read and understand. Further if you want to modify it again a lot of task.

Thus, to get rid of the pain, I put the db queries in spring’s context xml.

Later I realize using such injections using xml, its not only easier to maintain and understand also we can have module wise segregation of db queries in different <util:map> or in different "xyzDAO-queries.xml". Further its easier to add more customers to the existing application.

Please see the code snippet area for the context.xml called "userDAO-queries.xml". I've created Map <util:map/> with an id. In the Map I put the key as <entry key="QUERY" > and values as <value>.db queries goes here....</value> , which contains the query.

The java classes are DBQueriesImpl.java and UserDAOImpl.java for fetching the exact query from the "xyzDAO-queries.xml".

Please see the comments in the java class.

Context XML (userDAO-queries.xml) part :

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:util="http://www.springframework.org/schema/util"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.0.xsd">

    <util:map id="FIND_ALL_USER" key-type="java.lang.String" value-type="java.lang.String" >
      <entry key="QUERY" >
          <value>SELECT
                    user_id,
                    user_name,
                    user_password,
                    user_fname,
                    user_mname,
                    user_lname,
                    user_create_time 
                FROM
                    ty_users
          </value>
      </entry>
    </util:map>

    <util:map id="VALIDATE_USER_CREDENTIAL" key-type="java.lang.String" value-type="java.lang.String" >
    <entry key="QUERY" >
      <value>SELECT
                user_id,
                user_name,
                user_password 
              FROM
                  ty_users 
              WHERE
                  user_name = ? 
                  and user_password = ?
      </value>
    </entry> 
    </util:map>

    <util:map id="FIND_SPECIFIC_USER" key-type="java.lang.String" value-type="java.lang.String" >
    <entry key="QUERY" >
    	<value>SELECT user_id, user_name, user_password FROM ty_users WHERE user_id=?</value>
    </entry> 
    </util:map>

    <util:map id="CREATE_USER" key-type="java.lang.String" value-type="java.lang.String" >
    <entry key="QUERY" >
    	<value>INSERT INTO ty_users (user_name, user_password) VALUES (?, ?) </value>
    </entry>
    </util:map>

</beans>

Java Code Part:
UserDAOImpl.java
public class UserDAOImpl implements UserDAO{
  
	private static final Logger logger = LoggerFactory.getLogger(UserDAOImpl.class);// logger
	DBQueries dbQuery = new DBQueriesImpl("userDAO-queries.xml");//
	DBConnection dbConn = ConnectionFactory.getInstance().getConnectionMySQL();
	
  	@Override
	public List authenitcUserDetails(String userName, String userPassword) {
		Map queryMap = null;
		String query ;
		List> mappedUserList = null;
		List listUser = null;
		try{
			listUser = new ArrayList();
			queryMap = dbQuery.getQueryBeanFromFactory("VALIDATE_USER_CREDENTIAL"); //passing the query-name or Map Id.
			query =  dbQuery.getQuery(queryMap);//passing the query-map to get the query.

			//rest of the code is common fetching code.
			mappedUserList = dbConn.dbQueryRead(query, new Object[]{userName,userPassword});
			if(mappedUserList.size()>0){
				listUser =  new QueryResultSetMapperImpl().mapRersultSetToObject(mappedUserList, User.class);
			}
		}catch(Exception  ex){
			logger.error("fetchAllUser Error:: ", ex);
		}
		return listUser;
	}
}


DBQueriesImpl.java
public class DBQueriesImpl implements DBQueries {
    private static final Logger logger = LoggerFactory.getLogger(DBQueriesImpl.class);
	private ApplicationContext queriesCtx ;
    
  	/**
     * @Desc: Loading the queryContext xml
     * @param queryContext
     */
    public DBQueriesImpl(String queryContext) {
    	queriesCtx = new ClassPathXmlApplicationContext(queryContext);
    }
	
  	/**
     * @Desc: Reading from the loaded application context and getting the query-map, .  
     */
    @Override
    public Map getQueryBeanFromFactory(String beanId){
      	Map queryMap = null;
      	if (queriesCtx != null && beanId != null) {
      		queryMap = (Map)queriesCtx.getBean(beanId);
      	}
    	return queryMap;
    }
  
   /**
    * @Desc: Getting the exact query from the query-map, .  
    */
    @Override
    public String getQuery(Map queryMap) {
  		String query=null;
    	try{
    		if(queryMap.containsKey(QueryConstants.QUERY_NODE)){
    			query = (String) queryMap.get(QueryConstants.QUERY_NODE);
    			queryMap.remove(QueryConstants.QUERY_NODE);
    		}else{
    			throw new NoSuchFieldError();
    		}
    	}catch(Exception excp){
    		excp.printStackTrace();
    	}
    	return query;
    }
}



With this kind of setting I can also solve few other problems. In one of my assignment I used this trick. In the application, various clients have different set of data requirements thus, different set of sql-queries. Now instead of writing java classes to met client requirement we just write the set of spring-context.xmls having sql and used those spring-context at runtime and fetch data.


 

Topics:
spring dao ,application architecture

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}