Wednesday, August 14, 2013

Spring 3 MVC + Hibernate 4 + JdbcTemplate + Partial REST controller (Part 3)

Last part of the article is to use either Hibernate or Spring's JdbcTemplate to retrieve data. The following class is the BaseDao where DataSource and Hibernate SessionFactory are injected and used by concrete DAO classes:

package com.techtots.services.api.dao;

import javax.sql.DataSource;

import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;

public abstract class BaseDao {

	@Autowired
	protected SessionFactory sessionFactory;
	
	protected DataSource dataSource;

	protected JdbcTemplate jdbcTemplate;
	protected NamedParameterJdbcTemplate namedParameterJdbcTemplate;

	public DataSource getDataSource() {
		return dataSource;
	}

	@Autowired
	public void setDataSource(DataSource dataSource) {
		this.dataSource = dataSource;
		this.jdbcTemplate = new JdbcTemplate(this.dataSource);
		this.namedParameterJdbcTemplate = new NamedParameterJdbcTemplate(this.dataSource);
		
	}

	public JdbcTemplate getJdbcTemplate() {
		return jdbcTemplate;
	}

	public NamedParameterJdbcTemplate getNamedParameterJdbcTemplate() {
		return namedParameterJdbcTemplate;
	}

}

Once we have this out of the way, we can now define a concrete DAO class. We'll have a simple UserDao for testing.

package com.techtots.services.api.dao;

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Criteria;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.stereotype.Repository;

import com.techtots.services.api.entity.User;
import com.techtots.services.common.vo.UserVo;

@Repository
public class UserDao extends BaseDao {

	public List<User> getList() {
		Criteria criteria = sessionFactory.getCurrentSession().createCriteria(User.class);
		
		return criteria.list();
	}
	
	public List<UserVo> list() {
		final List<UserVo> list = new ArrayList<UserVo>();
		
		getJdbcTemplate().query("select * from tbl_user", new RowMapper<Object>() {

			@Override
			public Object mapRow(ResultSet rs, int arg1) throws SQLException {
				UserVo vo = new UserVo();
				
				vo.setId(rs.getInt("id"));
				vo.setUsername(rs.getString("nickname"));
				
				list.add(vo);
				
				return null;
			}
			
		});
		
		return list;
	}
}


Since this is just a reference, I've implemented 2 different function to retrieve data. getList() uses Hibernate's SessionFactory while list() uses JdbcTemplate. Following classes are the UserVo and User entity classes which are used by the DAO respectively:

package com.techtots.services.common.vo;

public class UserVo {

	private int id;
	private String username;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getUsername() {
		return username;
	}

	public void setUsername(String username) {
		this.username = username;
	}

}

package com.techtots.services.api.entity;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "tbl_user2")
public class User {

	@Id
	@GeneratedValue(strategy = GenerationType.AUTO)
	@Column(name = "id", nullable = false)
	private int id;

	@Column(name = "name", nullable = false, length = 200)
	private String name;

	@Column(name = "email", nullable = false, length = 250, unique = true)
	private String email;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

}

To call this from your UserController, you'll need to add the @Transactional annotation at either the class or method level. You wouldn't usually add this at the controller level as it's better to have everything wrapped up in a service class.

No comments: