import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import com.lowca.robot.Crawler;
/**
* <p>
* 通用dao类,用法和说明如下:
* </p>
* <p>
* 1.不支持事务
* </p>
* <p>
* 2.不支持连接池
* </p>
* <p>
* 3.命名方法必须严格遵守java pojo和数据库的命名规范/p>
* <p>
* 4.主键必须叫做“id”,且必须为Integer类型,其他基本类型的属性必须为其封装类型
* </p>
* <p>
* 5.不支持复杂映射
* </p>
*
* @author kong
*
*/
public class Dao {
private static final String DRIVER = "org.sqlite.JDBC";
private static final String CONNECT_URL = "jdbc:sqlite:c:/robot.db";
private static final String USERNAME = null;
private static final String PASSWORD = null;
private static final Log log = LogFactory.getLog(Crawler.class);
static {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
throw new RuntimeException("加载JDBC驱动失败:\n" + e.getMessage());
}
}
/**
* 获取连接
*
* @return
* @throws SQLException
*/
private Connection getConnection() throws SQLException {
Connection conn = null;
if (USERNAME != null && PASSWORD != null)
conn = DriverManager.getConnection(CONNECT_URL, USERNAME, USERNAME);
else
conn = DriverManager.getConnection(CONNECT_URL);
conn.setAutoCommit(false);
return conn;
}
/**
* 行集映射
*
* @param <T>
* @param clazz
* @param rs
* @return
* @throws SQLException
*/
private <T> T mapping(Class<T> clazz, ResultSet rs) throws SQLException {
T t = null;
if (rs.next()) {
try {
t = clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
ResultSetMetaData metadata = rs.getMetaData();
int size = metadata.getColumnCount();
for (int i = 0; i < size; i++) {
String columnName = metadata.getColumnLabel(i + 1);
Object columnValue = rs.getObject(metadata
.getColumnLabel(i + 1));
if (columnValue == null)
continue;
// 给对象赋值
String propertyName = toJavaCase(columnName);
String methodName = "set"
+ propertyName.substring(0, 1).toUpperCase()
+ propertyName.substring(1);
Method[] methods = clazz.getMethods();
for (Method method : methods) {
if (methodName.equals(method.getName())) {
try {
String propertyTypeName = method
.getParameterTypes()[0].getName();
String columnTypeName = columnValue.getClass()
.getName();
if (propertyTypeName
.equalsIgnoreCase(columnTypeName))
method.invoke(t, columnValue);
else {
// 转换长整型和日期类型的不适配问题
if ("java.util.Date".equals(propertyTypeName)
&& "java.lang.Long"
.equals(columnTypeName))
method.invoke(t, new Date(
(Long) columnValue));
// 转换整型为布尔型
if ("java.lang.Boolean"
.equals(propertyTypeName)
&& "java.lang.Integer"
.equals(columnTypeName))
method.invoke(t, columnValue.toString()
.equals("0") ? false : true);
}
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
}
}
return t;
}
/**
* 释放连接
*
* @param rs
* @param ps
* @param conn
*/
public void free(ResultSet rs, PreparedStatement ps, Connection conn) {
try {
if (rs != null)
rs.close();
} catch (Exception e) {
log.error(this, e);
} finally {
try {
if (ps != null)
ps.close();
} catch (Exception e) {
log.error(this, e);
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
log.error(this, e);
}
}
}
}
}
/**
* 查询方法
*
* @param <T>
* @param clazz
* @param sql
* @param values
* @return
* @throws SQLException
*/
public <T> T query(Class<T> clazz, String sql, Object[] values)
throws SQLException {
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
ps.setObject(i + 1, values[i]);
}
}
ResultSet rs = ps.executeQuery();
T t = mapping(clazz, rs);
free(rs, ps, conn);
return t;
}
/**
* 查询方法(不带参数)
*
* @param <T>
* @param clazz
* @param sql
* @return
* @throws SQLException
*/
public <T> T query(Class<T> clazz, String sql) throws SQLException {
return query(clazz, sql, null);
}
/**
* 查询多个对象
*
* @param <T>
* @param clazz
* @param sql
* @param values
* @return
* @throws SQLException
*/
public <T> List<T> queryList(Class<T> clazz, String sql, Object[] values)
throws SQLException {
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
ps.setObject(i + 1, values[i]);
}
}
ResultSet rs = ps.executeQuery();
List<T> list = new ArrayList<T>();
T t = null;
while ((t = mapping(clazz, rs)) != null) {
list.add(t);
}
free(rs, ps, conn);
return list;
}
/**
* 查询多个对象(不带参数)
*
* @param <T>
* @param clazz
* @param sql
* @return
* @throws SQLException
*/
public <T> List<T> queryList(Class<T> clazz, String sql)
throws SQLException {
return queryList(clazz, sql, null);
}
/**
*统计一类对象的个数
*
* @param clazz
* @return
* @throws SQLException
*/
public int count(Class<?> clazz) throws SQLException {
Connection conn = getConnection();
String tableName = toDbCase(clazz.getSimpleName());
String sql = "select count(*) from " + tableName;
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
int num = 0;
if (rs.next())
num = rs.getInt(1);
free(rs, ps, conn);
return num;
}
/**
* 根据sql统计
*
* @param sql
* @param values
* @return
* @throws SQLException
*/
public int count(String sql, Object[] values) throws SQLException {
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
ps.setObject(i + 1, values[i]);
}
}
ResultSet rs = ps.executeQuery();
int num = 0;
if (rs.next())
num = rs.getInt(1);
free(rs, ps, conn);
return num;
}
/**
* 根据sql统计(不带参数)
*
* @param sql
* @return
* @throws SQLException
*/
public int count(String sql) throws SQLException {
return count(sql, null);
}
/**
* 根据id获取
*
* @param <T>
* @param clazz
* @param id
* @return
* @throws SQLException
*/
public <T> T get(Class<T> clazz, Integer id) throws SQLException {
String tableName = toDbCase(clazz.getSimpleName());
String sql = "select * from " + tableName + " where id="
+ id.intValue();
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
T t = mapping(clazz, rs);
free(rs, ps, conn);
return t;
}
/**
* 删除对象
*
* @param clazz
* @param id
* @return
* @throws SQLException
*/
public int delete(Class<?> clazz, Integer id) throws SQLException {
String tableName = toDbCase(clazz.getSimpleName());
String sql = "delete from " + tableName + " where id=" + id.intValue();
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
int rowCount = ps.executeUpdate();
free(null, ps, conn);
return rowCount;
}
/**
* 保存对象
*
* @param object
* @throws SQLException
*/
public void save(Object object) throws SQLException {
// 通过反射提取属性和属性值
Method[] methods = object.getClass().getMethods();
Map<String, Object> kvMap = new HashMap<String, Object>();
for (Method method : methods) {
if (method.getName().startsWith("set")) {
String key = method.getName().substring(3, 4).toLowerCase()
+ method.getName().substring(4);
Method getMethod = null;
Object value = null;
try {
getMethod = object.getClass().getDeclaredMethod(
method.getName().replaceFirst("set", "get"));
value = getMethod.invoke(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
kvMap.put(key, value);
}
}
// 生成sql
String tableName = toDbCase(object.getClass().getSimpleName());
Object[] values = new Object[kvMap.size()];
StringBuffer sb = new StringBuffer("INSERT INTO " + tableName + "(");
StringBuffer params = new StringBuffer();
int index = 0;
for (String key : kvMap.keySet()) {
String columnName = toDbCase(key);
sb.append(columnName + ",");
params.append("?,");
values[index] = kvMap.get(key);
index++;
}
if (sb.charAt(sb.length() - 1) == ',')
sb.delete(sb.length() - 1, sb.length());
if (params.charAt(params.length() - 1) == ',')
params.delete(params.length() - 1, params.length());
sb.append(") VALUES(").append(params).append(");");
String sql = sb.toString();
// 执行sql
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
ps.setObject(i + 1, values[i]);
}
}
conn.setAutoCommit(true);
ps.execute();
conn.setAutoCommit(false);
// 获取主键
ps = conn.prepareStatement("select last_insert_rowid()");
ResultSet rs = ps.executeQuery();
Integer pk = 0;
if (rs.next())
pk = rs.getInt(1);
// 给对象赋主键的值
try {
Method method = object.getClass().getDeclaredMethod("setId",
Integer.class);
method.invoke(object, pk);
} catch (Exception e) {
throw new RuntimeException(e);
}
free(null, ps, conn);
}
/**
* 更新对象
*
* @param object
* @throws SQLException
*/
public void update(Object object) throws SQLException {
// 通过反射提取属性和属性值
Method[] methods = object.getClass().getMethods();
Map<String, Object> kvMap = new HashMap<String, Object>();
for (Method method : methods) {
if (method.getName().startsWith("set")) {
String key = method.getName().substring(3, 4).toLowerCase()
+ method.getName().substring(4);
Method getMethod = null;
Object value = null;
try {
getMethod = object.getClass().getDeclaredMethod(
method.getName().replaceFirst("set", "get"));
value = getMethod.invoke(object);
} catch (Exception e) {
throw new RuntimeException(e);
}
kvMap.put(key, value);
}
}
// 生成sql
String tableName = toDbCase(object.getClass().getSimpleName());
Object[] values = new Object[kvMap.size()];
StringBuffer sb = new StringBuffer("UPDATE " + tableName + " ");
int index = 0;
Integer id = 0;
boolean firstTime = true;
for (String key : kvMap.keySet()) {
String columnName = toDbCase(key);
if (key.equalsIgnoreCase("id")) {
id = (Integer) kvMap.get(key);
continue;
}
sb.append((firstTime ? " SET " : "") + columnName + "=?,");
firstTime = false;
values[index] = kvMap.get(key);
index++;
}
values[index] = id;
if (sb.charAt(sb.length() - 1) == ',')
sb.delete(sb.length() - 1, sb.length());
sb.append(" WHERE id=?;");
String sql = sb.toString();
// 执行sql
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
ps.setObject(i + 1, values[i]);
}
}
conn.setAutoCommit(true);
ps.executeUpdate();
conn.setAutoCommit(false);
free(null, ps, conn);
}
/**
* 执行sql语句
*
* @param sql
* @param values
* @return
* @throws SQLException
*/
public boolean execute(String sql, Object[] values) throws SQLException {
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
if (values != null) {
for (int i = 0; i < values.length; i++) {
ps.setObject(i + 1, values[i]);
}
}
conn.setAutoCommit(true);
boolean r = ps.execute();
conn.setAutoCommit(false);
free(null, ps, conn);
return r;
}
/**
* 执行sql语句,不带参数
*
* @param sql
* @return
* @throws SQLException
*/
public boolean execute(String sql) throws SQLException {
return execute(sql, null);
}
/**
* 检查数据库是否有这个表
*
* @param clazz
* @return
* @throws SQLException
*/
public boolean existTable(Class<?> clazz) throws SQLException {
String tableName = toDbCase(clazz.getSimpleName());
String sql = "SELECT COUNT(*) AS table_count FROM sqlite_master WHERE TYPE='table' AND NAME=?;";
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
ps.setObject(1, tableName);
ResultSet rs = ps.executeQuery();
int num = 0;
if (rs.next()) {
num = rs.getInt("table_count");
}
free(null, ps, conn);
return num > 0 ? true : false;
}
/**
* 使用类来创建表
*
* @param clazz
* @param delIfExist
* 如果表已存在,true表示删除旧表并重新建表,false表示保留旧表不再重新建
* @throws SQLException
*/
public void createTable(Class<?> clazz, boolean delIfExist)
throws SQLException {
// 如果表已经存在,则看看是否需要删除
boolean existTable = existTable(clazz);
if (!delIfExist && existTable) {
return;
}
if (delIfExist && existTable) {
deleteTable(clazz);
}
// 通过反射提取属性和属性值
Method[] methods = clazz.getMethods();
Map<String, String> kvMap = new HashMap<String, String>();
for (Method method : methods) {
if (method.getName().startsWith("set")) {
String property = method.getName().substring(3, 4)
.toLowerCase()
+ method.getName().substring(4);
String propertyClassName = method.getParameterTypes()[0]
.getName();
kvMap.put(property, propertyClassName);
}
}
// 生成sql
String tableName = toDbCase(clazz.getName());
StringBuffer sb = new StringBuffer("CREATE TABLE " + tableName
+ " (id INTEGER PRIMARY KEY,");
for (String key : kvMap.keySet()) {
if (key.equalsIgnoreCase("id")) {
continue;
}
String columnName = toDbCase(key);
String propertyClassName = kvMap.get(key);
String dbTypeName = getDbTypeName(propertyClassName);
sb.append(columnName + " " + dbTypeName + ",");
}
if (sb.charAt(sb.length() - 1) == ',')
sb.delete(sb.length() - 1, sb.length());
sb.append(");");
String sql = sb.toString();
// 执行sql
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
conn.setAutoCommit(true);
ps.execute();
conn.setAutoCommit(false);
free(null, ps, conn);
}
/**
* 使用sql来建表
*
* @param sql
* @throws SQLException
*/
public void createTable(String sql) throws SQLException {
// 创建表
Connection conn = getConnection();
PreparedStatement ps = conn.prepareStatement(sql);
conn.setAutoCommit(true);
ps.execute();
conn.setAutoCommit(false);
free(null, ps, conn);
}
/**
* 创建表,如果表已经存在,则不新建
*
* @param clazz
* @throws SQLException
*/
public void createTable(Class<?> clazz) throws SQLException {
createTable(clazz, false);
}
/**
* 删除表
*
* @param clazz
* @throws SQLException
*/
public void deleteTable(Class<?> clazz) throws SQLException {
String tableName = toDbCase(clazz.getSimpleName());
String sql = "DROP TABLE IF EXISTS " + tableName;
execute(sql);
}
private String getDbTypeName(String propertyClassName) {
if ("java.lang.Integer".equals(propertyClassName)
|| "java.lang.Long".equals(propertyClassName)
|| "java.lang.Character".equals(propertyClassName)
|| "java.lang.Short".equals(propertyClassName))
return "INTEGER";
if ("java.lang.Float".equals(propertyClassName)
|| "java.lang.Double".equals(propertyClassName))
return "REAL";
if ("java.util.Date".equals(propertyClassName))
return "DATETIME";
if ("java.lang.Boolean".equals(propertyClassName))
return "TINYINT";
if ("java.lang.String".equals(propertyClassName))
return "VARCHAR";
return "";
}
/**
* 数据库命名方式转换成java的命名方式
*
* @param s
* @return
*/
private static String toJavaCase(String s) {
if (s == null || s.trim().length() == 0)
return s;
StringBuffer sb = new StringBuffer();
String[] array = s.split("_");
boolean firstTime = true;
for (String e : array) {
if (e.length() == 0)
continue;
else if (e.length() == 1)
sb.append(!firstTime ? e.toUpperCase() : e);
else
sb.append(!firstTime ? (e.substring(0, 1).toUpperCase() + e
.substring(1)) : e);
firstTime = false;
}
return sb.toString();
}
/**
* Java命名方式转换成数据库的命名方式
*
* @param s
* @return
*/
private static String toDbCase(String s) {
if (s == null || s.trim().length() == 0)
return s;
char[] chars = s.toCharArray();
boolean firstTime = true;
StringBuffer sb = new StringBuffer();
for (char c : chars) {
if (c >= 'A' && c <= 'Z') {
char c1 = (char) (c + 32);
sb.append(firstTime ? c1 : "_" + c1);
} else
sb.append(c);
firstTime = false;
}
return sb.toString();
}
public static void main(String[] args) {
// System.out
// .println(toDbCase("theyBeganToHumWhenSeeingJacksonWalkIntoTheHall"));
// System.out
// .println(toJavaCase(toDbCase("theyBeganToHumWhenSeeingJacksonWalkIntoTheHall")));
StringBuffer sb = new StringBuffer("sdsdfds1");
sb.delete(sb.length() - 1, sb.length());
System.out.println(sb);
}
}
分享到:
相关推荐
在Java开发中,数据访问对象(DAO)模式是一种常见的设计模式,用于封装对数据库的操作,使得业务逻辑与数据访问逻辑分离。JDBC(Java Database Connectivity)是Java平台中用于访问数据库的标准API,但它直接使用...
下面我们将详细探讨如何在Java中使用面向对象的方式来操作关系型数据库,并构建DAO层。 1. **JDBC基础**:Java Database Connectivity (JDBC) 是Java中用于与各种数据库交互的标准API。通过JDBC,我们可以连接到...
在实现通用DAO时,反射通常用于动态调用数据库操作的方法,比如SQL查询。例如,在`UsersDAO.java`中,可能有以下代码: ```java public class UsersDAO extends BaseDao<Users> { @Override public void save...
综上所述,Hibernate通用DAO设计的核心在于抽象出共性的数据库操作,并通过泛型和继承等面向对象设计原则,达到代码复用的目的。这样不仅可以降低开发难度,还能提升系统的可维护性,对于大型项目尤其重要。通过学习...
标题中的“hibernate4 通用dao,service”指的是在Java开发中使用Hibernate框架实现的通用数据访问对象(DAO)和业务服务层(Service)。Hibernate是一个流行的对象关系映射(ORM)工具,它允许开发者使用面向对象的...
在C#编程中,"通用Dao层"是一个常见的设计模式,用于封装数据库操作,使得业务逻辑层能够专注于处理业务规则,而无需关心底层数据访问的细节。本篇将重点探讨如何利用C#的特性(Attribute)标签来实现这一目标,同时...
通过定义一个泛型接口,我们可以创建一个通用的数据访问对象(DAO),这个DAO可以处理任何类型的实体类,只要它们遵循一定的规则,比如拥有ID字段。这样,我们就只需要编写一次DAO的实现,就可以为不同的数据表提供...
然而,泛型通用DAO也存在局限性,如上述描述所示,它通常只适用于单表操作,对于复杂的关联查询和多表操作可能显得力不从心。此外,它可能无法充分利用ORM框架(如Hibernate、MyBatis等)提供的高级特性,如缓存、...
在实际应用中,除了基本的DAO操作,还可能扩展了分页查询、事务管理、缓存支持等功能,以满足更复杂的需求。 总的来说,这个资源为开发者提供了一个高效的工具,通过使用Hibernate和通用DAO模式,可以快速构建数据...
另类实现可以采用动态代理或AOP(面向切面编程)来实现通用DAO。下面是一个使用Java动态代理的例子: 1. 创建一个`BaseDAO`接口,定义一些基本的CRUD操作,如`save()`, `update()`, `delete()`, `findById()`, `...
使用该通用Dao框架,开发者只需关注业务逻辑,而无需关心底层的数据库操作和对象映射,极大地提升了开发效率。提供的sql文件则包含了数据库表结构和初始数据,下载后导入数据库,配合框架运行,可以直接看到预期效果...
为什么我们要使用通用DAO接口呢,因为我们的数据库操作无非是增删改查,CRUD操作,我们不需要为每个实体去编写一个dao接口,对于相似的实体操作可以只编写一个通用接口,然后采用不同的实现! DAO已经成为持久层...
自定义通用DAO实现基本的CRUD,比如: public interface BaseDao<T> { int insert(T obj) throws Exception; int update(T obj) throws Exception; int deleteByPrimaryKey(Object key) throws Exception; int ...
在Java编程领域,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者以面向对象的方式处理数据库操作,从而减少了对SQL的直接依赖。通用DAO(Data Access Object)是一种设计模式,用于封装对数据库的操作...
**Hibernate原生通用DAO**是基于Hibernate框架设计的一种简化数据访问操作的方式,它模仿了Spring框架中的`HibernateTemplate`类,旨在提供一个简单易用的DAO(Data Access Object)层,方便开发人员进行数据库操作...
2. **DAO 实现**:实现了 DAO 接口的具体类,它们负责处理与数据库的交互,通常包括编写 SQL 查询或使用 ORM(对象关系映射)框架。DAO 实现类通常包含连接管理,如打开和关闭数据库连接,以及处理事务。 3. **实体...
在上述DAO(数据访问对象)的例子中,如果不同的查询列表只需要改变SQL语句,那么使用一个通用的DAO接口并通过静态工厂方法提供不同实现,可以实现更粗粒度的接口,提高复用性并减少错误的可能性。 在服务导向架构...
本文将围绕“Hibernate超级通用DAO”这一主题,深入探讨如何构建一个功能强大的DAO层,实现包括增、删、改、查以及多条件模糊查询在内的各种功能。 首先,Hibernate是一个流行的Java ORM(对象关系映射)框架,它...
标题“ssh通用基于泛型的dao”指的是使用SSH(Spring、Struts2、Hibernate)框架开发的一个通用的、基于泛型的DAO实现,它旨在提高开发效率,减少重复工作。 SSH框架是Java企业级应用开发的常用组合,Spring提供了...
面向对象编程(Object-Oriented Programming,简称OOP)是一种广泛应用的编程范式,它将程序设计中的实体(如数据和操作数据的方法)抽象为对象,通过类与对象的概念来组织代码,使得程序更加模块化、可重用性和可...