package com.xiaoleilu.hutool.db;

import java.sql.SQLException;
import java.util.List;

import com.xiaoleilu.hutool.StrUtil;
import com.xiaoleilu.hutool.db.handler.EntityHandler;
import com.xiaoleilu.hutool.db.handler.SingleEntityHandler;

/**
 * 数据访问层模板
 * @author Looly
 *
 */
public class DaoTemplate {
	protected SqlRunner runner;
	
	/** 表名 */
	protected String tableName;
	/** 本表的主键字段，请在子类中覆盖或构造方法中指定，默认为id */
	protected String primaryKeyField = "id";
	
	//--------------------------------------------------------------- Constructor start
	public DaoTemplate(String tableName) {
		this.tableName = tableName;
	}
	
	public DaoTemplate(String tableName, String primaryKeyField) {
		this.tableName = tableName;
		this.primaryKeyField = primaryKeyField;
	}
	
	public DaoTemplate(String tableName, String primaryKeyField, SqlRunner runner) {
		this.tableName = tableName;
		this.primaryKeyField = primaryKeyField;
		this.runner = runner;
	}
	//--------------------------------------------------------------- Constructor end
	
	/**
	 * 添加
	 * @param entity 实体对象
	 * @return 插入行数
	 * @throws SQLException
	 */
	public int add(Entity entity) throws SQLException {
		entity.setTableName(tableName);
		return runner.insert(entity);
	}
	
	/**
	 * 添加
	 * @param entity 实体对象
	 * @return 主键列表
	 * @throws SQLException
	 */
	public List<Object> addForGeneratedKeys(Entity entity) throws SQLException {
		entity.setTableName(tableName);
		return runner.insertForGeneratedKeys(entity);
	}
	
	/**
	 * 添加
	 * @param entity 实体对象
	 * @return 自增主键
	 * @throws SQLException
	 */
	public Long addForGeneratedKey(Entity entity) throws SQLException {
		entity.setTableName(tableName);
		return runner.insertForGeneratedKey(entity);
	}
	
	/**
	 * 删除
	 * @param <T> 主键类型
	 * 
	 * @param pk 主键
	 * @return 删除行数
	 * @throws SQLException
	 */
	public <T> int del(T pk) throws SQLException {
		if (pk == null) {
			return 0;
		}

		return runner.del(Entity.create(tableName).set(primaryKeyField, pk));
	}
	
	/**
	 * 删除
	 * @param <T> 主键类型
	 * 
	 * @param field 字段名
	 * @param value 字段值
	 * @return 删除行数
	 * @throws SQLException
	 */
	public <T> int del(String field, T value) throws SQLException {
		if (StrUtil.isBlank(field)) {
			return 0;
		}

		return runner.del(Entity.create(tableName).set(field, value));
	}
	
	
	/**
	 * 更新职位信息
	 * 
	 * @param entity 实体对象，必须包含主键
	 * @return 更新行数
	 * @throws SQLException
	 */
	public int update(Entity entity) throws SQLException {
		entity.setTableName(tableName);
		Object pk = entity.get(primaryKeyField);
		if (null == pk) {
			throw new SQLException(StrUtil.format("Please determine `{}` for update", primaryKeyField));
		}

		Entity where = Entity.create(tableName).set(primaryKeyField, pk);
		Entity record = (Entity) entity.clone();
		record.remove(primaryKeyField);

		return runner.update(record, where);
	}
	
	/**
	 * 增加或者更新实体
	 * @param entity 实体，当包含主键时更新，否则新增
	 * @return 新增或更新条数
	 * @throws SQLException
	 */
	public int addOrUpdate(Entity entity) throws SQLException {
		if(entity.get(primaryKeyField) == null) {
			entity.set(primaryKeyField, add(entity));
			return 1;
		}else {
			 return update(entity);
		}
	}
	
	/**
	 * 根据主键获取单个记录
	 * @param <T>
	 * 
	 * @param pk 主键值
	 * @return 记录
	 * @throws SQLException
	 * @throws SQLException
	 */
	public <T> Entity get(T pk) throws SQLException {
		return runner.find(null,
				Entity.create(tableName).set(primaryKeyField, pk),
				new SingleEntityHandler());
	}
	
	/**
	 * 根据某个字段（最好是唯一字段）查询单个记录
	 * @param <T>
	 * 
	 * @param field 字段名
	 * @param value 字段值
	 * @return 记录
	 * @throws SQLException
	 * @throws SQLException
	 */
	public <T> Entity get(String field, T value) throws SQLException {
		return runner.find(null,
				Entity.create(tableName).set(field, value),
				new SingleEntityHandler());
	}
	
	/**
	 * 根据某个字段值查询结果
	 * @param <T>
	 * 
	 * @param field 字段名
	 * @param value 字段值
	 * @return 记录
	 * @throws SQLException
	 * @throws SQLException
	 */
	public <T> List<Entity> find(String field, T value) throws SQLException {
		return runner.find(null,
				Entity.create(tableName).set(field, value),
				new EntityHandler());
	}
	
	/**
	 * 查询当前表的所有记录
	 * @return 记录
	 * @throws SQLException
	 * @throws SQLException
	 */
	public List<Entity> findAll() throws SQLException {
		return runner.find(null,
				Entity.create(tableName),
				new EntityHandler());
	}
}

@@ -82,24 +82,56 @@
 il.List;%0D%0A%0D%0A
+import javax.sql.DataSource;%0D%0A%0D%0A
 import com.x
@@ -809,32 +809,182 @@
 yField;%0D%0A%09%7D%0D%0A%09%0D%0A
+%09public DaoTemplate(String tableName, String primaryKeyField, DataSource ds) %7B%0D%0A%09%09this(tableName, primaryKeyField,  DbUtil.newSqlRunner(ds));%0D%0A%09%7D%0D%0A%09%0D%0A
 %09public DaoTempl

fix Oracle