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#编程 数据库操作应用 LINQJoin(源码)(源码)C#编程 数据库操作应用 LINQJoin(源码)(源码)C#编程 数据库操作应用 LINQJoin(源码)(源码)C#编程 数据库操作应用 LINQJoin(源码)(源码)C#编程 数据库操作应用 LINQJoin...
在IT领域,数据库操作是应用程序开发中的核心环节,尤其是在桌面应用和嵌入式系统中。Qt框架提供了一个强大的工具集,使得开发者可以方便地利用SQLite数据库进行数据存储和管理。本篇文章将深入探讨如何在QT5.14.2...
C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 数据库操作应用 GetDataStruct(源码)(源码)C#编程 ...
数据库操作流程数据库操作流程数据库操作流程
在处理数据库操作时,开发者经常使用ADO.NET(ActiveX Data Objects .NET)库,它提供了与多种数据库交互的能力,包括Microsoft Access。"C# ACCESS 数据库操作类"是一个自定义的C#类,设计用来简化对Access数据库的...
这个压缩包"**C# SQL Server数据库操作DLL**"提供了一种便捷的方式,通过一个动态链接库(DLL)来处理这些操作,免去了手动编写大量基础数据库访问代码的麻烦。DLL(DBClass.dll)封装了对SQL Server数据库的基本...
在IT行业中,数据库操作是核心任务之一,尤其是在开发企业级应用程序时。为了简化数据库操作,开发者经常使用封装好的类库,以实现代码的复用性和稳定性。本篇将详细讲解"通用数据库操作类库"这一主题,特别是针对C#...
除了基础的ADO.NET操作,你还可以使用ORM(对象关系映射)框架,如Entity Framework,简化数据库操作。这使得代码更易于维护且更少的直接SQL交互。 10. **错误处理**: 处理可能出现的异常是良好编程实践的一部分...
C#数据库操作类,oracle数据库,支持事务,动态和 静态方法
Android SQLite 数据库操作报告 一、实验目的 Android 实验报告的主要目的是熟悉 Android 平台的文件操作、掌握 Android SQLite 数据库的设计和应用、熟悉 XML 和 JSON 文件的读取。通过本实验,用户可以掌握 ...
在Java编程领域,数据库操作是不可或缺的一部分,尤其是在开发企业级应用程序时。本资料"Java数据库操作类20170703"聚焦于利用Java进行数据库交互,并且支持多种类型的数据库,包括Excel、Access、MSSQLServer、...
主要介绍了PHP简单数据库操作类实例,支持增删改查及链式操作,非常...提供一个数据库操作类(模型Model),供大家使用。支持增、删、改、查,支持链式操作,代码不到100行,非常小巧方便,很适合小项目的快速部署使用。
VC++数据库操作实例解析(ADO技术,使用一个辅助类来进行操作) 本文主要介绍了使用VC++进行数据库操作的实例解析,使用ADO技术和一个辅助类来进行操作。ADO(ActiveX Data Objects)是Microsoft提供的一种数据访问...
【标题】:“云的ADO数据库操作支持库演示” 在标题中提到的“云的ADO数据库操作支持库演示”指的是利用ActiveX Data Objects (ADO)技术进行数据库操作,并且这种操作是在云端环境中进行的。ADO是Microsoft开发的一...
数据库的操作基本也就增删改查四类,本文主要列出PHPCMS V9的数据库操作类常用的增删改查的使用方法,为我们对PHPCMS二次开发时对数据库操作时提供帮助。