分享一个很轻的、纯JDBC ORM映射小框架,泛型化,SQL级别

首先这是一个超轻的纯JDBC 框架,说是ORM,但又不配,但又具有一点点ORM的特性。四不像,怎么称呼,各位看官自取。

笨人笨舌的,看看代码吧,也许您就更清楚:

首先定义一个通用Dao的借口,定义了有限的几个方法:

package com.xiaomin.dao;

import java.util.List;

/**
 * 利用泛型操作数据表
 * 
 * @author xiaomin
 * 
 * @param <T>
 */
public interface IBaseDao<T> {

	/**
	 * 插入对象
	 * 
	 * @param sql
	 * @param params
	 */
	int add(String sql, Object... params);

	/**
	 * 查找多个对象
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	List<T> query(String sql, Object... params);

	/**
	 * 查找对象
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	T get(String sql, Object... params);

	/**
	 * 执行更新的sql语句,插入,修改,删除
	 * 
	 * @param sql
	 * @return
	 */
	boolean update(String sql);
}

 对应实现是重点:

package com.xiaomin.dao.impl;

import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.List;

import org.apache.commons.configuration.PropertiesConfiguration;
import org.apache.commons.dbutils.DbUtils;
import org.apache.commons.dbutils.QueryRunner;
import org.apache.commons.dbutils.handlers.BeanListHandler;

import com.xiaomin.dao.IBaseDao;

/**
 * 利用泛型操作数据表
 * 
 * @author xiaomin
 * 
 * @param <T>
 */
public class BaseDAOImpl<T> implements IBaseDao<T> {

	// 在构造函数中反射出泛型类对象
	private Class<T> tClass;

	@SuppressWarnings("unchecked")
	public BaseDAOImpl() {
		tClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	/**
	 * 插入对象
	 * 
	 * @param sql
	 * @param params
	 */
	public int add(String sql, Object... params) {
		Connection conn = getConnection();
		QueryRunner qr = new QueryRunner();
		try {
			int inserts = qr.update(conn, sql, params);
			return inserts;
		} catch (SQLException e) {
			e.printStackTrace();
			return -1;
		} finally {
			DbUtils.closeQuietly(conn);
		}
	}

	/**
	 * 查找多个对象
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	@SuppressWarnings( { "unchecked", "deprecation" })
	public List<T> query(String sql, Object... params) {
		List<T> beans = null;
		Connection conn = null;
		try {
			conn = getConnection();
			QueryRunner qRunner = new QueryRunner();
			beans = (List<T>) qRunner.query(conn, sql, params, new BeanListHandler(tClass));
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return beans;
	}

	/**
	 * 查找对象
	 * 
	 * @param sql
	 * @param params
	 * @return
	 */
	@SuppressWarnings( { "unchecked", "deprecation" })
	public T get(String sql, Object... params) {
		T obj = null;
		Connection conn = null;
		try {
			conn = getConnection();
			QueryRunner qRunner = new QueryRunner();

			List<T> litT = (List<T>) qRunner.query(conn, sql, params, new BeanListHandler(tClass));

			if (litT != null && litT.size() > 0)
				obj = litT.get(0);
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}

		return obj;
	}

	/**
	 * 执行更新的sql语句,插入,修改,删除
	 * 
	 * @param sql
	 * @return
	 */
	public boolean update(String sql) {
		Connection conn = null;
		boolean flag = false;
		try {
			conn = getConnection();
			QueryRunner qRunner = new QueryRunner();
			int i = qRunner.update(conn, sql);
			if (i > 0) {
				flag = true;
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			DbUtils.closeQuietly(conn);
		}
		return flag;
	}

	/**
	 * 数据库连接 若生产环境下,建议使用数据连接池获取链接
	 * 
	 * @return
	 */
	private static Connection getConnection() {
		Connection conn = null;

		PropertiesConfiguration propertyUtil = null;
		try {
			propertyUtil = new PropertiesConfiguration("/jdbc.properties");
		} catch (Exception e) {
			return null;
		}

		String driver = propertyUtil.getString("jdbc.driverClassName");
		String url = propertyUtil.getString("jdbc.url");

		DbUtils.loadDriver(driver);

		try {
			conn = DriverManager.getConnection(url, propertyUtil.getString("jdbc.username"), propertyUtil
					.getString("jdbc.password"));
		} catch (SQLException ex) {
			ex.printStackTrace();
		}

		return conn;
	}
}

 诸位看到这里一定明白了,使用到了Apache Commons DbUtils,然后添加JDK 1.5的泛型支持,很浅显。

如何使用呢 ?

我们在数据库中定义了一个表格:

CREATE TABLE BaseEntity(
	id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
	url VARCHAR(100),
	site VARCHAR(50),
	pubDate TIMESTAMP(8),
	inDate TIMESTAMP(8)
);

 对应的实体则一定是:

package com.yourdomain;

import java.io.Serializable;
import java.util.Date;

public class BaseEntity implements Serializable {
	private static final long serialVersionUID = 516103458363794423L;

	private Integer id;

	private String url;

	/**
	 * 添加到数据库日期
	 */
	private Date inDate;

	/**
	 * 来自网站简称
	 */
	private String site;

	/**
	 * 原始站点发布日期
	 */
	private Date pubDate;

	public BaseEntity() {
	}

	public BaseEntity(String url, Date inDate, String site, Date pubDate) {
		this.url = url;
		this.inDate = inDate;
		this.site = site;
		this.pubDate = pubDate;
	}

	public BaseEntity(Integer id, String url, Date inDate, String site, Date pubDate) {
		this(url, inDate, site, pubDate);
		this.id = id;
	}

	public Integer getId() {
		return id;
	}

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

	public String getUrl() {
		return url;
	}

	public void setUrl(String url) {
		this.url = url;
	}

	public Date getInDate() {
		return inDate;
	}

	public void setInDate(Date inDate) {
		this.inDate = inDate;
	}

	public String getSite() {
		return site;
	}

	public void setSite(String site) {
		this.site = site;
	}

	public Date getPubDate() {
		return pubDate;
	}

	public void setPubDate(Date pubDate) {
		this.pubDate = pubDate;
	}
}

 下面是对这个实体的操作:

package com.yourdomain.dao.impl;

import java.util.List;

import com.xiaomin.dao.impl.BaseDAOImpl;
import com.yourdomain.BaseEntity;
import com.yourdomain.dao.IDemoDao;

public class DemoDaoImpl extends BaseDAOImpl<BaseEntity> implements IDemoDao {

	public List<BaseEntity> getAll() {
		String hql = "select * from BaseEntity";
		return this.query(hql);	
	}

	public BaseEntity getBaseEntity(Integer entityId) {
		String sql = "select * from BaseEntity where id = ?";
		return this.get(sql, entityId);
	}

	public void save(BaseEntity videoEntity) {
		String sql = "INSERT INTO BaseEntity(url,site,pubDate,inDate) VALUES (?,?,?,?)";
		
		Object[] insertParams = { videoEntity.getUrl(), videoEntity.getSite(),
				videoEntity.getPubDate(), videoEntity.getInDate() };
		
		this.add(sql, insertParams);
	}

	public void save(List<BaseEntity> entityList) {
		for(BaseEntity entity : entityList){
			this.save(entity);
		}
	}
}

 这样对 BaseEntity 的操作就这样完成了。

还有未能说清楚地方,请参见附件一个完整Demo。

 

附加说明:

1 . 需要 JDK 1.5 或更高版本;使用到泛型,可变参数;每一个实体对应ID个人认为使用不上,暂无泛型化
2 . 需要一个数据库,数据库连接参数在 src/jdbc.properties 中修改
3 . 创建数据库脚本在 document/database.sql 中寻找;测试请运行test.service.TestDemoDao
4 . 仅仅为了更简单使用JDBC,厌烦了Hibernate的臃肿
5 . 可在中小型项目中使用
6 . 仅仅封装了Dao层,请自行融入到现有项目中
7 . 数据库表格和实体名字一样,字段名称和实体属性名字一致
8 . 新的Dao操作类,仅仅需要集成com.xiaomin.dao.impl.BaseDAOImpl或者其它方式,请自行实践
9 . 又是一个贫瘠的域模型,很瘦!

 

在小型项目中是再简单不过了,只是分享,但不推荐您也这样做,除非您有驾驭能力,出了问题也知道在什么地方。

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值