现在的位置: 首页 > 综合 > 正文

JavaWeb 注解注入连接池

2013年12月11日 ⁄ 综合 ⁄ 共 4910字 ⁄ 字号 评论关闭

      当我们在使用 JDBC 技术的时候,为了减轻服务器的压力,我们通常采用连接池技术,但是我们怎么引用获取连接池?如果将连接池写死在 Dao 层中很不优雅,并且不直观。如果我们采用注解技术,就可以很方便的为每个 Dao 动态注入一个了连接池。这也是 Spring 框架中采用的技术。

      为了注入一个连接池,首先我们必须声明一个注解,注解中有连接数据库常用的属性,当然还有一个连接池的类型,因为我们在注入连接池的时候不知道这个 Dao 想要的是一个什么样的连接池,另外我们为了将连接池注入到 Dao 层中,我们必须将 Dao 层与 Service 层解耦,因为如果让 Dao 直接感染了 Service 层,我们就无法控制 Dao 层中的连接池。解耦采用泛型工厂模式,在创建一个 Dao 实例对象的时候为该 Dao 注入一个连接池。在
Dao 对象中维护着一个包含连接池信息注解字段,我们采用反射技术得到该字段上面的注解信息,从而动态创建一个连接池对象给 Dao 使用。

注解:

package cn.dk.annotation;

import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import com.mchange.v2.c3p0.DataSources;

@Retention(RetentionPolicy.RUNTIME)
public @interface injectDatasource {

	String driverclass() default "com.mysql.jdbc.Driver";
	String url() default "jdbc:mysql://localhost:3306/user";
	String username() default "root";
	String password() default "root";
	@SuppressWarnings("unchecked")
	Class poolType() default DataSources.class;
}

Dao 层

package cn.dk.dao;

import cn.dk.domain.User;

public interface IUserDao {

	User login(String username, String password);

}
package cn.dk.dao.impl;

import java.sql.SQLException;
import javax.sql.DataSource;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanHandler;
import cn.dk.annotation.injectDatasource;
import cn.dk.dao.IUserDao;
import cn.dk.domain.User;

public class UserDao implements IUserDao {

	@injectDatasource private DataSource source;

	public User login(String username, String password) {
		QueryRunner runner = new QueryRunner(source);
		String sql = "select * from user where username=? and password=?";
		Object[] params = { username, password };
		try {
			return (User) runner.query(sql, new BeanHandler(User.class), params);
		} catch (SQLException e) {
			throw new RuntimeException(e);
		}
	}
}

泛型工厂

package cn.dk.factory;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.Properties;
import javax.sql.DataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;
import com.mchange.v2.c3p0.ComboPooledDataSource;
import com.mchange.v2.c3p0.DataSources;
import cn.dk.annotation.injectDatasource;

public class DaoFactory {
	
	private static Properties properties = new Properties();
	private static DaoFactory factory = new DaoFactory();

	private DaoFactory(){
		InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("daoFactory.properties");
		try {
			properties.load(inputStream);
		} catch (IOException e) {
			throw new ExceptionInInitializerError(e);
		}
	}
	
	public static DaoFactory newInstance(){
		return factory;
	}
	
	@SuppressWarnings("unchecked")
	public <T> T getDao(Class<T> clazz){
		String key = clazz.getSimpleName();
		String className = properties.getProperty(key);
		try {
			T t = (T) Class.forName(className).newInstance();
			injectDataSource(t);
			return t;
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
	}
	
	@SuppressWarnings("unchecked")
	public void injectDataSource(Object obj){
		Class<?> clazz = obj.getClass();
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length; i++) {
			fields[i].setAccessible(true);
			injectDatasource annotation = fields[i].getAnnotation(injectDatasource.class);
			if(annotation == null)
				continue;
			try {
				Class poolType = annotation.poolType();
				if(poolType==ComboPooledDataSource.class){
					ComboPooledDataSource source = new ComboPooledDataSource();
					source.setDriverClass(annotation.driverclass());
					source.setJdbcUrl(annotation.url());
					source.setUser(annotation.username());
					source.setPassword(annotation.password());
					fields[i].set(obj, source);
				}else if(poolType==DataSources.class){
					InputStream inputStream = DaoFactory.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
					Properties dataProperties = new Properties();
					dataProperties.load(inputStream);
					DataSource source = BasicDataSourceFactory.createDataSource(dataProperties);
					fields[i].set(obj, source);
				}
			} catch (Exception e) {
				throw new RuntimeException(e);
			}
		}
	}
}

Service 层

package cn.dk.service;

import cn.dk.dao.IUserDao;
import cn.dk.domain.User;
import cn.dk.factory.DaoFactory;

public class UserService {
	
	private DaoFactory factory = DaoFactory.newInstance();
	private IUserDao userDao = factory.getDao(IUserDao.class);

	public User login(String username, String password) {
		return userDao.login(username, password);
	}
}

 

Web 层

package cn.dk.web;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import cn.dk.domain.User;
import cn.dk.service.UserService;

@SuppressWarnings("serial")
public class LoginServlet extends HttpServlet {

	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		UserService service = new UserService();
		String username = request.getParameter("username");
		String password = request.getParameter("password");
		User user = service.login(username, password);
		if(user == null){
			request.setAttribute("message", "密码不正确");
			request.getRequestDispatcher("/message.jsp").forward(request, response);
		}else{
			request.getSession().setAttribute("user", user);
			response.sendRedirect(request.getContextPath() + "/index.jsp");
		}
	}

	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		doGet(request, response);
	}

}

 

抱歉!评论已关闭.