`
yongboy
  • 浏览: 105992 次
  • 来自: ...
博客专栏
E16f1064-1c93-305c-9ed5-2118b09bada4
Servlet 3.0 学...
浏览量:0
社区版块
存档分类

分享一个很轻的、纯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 . 又是一个贫瘠的域模型,很瘦!

 

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

 

 

1
0
分享到:
评论
1 楼 xihuyu2000 2010-09-25  
我在项目中用过,后来被Hibernate替换掉了,原因是传入的参数类型无法验证,直接拼SQL会造成代码难读,直接结果是在DAO层花费了过多的时间,不经济

相关推荐

    利用java反射、注解及泛型模拟ORM实现

    2. **构建映射模型**:根据注解信息创建一个映射模型,描述类与数据库表、字段与列的对应关系。 3. **动态SQL生成**:基于映射模型,动态生成SQL语句,如SELECT、INSERT、UPDATE和DELETE。这可以使用模板引擎或字符...

    Hibernate泛型Dao

    【标题】"Hibernate泛型Dao"是针对Java开发中的数据持久化框架Hibernate的一个高级应用,主要目的是为了提高代码的复用性和简洁性。在传统的Hibernate使用中,针对每个实体类,我们都需要创建一个对应的Dao(Data ...

    Spring/泛型Hibernate的实现

    Maven是一个项目管理和构建工具,能够帮助开发者自动化构建过程,简化依赖管理。在本案例中,我们可以使用Maven来构建整个工程,包括管理依赖、编译代码、打包、测试等步骤。 ##### 3.1 添加依赖 在项目的`pom.xml...

    SpringBoot+Spring data JPA+FreeMarker+shiro+log4jdbc

    综合上述技术,这个项目可能是一个使用SpringBoot作为基础框架,通过Spring Data JPA进行数据库操作,使用FreeMarker作为模板引擎展示页面,Shiro负责安全控制,而Log4jdbc则用于记录数据库查询日志的Web应用。...

    某知名大厂Java工程师面试总结

    MyBatis是一个优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。面试中可能会涉及以下问题: 1. MyBatis的定义:MyBatis是一个基于Java的持久层框架,用于简化数据库操作。 2. 优点:轻量级、灵活、支持...

    iBatis和MyBatis对比

    MyBatis的出现意味着iBatis的升级,它不再仅仅是SQL映射框架,而是发展成一个更全面的ORM解决方案。 在MyBatis中,配置文件的结构与iBatis有所不同。全局配置文件通常命名为`Configuration.xml`,而映射文件则定义...

    super-nano-jdbc:超小纳米JDBC层

    "super-nano-jdbc"是一个轻量级的Java JDBC库,设计目标是提供一个极简的、高效的数据库访问层。它的核心理念是减小体积,提高性能,使得开发者在处理数据库交互时能更加便捷和快速。这个库由Rapidpm-Nano项目开发,...

    ibatis入门实例

    Ibatis可以被看作是一个半自动的ORM(对象关系映射)框架,它允许开发者编写SQL语句,但同时又可以自动化地将SQL执行结果映射到Java对象。 【描述】:“ibatis入门实例,推荐配合博客使用...

    SSI框架+权限(Oracle)

    iBatis允许开发者直接编写SQL语句,避免了ORM(Object-Relational Mapping,对象关系映射)框架的性能损失,同时提供了动态SQL的功能,增强了数据库查询的灵活性。 **Oracle10g** 是Oracle公司的一款关系型数据库...

    ssh 学习笔记

    Hibernate是一个对象关系映射(Object Relational Mapping,简称ORM)框架,它让开发者通过Java对象来操作数据库,而不需要编写复杂的SQL语句。在Hibernate中,开发者可以通过声明映射文件或者注解来配置对象和...

    Java泛型与数据库应用实例详解

    - 在实际开发中,通常会使用更高级的ORM框架,如Hibernate或MyBatis,它们提供了更强大的映射和事务管理功能,比直接使用JDBC更加便捷和高效。 - 数据库连接的生命周期管理是关键,确保在操作完成后关闭连接,以...

    Hibernate实战(第2版 中文高清版)

     1.3.2 用SQL/JDBC手工编写持久层   1.3.3 使用序列化   1.3.4 面向对象的数据库系统   1.3.5 其他选项   1.4 ORM   1.4.1 什么是ORM   1.4.2 一般的ORM问题   1.4.3 为什么选择ORM   1.4.4 ...

    Hibernate4实战.pdf

    Hibernate是一个开源的对象关系映射(ORM)框架,它被广泛用于Java应用中,用以实现数据持久化层。它允许开发者使用面向对象的方式来操作数据库,从而可以脱离数据库底层细节。Hibernate不仅封装了JDBC,并且实现了...

    j2se资源集(精华)

    - **Hibernate**:是一个流行的 Object-Relational Mapping (ORM) 工具,它允许开发者用 Java 对象的方式操作数据库,减少了 SQL 编写的工作量。理解 Hibernate 的配置、实体映射、会话管理、查询语言(HQL)是学习 ...

    数据访问设计_renjun_2010-11-22

    数据访问设计(Data Access Layer Design),旨在构建一个轻量级、高效且易于维护的数据访问层,使得开发者能够以简单直观的方式进行数据库操作,同时避免了传统JDBC驱动带来的复杂性。这一设计理念的核心目标在于...

    自定义Dao,反射实现

    自定义Dao并通过反射实现,虽然比使用ORM框架(如Hibernate、MyBatis)更繁琐,但可以更好地控制SQL语句,避免了不必要的映射配置。这种方法适用于小型项目或对性能有较高要求的场景,同时也为学习Java反射机制提供...

    ssh数据库基本操作封装

    SSH(Struts + Spring + Hibernate)是一个经典的Java Web开发框架,用于构建企业级应用程序。在这个主题中,“ssh数据库基本操作封装”指的是将常用的数据库交互功能,如增删改查(CRUD),通过SSH框架进行封装,...

    2020-2021《JAVA语言编程》期末课程考试试卷B(含答案).docx

    Java语言编程是计算机科学中的一个核心领域,尤其在互联网应用开发中扮演着至关重要的角色。这份2020-2021年《JAVA语言编程》期末课程考试试卷B涵盖了多个Java编程的基础与进阶知识点。 1. **面向对象编程**:题目...

Global site tag (gtag.js) - Google Analytics