package com.bdqn.dao.impl;

import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.Connection;
import java.sql.DriverAction;
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.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Properties;
import java.util.regex.Matcher;

import javax.swing.plaf.InputMapUIResource;

import com.bdqn.bean.annotation.Column;
import com.bdqn.bean.annotation.Id;
import com.bdqn.bean.annotation.Table;
import com.bdqn.dao.IBaseDao;
import com.bdqn.util.DbUtil;
import com.bdqn.util.StringUtil;

public class BaseDaoimpl<T> implements IBaseDao<T>{

private static Connection conn;
private static String URL;//连接路径
private static String DRIVER;//数据库驱动
private static String USER;//用户名
private static String PASSWORD; //登陆密码


static {
init();
}
public static void init() {
//1.我们使用类的 字节码对象提供一个方法,getResourceAsStream 获取这个属性文件
InputStream in= BaseDaoimpl.class.getResourceAsStream("/jdbc.properties");
//2.
Properties props=new Properties();
//3.通过load去加载一个流,加载进来之后,属性的值装配到了这个Props对象中
try {
props.load(in);
DRIVER = props.getProperty("driver");
URL = props.getProperty("url");
USER = props.getProperty("user");
PASSWORD = props.getProperty("password");
Class.forName(DRIVER);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 得到数据连接 并登录数据库
*/
@Override
public Connection getConnection() {


try {
//一个连接对象,有可能是null ,有可能不是null,只是关闭了
if(conn == null || conn.isClosed() ) {
//驱动 得到 连接对象 路径 用户名 用户密码
conn= DriverManager.getConnection(URL, USER, PASSWORD);

}
} catch (SQLException e) {
e.printStackTrace();
}
return conn;
}

/**
* 执行Sql语句
* 影响行数
*/
@Override
public int executeUpdate(String sql, Object...objects) {
conn = getConnection(); //本类方法

//1 通过连接对象获取ps
PreparedStatement ps =null;
int row=0;
try {
conn.setAutoCommit(false);
ps= conn.prepareStatement(sql);
for(int i=0; i<objects.length;i++) {
ps.setObject(i+1, objects[i]);
}
row =ps.executeUpdate();//执行语句
//进行事务提交
// conn.commit();
} catch (SQLException e) {
//保持数据统一性 捉到的错误进行回滚
try {
conn.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}finally {
DbUtil.close(conn, ps);
}
return 0;
}

/**
* 按照id查询 得到一个集合
*/
@Override
public Map<String, Object> queryByPrimaryKey(String sql, Object key) {
conn= getConnection();
//通过连接对象获取ps,
PreparedStatement ps= null;
ResultSet rs =null;
ResultSetMetaData rsmd = null;
Map<String,Object> map= new HashMap<>();

try {
ps= conn.prepareStatement(sql);
ps.setObject(1, key);
//获取结果集
rs=ps.executeQuery();
rsmd=rs.getMetaData();
int row=0;
//结果集封装
while(rs.next()) {
if(row >0) {
throw new RuntimeException("查出不止一个,万万不行的");
}
row++;
//什么当key 什么当值
for(int i=0; i<rsmd.getColumnCount();i++) {
map.put(rsmd.getColumnLabel(i+1), rs.getObject(i+1));
}
System.out.println("以下是你要查询的员工");
System.out.println("id\tname\tsex\taddress\tPhone\temall");
System.out.print(rs.getInt(1)+"\t");
System.out.print(rs.getString(2)+"\t");
System.out.print(rs.getString(3)+"\t");
System.out.print(rs.getString(4)+"\t");
System.out.print(rs.getString(5)+"\t");
System.out.print(rs.getString(6)+"\t");

}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DbUtil.close(conn, ps);
}
return map;
}

/**
* 客观查找(可以按条件查找)
*/
@Override
public List<Map<String, Object>> selectTive(String sql, Object...objects) {
conn= getConnection();
//通过对象连接对象
PreparedStatement ps= null;
ResultSet rs= null;
ResultSetMetaData rsmd=null;

List<Map<String ,Object>> list=new ArrayList<>();
try {
ps= conn.prepareStatement(sql);
for(int i=1;i<=objects.length;i++) {
ps.setObject(i,objects[i-1]);
}
rs= ps.executeQuery();
rsmd=rs.getMetaData();
//结果集的封装
while(rs.next()) {
Map<String,Object> map =new HashMap<>();
for(int i=0; i<rsmd.getColumnCount();i++) {
map.put(rsmd.getColumnLabel(i+1), rs.getObject(i+1));
}
list.add(map);

}
} catch (SQLException e) {
e.printStackTrace();
}finally {
DbUtil.close(conn, ps);
}

return list;
}

/**
* 按照id查找把整个对象插入
*/
@Override
public T selectByKey(String sql, Object id, Class<T> clz) {
T obj= null;
Map<String,Object>map =queryByPrimaryKey(sql, id);
try {
obj=clz.newInstance();
Method[] methods = clz.getDeclaredMethods();
Iterator<Entry<String, Object>> it = map.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Object>entry =it.next();
String key= entry.getKey();
String camel=StringUtil.under2Camel(key);
//如果使用的是下划线风格,讲其转换为驼峰命名风格.\
Object value= entry.getValue();
for(int j = 0 ; j < methods.length ;j ++) {
String method = methods[j].getName();
method = method.substring(3, method.length());
if(method.equalsIgnoreCase(camel) && methods[j].getName().startsWith("set")) {
methods[j].invoke(obj, value);
}
}
}
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();

} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj;
}

/**
* 对象 客串化
*/
@Override
public T one(Class<T> clz, Serializable id) {
String tableName= clz.getSimpleName();
String sql ="select * from"+tableName+"where id =?";
System.err.println(sql);
T o=selectByKey(sql, id, clz);
return null;
}


@Override
public T selectOne(Class<T> clz, Serializable id) {
//使用反射动态分析数据,有那些自动
// 1 扫描类注解 2扫描字段注解
Annotation[] classAns = clz.getDeclaredAnnotations();
Field[] fields = clz.getDeclaredFields();
String tableName = null;
List<String> columns = new ArrayList<>();
String key = null;
if(classAns.length > 0 ) {
for(int i = 0 ; i < classAns.length; i++) {
if(classAns[i].annotationType().getSimpleName().equals("Table")) {
Table table = (Table) classAns[i];
tableName = table.name();
if(tableName == null || tableName.equals("")) {
tableName = clz.getSimpleName();
}
}
}
} else {
tableName = clz.getSimpleName();
}
Map<String, String> field2Column = new HashMap<>();
if(fields.length > 0) {
// 获取每一filed的时候就顺便把这个fieldName和value都获取了
for(int i = 0 ; i < fields.length ; i++) {
Annotation[] filedAnnotaions = fields[i].getDeclaredAnnotations();
for (Annotation annotation : filedAnnotaions) {
if(annotation.annotationType().getSimpleName().equals("Column")) {
// 如果加上@Column注解的话。
Column col = (Column) annotation;
columns.add(col.name());
field2Column.put(col.name(), fields[i].getName());
}

if(annotation.annotationType().getSimpleName().equals("Id")) {
// 如果加上@Column注解的话。
Id _id = (Id) annotation;
key = _id.name();
field2Column.put(_id.name(), fields[i].getName());
}
}

}

}

StringBuilder sb = new StringBuilder();
sb.append("select " + key + " , ");
for (String string : columns) {
sb.append(" " + string + ",");
}
// 去除最后一个逗号
sb.deleteCharAt(sb.length()-1);
sb.append(" from " + tableName + " where " + key + " = ? ");
String sql = sb.toString();
System.out.println(sql);
Map<String, Object> map = queryByPrimaryKey(sql, id);
T obj = map2Bean(map,field2Column,clz);
return obj;
}

private T map2Bean(Map<String, Object> map, Map<String, String> field2Column, Class<T> clz) {
try {
T o = clz.newInstance();
// 去调用它的所有的set方法
Method[] methods = clz.getDeclaredMethods();
for (Method method : methods) {
// 遍历field2Column 取它每个值去匹配set方法
Iterator<Entry<String, String>> it = field2Column.entrySet().iterator();
while(it.hasNext()) {
Entry<String, String> entry = it.next();
String key = entry.getKey();
String value = entry.getValue();
// 转换大小写之后比较contains还不够安全,采用equsls比较
String methodName = method.getName();
// 如果有某些方法长度不满足3,这个时候截取无疑是不安全的。
if(methodName.length() > 3) {
methodName = methodName.substring(3);
if(methodName.equalsIgnoreCase(value) && method.getName().startsWith("set")) {
// 证明这个值满足条件的
method.invoke(o, map.get(key));
}
}
}
}
return o;
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return null;

}
@Override
public List<T> list(String sql, Class<T> clz, Object... objects) {
List<T> list= new ArrayList<>();
List<Map<String,Object>> l = selectTive(sql, objects);
Method[] methods=clz.getDeclaredMethods();
for(int i=0; i<l.size();i++) {
try {
T obj=clz.newInstance();
Map<String, Object> map = l.get(i);
Iterator<Entry<String, Object>> it = map.entrySet().iterator();
while(it.hasNext()) {
Entry<String, Object> entry = it.next();
String key = entry.getKey();
String camel = StringUtil.under2Camel(key);
// 如果使用的是下划线风格,将其转换为驼峰命名 的风格。
Object value = entry.getValue();
for(int j = 0 ; j < methods.length ;j ++) {
String method = methods[j].getName();
method = method.substring(3, method.length());
if(method.equalsIgnoreCase(camel) && methods[j].getName().startsWith("set")) {
methods[j].invoke(obj, value);
}
}
}
list.add(obj);
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}

return list;
}

}

java方式连接数据操作数据库的更多相关文章

  1. 使用python简单连接并操作数据库

    python中连接并操作数据库 图示操作流程 一.使用的完整流程 # 1. 导入模块 from pymysql import connect # 2. 创建和数据库服务器的连接,自行设置 服务器地址, ...

  2. PHP连接MYSQL操作数据库

    PHP连接MYSQL操作数据库 <?php $con = mysql_connect("localhost","root",""); ...

  3. jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行?

    jsp页面:js方法里嵌套java代码(是操作数据库的),如果这个js 方法没被调用,当jsp页面被解析的时候,不管这个js方法有没有被调用这段java代码都会被执行? 因为在解析时最新解析的就是JA ...

  4. 【node】node连接mongodb操作数据库

    1.下载第三方模块mongodb cnpm install mongodb --save 2.检测是否连接成功 1.引入第三方模块mongodb并创建一个客户端 const MongoClient = ...

  5. 【node】------node连接mongodb操作数据库------【巷子】

    1.下载第三方模块mongodb cnpm install mongodb --save 2.检测是否连接成功 1.引入第三方模块mongodb并创建一个客户端 const MongoClient = ...

  6. 使用Java API连接和操作HBase数据库

    创建的数据库存储如下数据 表结构 java代码 public class HbaseTest { /** * 配置ss */ static Configuration config = null; p ...

  7. JAVA连接、操作数据库的DBHelper

    工厂模式的DBHelper 1 import java.sql.Connection; 2 import java.sql.DriverManager; 3 import java.sql.Prepa ...

  8. java批量插入数据进数据库中

    方式1: for循环,每一次进行一次插入数据. 方式2: jdbc的preparedStatement的batch操作 PreparedStatement.addBatch(); ...... Pre ...

  9. Python 连接、操作数据库

    使用python3+pymysql 一.安装python3 a)         从网上下载安装吧 二.安装pymysql https://pypi.python.org/pypi/PyMySQL h ...

随机推荐

  1. 2981:大整数加法-poj

    2981:大整数加法 总时间限制:  1000ms 内存限制:  65536kB 描述 求两个不超过200位的非负整数的和. 输入 有两行,每行是一个不超过200位的非负整数,可能有多余的前导0. 输 ...

  2. 面向对象编程 —— java实现函数求导

    文章目录 ★引子 ★求导 ★最初的想法 ★初步的想法 ★后来的想法 ★最后的想法 ★编程范式 ★结尾 首先声明一点,本文主要介绍的是面向对象(OO)的思想,顺便谈下函数式编程,而不是教你如何准确地.科 ...

  3. CNCC2017中的深度学习与跨媒体智能

    CNCC2017中的深度学习与跨媒体智能 转载请注明作者:梦里茶 目录 机器学习与跨媒体智能 传统方法与深度学习 图像分割 小数据集下的深度学习 语音前沿技术 生成模型 基于贝叶斯的视觉信息编解码 珠 ...

  4. CentOS下redis集群安装

    环境: 一台CentOS虚拟机上部署六个节点,创建3个master,3个slave节点 1.下载并解压 cd /root wget http://download.redis.io/releases/ ...

  5. php面试之四-Linux部分

    php面试题之四——Linux部分(高级部分) 四.Linux部分 1.请解释下列10个shell命令的用途(新浪网技术部) top.ps.mv.find.df.cat.chmod.chgrp.gre ...

  6. php结合redis实现秒杀功能

    <?php 第一种,简单实现 $conn=mysql_connect("localhost","big","123456"); if( ...

  7. Golang学习--包管理工具glide

    上一篇文章中我们已经成功的运行了go的代码,这是我们迈出的最基础的一步. 一个项目通常会依赖很多外部的库,当依赖的库比较多的时候,手工管理就会比较麻烦,这个时候就需要包管理工具出场了,帮你管理好所有依 ...

  8. Spring Cloud Zuul 添加 ZuulFilter

    紧接着上篇随笔Spring Cloud Zuul写,添加过滤器,进行权限验证 1.添加过滤器 package com.dzpykj.filter; import java.io.IOException ...

  9. 两个port贴合七夕主题,百度输入法的“情感营销”策略

        一年一度的七夕佳节是情侣.夫妻之间传情达意.诉说衷肠的最佳时节.基于这一背景.一些传统企业.互联网公司也会针对性的推出一些营销策划,使产品和服务更贴近用户需求,更"接地气" ...

  10. 一句话搞定webmap(一)——轻地图组件

    摘要: 遥想当年.在APP中增加LBS元素相当困难:要刻苦学习java,要刻苦学习iOS开发,要刻苦学习javascript-- 而现在.要制作一张地图真是越来越easy了!居然仅仅须要一句话.就能够 ...