package com;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.sql.DataSource;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.lang.builder.ReflectionToStringBuilder;
import org.apache.commons.lang.reflect.FieldUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.ColumnMapRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.core.namedparam.BeanPropertySqlParameterSource;
import org.springframework.jdbc.core.simple.SimpleJdbcInsert;
import org.springframework.stereotype.Repository;
/**
* Usage:
* This is a generic class for data access.
* Entity must have @Id annotation on identity field.
* @author lixiaodong
*
* @param <T>
*/
@Repository
public class GenericDao<T extends Serializable>{
private final Logger log = LoggerFactory.getLogger(getClass());
@Autowired
private DataSource dataSource;
private String tableName;
/**
*
* @return
*/
private JdbcTemplate getJdbcTemplate() {
return new JdbcTemplate(dataSource);
}
public GenericDao() {
}
private Class<T> entityClass;
/**
* Get generic class
* @return Class<T>
*/
@SuppressWarnings("unchecked")
protected Class<T> getEntityClass() {
if (entityClass == null) {
entityClass = (Class<T>) ((ParameterizedType) getClass()
.getGenericSuperclass()).getActualTypeArguments()[0];
}
return entityClass;
}
/**
* Get table name of Entity
* @return tableName
*/
protected String getTableName(){
if(this.tableName == null){
Table table = getEntityClass().getAnnotation(Table.class);
if(table == null){
log.error("Annotation @Table not found!");
}
this.tableName = table.name();
}
return this.tableName;
}
private String id;
/**
* delete by id
*/
public void delete(Serializable... entityIds) {
String sql = "delete from "+getTableName()+" where "+getId()+" = ?";
for (Serializable entityId : entityIds) {
getJdbcTemplate().update(sql,entityId);
log.debug(sql);
}
}
/**
* Get field name of id annotation
* @return fieldName
*/
protected String getId(){
String fieldName = StringUtils.EMPTY;
if(this.id==null){
Field []fields = getEntityClass().getDeclaredFields();
for (Field field : fields) {
if(isIdField(field)){
fieldName = field.getName();
break;
}
}
if(StringUtils.isEmpty(fieldName)){
log.error(getTableName()+" have not specific Id");
}
}else{
return this.id;
}
return fieldName;
}
/**
* Is this a id field
* @param field
* @return true or false
*/
private boolean isIdField(Field field){
Annotation []annotations = field.getAnnotations();
for (Annotation annotation : annotations) {
if(annotation instanceof Id){
return true;
}
}
return false;
}
/**
* Find a object by Id
* Find <T>
*/
public T find(Serializable entityId) {
String sql = "select * from "+getTableName()+" where "+getId()+" = ?";
return (T)getJdbcTemplate().queryForObject(sql, new Object[]{entityId},new GenericRowMapper());
}
/**
* save entity
* @return
*/
public int save(T entity) {
SimpleJdbcInsert insertActor = new SimpleJdbcInsert(getJdbcTemplate());
insertActor.setTableName(getTableName());
log.debug(insertActor.getInsertString());
insertActor.setGeneratedKeyName(getId());
return insertActor.executeAndReturnKey(new BeanPropertySqlParameterSource(entity)).intValue();
};
/**
* Get field count which is not null.
* @param fields
* @param entity
* @return
*/
private int getNotNullFieldSize(Field []fields,T entity){
int size = 0;
try {
for (Field field : fields) {
Object value = FieldUtils.readDeclaredField(entity, field.getName(), true);
if(value != null){
size ++;
}
}
} catch (IllegalAccessException e) {
e.printStackTrace();
}
return size;
}
/**
* update single entity
* Entity Id required
* update non-null field.
*/
public int update(T entity) {
String id = getId();
StringBuilder sql = new StringBuilder();
sql.append("update ");
sql.append(getTableName());
sql.append(" set ");
Field []fields = entity.getClass().getDeclaredFields();
Object []params = new Object[getNotNullFieldSize(fields, entity)];
int index = 0;
try {
for (int i = 0;i < fields.length; i++) {
Field field = fields[i];
Object value = FieldUtils.readDeclaredField(entity, field.getName(), true);
//if value is null,then discard
boolean isNotIdField = !id.equals(field.getName());
if(isNotIdField && null != value){
sql.append(" ");
sql.append(field.getName());
sql.append(" = ? ");
params[index++] = FieldUtils.readDeclaredField(entity, field.getName(), true);
sql.append(",");
}
}
sql.append("where"+id);
sql = new StringBuilder(sql.toString().replace(",where", " where "));
sql.append(" = ?");
params[index] = FieldUtils.readDeclaredField(entity, id, true);
} catch (IllegalAccessException e) {
log.debug(e.getMessage());
e.printStackTrace();
}
log.debug("Excute SQL:"+sql.toString());
log.debug("params:"+ReflectionToStringBuilder.toString(params));
return update(sql.toString(),params);
}
/**
* update through sql with params
* @param sql
* @param params
* @return result count.
*/
public int update(String sql,Object ...params){
return getJdbcTemplate().update(sql,params);
}
/**
* find all of entity
*/
public List<T> findAll() {
StringBuilder sql = new StringBuilder();
sql.append("select * from ").append(getTableName());
return findBySQL(sql.toString());
}
/**
* find all by sql
*/
public List<T> findBySQL(String sql) {
return getJdbcTemplate().query(sql.toString(),new GenericRowMapper());
}
/**
* find by sql with params
* @param sql
* @param params
* @return
*/
public List<T> find(String sql,Object ...params) {
return getJdbcTemplate().query(sql.toString(),params,new GenericRowMapper());
}
/**
* Find Pager
* @param pageIndex
* @param pageSize
* @param params like name="jetty" you can put it in map
* params.put("name","jetty");
* @param orders
* @return
*/
public Pager<T> findPager(int pageIndex,int pageSize,Map<String, Object> params,List<Order> orders){
String sql = "select * from "+getTableName();
Object [] sqlParams = null;
if(MapUtils.isNotEmpty(params)){
//log.error("Throw error when execute findPager method,params is empty!");
//Append params to sql string.
Set<String> pKeys = params.keySet();
sqlParams = new Object[params.size()];
sql += " where ";
int i = 0;
for (String key : pKeys) {
sql += key + " like ? ";
sqlParams[i] = "%"+params.get(key)+"%";
//last parameter can't contact ','
if(i != params.size()-1){
sql += ",";
}
i ++;
}
}
//Append orders to sql string.
if(CollectionUtils.isNotEmpty(orders)){
sql += " order by ";
int j = 0;
for (Order order : orders) {
sql += order.getName() + " " + order.getSort();
if(j != orders.size() - 1){
sql += ",";
}
j ++;
}
}
return findPager(sql, pageIndex, pageSize,sqlParams);
}
public Pager<T> findPager(String sql,int pageIndex,int pageSize,Object ...sqlParams){
int start = (pageIndex -1)*pageSize;
int totalCount = getCount();
//Page count
int pageSum = 1;
if (totalCount % pageSize == 0) {
pageSum = totalCount / pageSize;
} else {
pageSum = totalCount / pageSize + 1;
}
sql += " limit "+ start +","+pageSize;
log.debug("execute findPager SQL : "+sql);
List<T> list = null;
if(ArrayUtils.isNotEmpty(sqlParams)){
list = find(sql, sqlParams);
}else{
list = findBySQL(sql);
}
return new Pager<T>(totalCount, pageIndex, pageSum, pageSize, list);
}
/**
* Find a pager
* @param pageIndex
* @param pageSize
* @return
*/
public Pager<T> findPager(int pageIndex,int pageSize){
int totalCount = getCount();
int start = (pageIndex -1)*pageSize;
//Page count
int pageSum = 1;
if (totalCount % pageSize == 0) {
pageSum = totalCount / pageSize;
} else {
pageSum = totalCount / pageSize + 1;
}
String sql = "select * from "+getTableName()+" limit "+ start +","+pageSize;
List<T> list = findBySQL(sql);
log.debug(sql);
return new Pager<T>(totalCount, pageIndex, pageSum, pageSize, list);
}
/**
* Get count of entity
*/
public int getCount() {
String sql="select count(1) from "+getTableName();
return getJdbcTemplate().queryForInt(sql);
}
/**
* A generic row mapper class.
* @author lixiaodong
*/
class GenericRowMapper implements RowMapper<T>{
@SuppressWarnings("unchecked")
@Override
public T mapRow(ResultSet rs, int rowNum) throws SQLException {
Map<String, Object> columns = new ColumnMapRowMapper().mapRow(rs, rowNum);
Object object = null;
try {
object = getEntityClass().newInstance();
String fieldName = null;
for (String key : columns.keySet()) {
fieldName = lowerCaseFirst(key);
FieldUtils.writeDeclaredField(object, fieldName, columns.get(key), true);
}
} catch (InstantiationException e) {
log.debug(e.getMessage());
e.printStackTrace();
} catch (IllegalAccessException e) {
log.debug(e.getMessage());
e.printStackTrace();
}
return (T)object;
}
}
private String lowerCaseFirst(String str) {
return (str != null) ? str.substring(0, 1).toLowerCase()
+ str.substring(1) : null;
}
}
相关推荐
达梦数据库操作手册 达梦数据库是一种关系型数据库管理系统(RDBMS),具有高性能、高可靠性和高安全性。它适用于各种应用场景,包括企业级应用、大数据处理和云服务等。本操作手册旨在为使用达梦数据库的用户提供...
C#编程 数据库操作应用 DynamicQuery(源码)(源码)C#编程 数据库操作应用 DynamicQuery(源码)(源码)C#编程 数据库操作应用 DynamicQuery(源码)(源码)C#编程 数据库操作应用 DynamicQuery(源码)(源码)C#编程 数据库...
在C#编程中,数据库操作是常见的任务,用于与数据存储进行交互。AccessHelper是一个专门为Access数据库设计的C#操作类,它简化了对数据库的读写和其他常见操作。以下是对AccessHelper类及其功能的详细解释: 1. **...
在IT领域,数据库操作是应用程序开发中的核心环节,尤其是在桌面应用和嵌入式系统中。Qt框架提供了一个强大的工具集,使得开发者可以方便地利用SQLite数据库进行数据存储和管理。本篇文章将深入探讨如何在QT5.14.2...
C#编程 数据库操作应用 UseUpdate(源码)(源码)C#编程 数据库操作应用 UseUpdate(源码)(源码)C#编程 数据库操作应用 UseUpdate(源码)(源码)C#编程 数据库操作应用 UseUpdate(源码)(源码)C#编程 数据库操作应用 ...
C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 ...
数据库操作流程数据库操作流程数据库操作流程
windows 关于qt的数据库操作封装类 以及用例: SQLite,是一款轻型的数据库,是遵守ACID的关系型数据库管理系统,它包含在一个相对小的C库中。它的功能特点有: 1. ACID事务 2. 零配置 – 无需安装和管理配置 3....
在处理数据库操作时,开发者经常使用ADO.NET(ActiveX Data Objects .NET)库,它提供了与多种数据库交互的能力,包括Microsoft Access。"C# ACCESS 数据库操作类"是一个自定义的C#类,设计用来简化对Access数据库的...
在IT行业中,数据库操作是核心任务之一,尤其是在开发企业级应用程序时。为了简化数据库操作,开发者经常使用封装好的类库,以实现代码的复用性和稳定性。本篇将详细讲解"通用数据库操作类库"这一主题,特别是针对C#...
除了基础的ADO.NET操作,你还可以使用ORM(对象关系映射)框架,如Entity Framework,简化数据库操作。这使得代码更易于维护且更少的直接SQL交互。 10. **错误处理**: 处理可能出现的异常是良好编程实践的一部分...
C# SQL 数据库操作类代码 C# SQL 数据库操作类是指通过C#语言编写的数据库操作类,可以直接连接SQL数据库,并进行数据的更新、查询等操作。该类提供了构造函数初始化连接字符串、插入数据、查询数据等方法,方便...
在Java编程领域,数据库操作是不可或缺的一部分,尤其是在开发企业级应用程序时。本资料"Java数据库操作类20170703"聚焦于利用Java进行数据库交互,并且支持多种类型的数据库,包括Excel、Access、MSSQLServer、...
主要介绍了PHP简单数据库操作类实例,支持增删改查及链式操作,非常...提供一个数据库操作类(模型Model),供大家使用。支持增、删、改、查,支持链式操作,代码不到100行,非常小巧方便,很适合小项目的快速部署使用。
【标题】:“云的ADO数据库操作支持库演示” 在标题中提到的“云的ADO数据库操作支持库演示”指的是利用ActiveX Data Objects (ADO)技术进行数据库操作,并且这种操作是在云端环境中进行的。ADO是Microsoft开发的一...
在C++编程中,数据库操作通常需要通过特定的API或者库来实现,比如ODBC(Open Database Connectivity)或更高级的如MySQL Connector/C++。在这个主题中,"c++数据库操作类(很好用)" 提供了一个可能的自定义封装,...
7. **事务处理**:对于涉及多条数据库操作的复杂事务,DBConnection类可能会提供开始、提交和回滚事务的功能,确保数据的一致性。 在提供的`test.php`文件中,我们可以预期看到如何实例化DBConnection类,设置不同...
数据库的操作基本也就增删改查四类,本文主要列出PHPCMS V9的数据库操作类常用的增删改查的使用方法,为我们对PHPCMS二次开发时对数据库操作时提供帮助。
在VB.NET编程环境中,数据库操作是一项基础且重要的技能。本实例是基于VB.NET 2005的一个简单项目,它涵盖了数据库的添加、删除和查询功能。该项目使用了ADO.NET库,这是一种强大的数据访问技术,使得VB.NET可以方便...
关系数据库操作示例 关系数据库是当今信息时代中最为重要的数据存储和管理方式。它可以将大量的数据组织起来,提供了高效的数据存储和检索方式。关系数据库的核心是关系代数和SQL语言,它们是关系数据库的基础。 ...