package com.huawei.base;

import java.io.Serializable;
import java.lang.reflect.Array;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.ParameterizedType;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.huawei.common.CallBack;
import com.huawei.common.Page;
import com.huawei.utils.BeanUtil;
import com.huawei.utils.DBUtil;

/**
* @author Administrator
*
*
* void executeQuery(String sql,Object[] parmas,CallBack callback) 通用的查询
* void executeUpdate(String sql,Object[] parmas) //通用的执行
*
* List<Object> findAll() //查询全部
* Object findOne(Integer id) //根据id查询一个
*
* void save(Object o) //给定一个对象 然后存储到数据库
*
* void update(Object o) //根据一个对象 更新数据库中所对应的字段
*
* void delete(Object o) //根据一个对象删除数据库中 对应的记录
* void deleteById(Integer id) //根据传入的id删除
* void delete(String sql,Object[] params) //自定义删除
*
*
*
*
*/
public abstract class BaseDAO<T,ID extends Serializable> {


//目标类 用于 反射
protected Class<T> clazz;

@SuppressWarnings("unchecked")
public BaseDAO() {
ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
//得到类上面的泛型参数的实际类型
clazz = (Class<T>) type.getActualTypeArguments()[0];
}

/**
* 通用的查寻方法
* @param sql 给定一个sql语句
* @param params 给定与sql语句中相对应的参数
* @param callBack 用于处理结果集的回调函数
*/
public void executeQuery(String sql,Object []params,CallBack callBack){

Connection connection = DBUtil.getConnection();

PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = connection.prepareStatement(sql);
//处理参数
if(params!=null && params.length>0){
for(int i=0;i<params.length;i++){
ps.setObject(i+1, params[i]);
}
}
System.out.println("ORM:"+sql);
rs = ps.executeQuery();
//处理业务逻辑
callBack.execute(rs);

} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.close(rs,ps,connection);
}

}

/**
* 除了查询以外 的所有操作
* @param sql 给定一个sql语句
* @param params 参数
*/
public void executeUpdate(String sql,Object []params){
Connection connection = DBUtil.getConnection();
PreparedStatement ps = null;
try {
ps = connection.prepareStatement(sql);
//处理参数
if(params!=null && params.length>0){
for(int i=0;i<params.length;i++){
ps.setObject(i+1, params[i]);
}
}
System.out.println("ORM:"+sql);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally{
DBUtil.close(ps,connection);
}
}

/**
* 通用查询
* @param sql
* @param params
* @return
*/
public List<T> find(String sql,Object []params){

final List<T> result = new ArrayList<T>();
this.executeQuery(sql, params, new CallBack() {

@Override
public void execute(ResultSet rs) throws SQLException {
//处理结果
try {
//得到虚拟表的 结构信息
ResultSetMetaData rsmd = rs.getMetaData();
while(rs.next()){
//每一行代表一个对象
T o = clazz.newInstance();
//每一个单元格 代表对象中的一个属性
for(int i=0;i<rsmd.getColumnCount();i++){
//得到列明
String column_name = rsmd.getColumnName(i+1);
//根据列名去得到 clazz中的 属性
Field field = clazz.getDeclaredField(column_name);
//得到 set方法 setUsername(String name)
Method method = clazz.getDeclaredMethod(BeanUtil.setter(field), field.getType());
method.invoke(o, rs.getObject(column_name));
}
result.add(o);
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
return result;
}

/**
* 查找全部
* @return 返回一个结果集
*/
public List<T> findAll(){
//存储结果集
String sql = "SELECT * FROM "+BeanUtil.getTableName(clazz);
return this.find(sql, null);
}

public T findById(ID id){
String sql = "SELECT * FROM "+BeanUtil.getTableName(clazz) +" WHERE id=?";
List<T> result = this.find(sql, new Object[]{id});
return result.size()>0?result.get(0):null;
}

public List<T> findBy(String prop,Object param){
String sql = "SELECT * FROM "+BeanUtil.getTableName(clazz) +" WHERE "+prop+"=?";
return this.find(sql, new Object[]{param});
}

public Page find4Page(Page page){
//构建sql语句
String sql = "SELECT * FROM "+BeanUtil.getTableName(clazz)+" LIMIT ?,?";
//得到数据
List<T> data = this.find(sql, new Object[]{(page.getCurr()-1)*page.getPageSize(),page.getPageSize()});
page.setRowCount(this.getCount());
page.setData(data);
return page;

}

public Long getCount(){
String sql = "SELECT COUNT(1) FROM "+BeanUtil.getTableName(clazz);
return this.getCount(sql, null);

}
public Long getCount(String sql,Object[] params){

final long []count = new long[]{0L};

this.executeQuery(sql, params, new CallBack() {

@Override
public void execute(ResultSet rs) throws SQLException {
while(rs.next()){
count[0] = rs.getLong(1);
}

}
});

return count[0];
}

/**
* 将给定的对象 持久化到数据库
* @param o 被持久化对象
*/
public void save(T o){
StringBuilder sb = new StringBuilder("INSERT INTO "+BeanUtil.getTableName(clazz)+" (");
StringBuilder values = new StringBuilder(" VALUES (");
//存储参数
List<Object> params = new ArrayList<Object>();
//得到所有的属性
Field []fields = clazz.getDeclaredFields();
try{
for(Field field:fields){
sb.append(BeanUtil.getColumnName(field)).append(",");
values.append("?,");
Method method = clazz.getDeclaredMethod(BeanUtil.getter(field));
//得到属性的值
params.add(method.invoke(o));
}
}catch (Exception e) {
e.printStackTrace();
}
//处理sql语句
sb.deleteCharAt(sb.length()-1).append(")");
values.deleteCharAt(values.length()-1).append(")");
sb.append(values);
this.executeUpdate(sb.toString(), params.toArray());
}



/**
* 更新 更新的对象中 一定要包含id
* @param o
*/
public void update(T o){
StringBuilder sb = new StringBuilder("UPDATE "+BeanUtil.getTableName(clazz)+" SET ");
//存储参数
List<Object> params = new ArrayList<Object>();
//得到所有的属性
Field []fields = clazz.getDeclaredFields();

Object id = null;

try{
for(Field field:fields){
//UPDATE USERS SET USERNAME=?,PASSWORD=?
String name = BeanUtil.getColumnName(field);
Method method = clazz.getDeclaredMethod(BeanUtil.getter(field));
//得到属性的值

Object value = method.invoke(o);

if("id".equals(name)){
id = value;
continue;
}
sb.append(name+"=?").append(",");
params.add(value);
}
}catch (Exception e) {
e.printStackTrace();
}
//处理sql语句
sb.deleteCharAt(sb.length()-1).append(" WHERE id=?");
if(id==null){
System.out.println("ID不能为空");
return;
}
params.add(id);
this.executeUpdate(sb.toString(), params.toArray());

}

@SuppressWarnings("unchecked")
public void delete(ID id){
//动态创建泛型数组
ID []ids = (ID[])Array.newInstance(id.getClass(), 1);
ids[0] =id;
this.delete(ids);
}

@SuppressWarnings("unchecked")
public void delete(T o){
try {
ID id = (ID)this.clazz.getDeclaredMethod("getId").invoke(o);
if(id!=null){
this.delete(id);
return ;
}
System.out.println("ID不能为空");
} catch (Exception e) {
e.printStackTrace();
}
}
public void delete(ID[] ids){
String sql = "DELETE FROM "+BeanUtil.getTableName(clazz) + " WHERE id in (?)";
this.executeUpdate(sql, ids);
}

public void delete(String sql,Object[] params){
this.executeUpdate(sql, params);
}
}

 

 

 

package com.huawei.common;

import java.sql.ResultSet;
import java.sql.SQLException;

public interface CallBack {

void execute(ResultSet rs) throws SQLException;
}

 

 

package com.huawei.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

/**
* @author Administrator
*
*/
public class DBUtil {


/**
* 得到数据库连接
* @return
*/
public static Connection getConnection(){
//显示加载驱动
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "123456");
return connection;
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (SQLException e) {
e.printStackTrace();
}
return null;
}

/**
*
* 释放资源
* @param objects
*/
public static void close(Object ...objects){
if(objects!=null && objects.length>0){
try {
for(Object o:objects){
if(o instanceof ResultSet){
((ResultSet)o).close();
}else if(o instanceof Statement){
((Statement)o).close();
}else if(o instanceof Connection){
((Connection)o).close();
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

public static void main(String[] args) {
System.out.println(getConnection());
}
}

 

 

 

package com.huawei.utils;

import java.lang.reflect.Field;

/**
* bean 工具
* @author Administrator
*
*/
public class BeanUtil {

/**
* 获取set方法名
* 获取标名
* @param clazz
*/
public static String getTableName(Class<?> clazz){
//获取类名
String name = clazz.getSimpleName();
name = name.substring(0, 1).toLowerCase()+name.substring(1);
return name;
}

/**
* @param field
* @return
*/
public static String setter(Field field){
String name = field.getName();
return "set"+name.substring(0,1).toUpperCase()+name.substring(1);
}
public static String getter(Field field){
String name = field.getName();
return "get"+name.substring(0,1).toUpperCase()+name.substring(1);
}

public static String getColumnName(Field field){
String name = field.getName();
return name.substring(0,1).toLowerCase()+name.substring(1);
}
}

 

 

package com.huawei.common;

import java.util.HashMap;
import java.util.Map;

/**
* 分页
* @author Administrator
*
*/
public class Page {

//总页数
private int pageCount = 0;
//每一页可显示的条数
private int pageSize = 10;
//数据的总数
private long rowCount = 0L;
//上一页
private int prev = 1;
//下一页
private int next;
//当前页
private int curr = 1;
//第一页
private int first = 1;
//最后一页
private int last;
//游标的宽度
private int navSize = 11;
//游标的起始位置
private int start = 1;
//存储分页数据
private Object data;
//存储搜索的字段
private Map<String, Object> keywords = new HashMap<String, Object>();

//游标的结束位置
private int end;

public Page() {

}


public Page(long rowCount,int curr) {
this.init(rowCount, curr);

}


private void init(long rowCount,int curr){
//初始化rowCount
this.rowCount = rowCount<0?0:rowCount;
//计算总页数
this.pageCount = (int)Math.ceil(this.rowCount*1.0 / this.pageSize);
//处理当前页
this.curr = Math.min(curr, this.pageCount);
this.curr = Math.max(1, this.curr);



//第一页
this.first = 1;
//最后一页
this.last = this.pageCount;
//上一页
this.prev = this.curr>1?(this.curr-1):1;
//下一页
this.next = this.curr<this.pageCount?(this.curr+1):this.pageCount;

//判断navSize和PageCount的关系
if(this.pageCount > this.navSize){
//处理位置在 开始的时候
if(this.curr <=(this.navSize/2+1)){
this.start = 1;
this.end = this.navSize;
// }else if((this.pageCount - this.curr)<=(this.navSize/2-1)){ //处理位置在结束的时候
}else if((this.pageCount - this.curr)<=(Math.ceil(this.navSize*1.0/2)-1)){ //处理位置在结束的时候
//this.start = this.curr-5;
this.start = this.pageCount - (this.navSize-1);
this.end = this.pageCount;
}else{ //处理位置在中间的时候
this.start = this.curr-(this.navSize/2);
this.end = this.start+this.navSize-1;
}
}else{ //处理pageCount很小的时候
this.start = 1;
this.end = this.pageCount;
}
}

public int getPageCount() {
return pageCount;
}
public void setPageCount(int pageCount) {
this.pageCount = pageCount;
}
public int getPageSize() {
return pageSize;
}
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public long getRowCount() {
return rowCount;
}
public void setRowCount(long rowCount) {
this.rowCount = rowCount;
this.init(rowCount, this.curr);
}
public int getPrev() {
return prev;
}
public void setPrev(int prev) {
this.prev = prev;
}
public int getNext() {
return next;
}
public void setNext(int next) {
this.next = next;
}
public int getCurr() {
return curr;
}
public void setCurr(int curr) {
this.curr = curr;
}
public int getFirst() {
return first;
}
public void setFirst(int first) {
this.first = first;
}

public int getLast() {
return last;
}
public void setLast(int last) {
this.last = last;
}
public int getNavSize() {
return navSize;
}
public void setNavSize(int navSize) {
this.navSize = navSize;
}
public int getStart() {
return start;
}

public void setStart(int start) {
this.start = start;
}

public int getEnd() {
return end;
}

public Object getData() {
return data;
}
public void setData(Object data) {
this.data = data;
}
public void setEnd(int end) {
this.end = end;
}


public Map<String, Object> getKeywords() {
return keywords;
}


public void setKeywords(Map<String, Object> keywords) {
this.keywords = keywords;
}


public static void main(String[] args) {
//System.out.println(Math.ceil(11L*1.0/10));

Page page = new Page(760L, 71);

System.out.println("总条数:"+page.getRowCount());
System.out.println("总页数:"+page.getPageCount());
System.out.println("首页:"+page.getFirst());
System.out.println("上一页:"+page.getPrev());
System.out.println("Start:"+page.getStart());
System.out.println("当前页:"+page.getCurr());
System.out.println("End:"+page.getEnd());
System.out.println("下一页:"+page.getNext());
System.out.println("尾页:"+page.getLast());

System.out.println(11/2-1);
System.out.println(76-70);
}



}