通过反射封装JDBC
具体上代码我的BaseDao:
public class BaseDao<T> {
private Class clazz;
private Properties pro=null;
public BaseDao(){
ParameterizedType pt=(ParameterizedType) this.getClass().getGenericSuperclass(); //按英译意思是获取这个类的泛型父类
clazz=(Class) pt.getActualTypeArguments()[0]; //得到真实的类型内容
pro=MainKey.getMainKeyType(clazz); //静态方法获取的是每个实体类的类名(相当于数据库里的表明)和数据库里的主键自动增长列
}
//返回数据库连接
private Connection getConnection() throws IOException{
try {
Properties pro=new Properties();
pro.load(BaseDao.class.getClassLoader().getResourceAsStream("config.Properties")); //我的连接数据库配置文件
Class.forName(pro.getProperty("driver"));
return DriverManager.getConnection(pro.getProperty("url"), pro.getProperty("user"), pro.getProperty("pwd"));
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 添加
* @param t
* 要保存的类
* @return 成功返回true/失败返回false
*/
public boolean save(T t){
Connection con=null;
try {
con = getConnection();
Field[] filds=clazz.getDeclaredFields(); //获取公开的字段包括私有
StringBuffer sb=new StringBuffer();
sb.append("INSERT INTO ["+t.getClass().getSimpleName()+ "](");
for (Field field : filds) {
if(field.getName().equals(pro.getProperty("idname"))){
continue;
}
sb.append(field.getName()+",");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")VALUES(");
List<Object> prams=new ArrayList<Object>();
for (Field field : filds) {
if(field.getName().equals(pro.getProperty("idname"))){
continue;
}
PropertyDescriptor pd=new PropertyDescriptor(field.getName(),clazz);
Method mt=pd.getReadMethod();
Object obj=mt.invoke(t);
prams.add(obj);
sb.append("?,");
}
sb.deleteCharAt(sb.length()-1);
sb.append(")");
PreparedStatement ps=con.prepareStatement(sb.toString(),Statement.RETURN_GENERATED_KEYS); //Statement.RETURN_GENERATED_KEYS可以获
//得自增列的id号
for (int i = 0; i < prams.size(); i++) {
ps.setObject(i+1,prams.get(i));
}
int count=ps.executeUpdate();
ResultSet rs=ps.getGeneratedKeys(); //在这里可以把自增列的ID号读出来
if(rs.next()){
System.out.println("key:"+rs.getInt(1));
}
if(count>0){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
/**
* 删除
* @param ser 参数
* @return 成功返回true/失败返回false
*/
public boolean delete(Serializable ser){
Connection con=null;
try {
con=getConnection();
String sql="DELETE FROM"+pro.getProperty("tableName")+" where "+pro.getProperty("idname")+"=?";
PreparedStatement ps=con.prepareStatement(sql);
ps.setObject(1,ser);
int count=ps.executeUpdate();
if(count>0){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
/**
* 更新
* @param t要更新的类
* @return 成功返回true/失败返回false
*/
public boolean update(T t){
Connection con=null;
try {
con=getConnection();
StringBuffer sb=new StringBuffer();
sb.append("UPDATE"+pro.getProperty("tableName")+"set");
Field[] fields=clazz.getDeclaredFields();
List<Object> prams=new ArrayList<Object>();
for (Field field : fields) {
if(pro.getProperty("idname").equals(field.getName())){
continue;
}
sb.append(" "+field.getName()+"=?,");
PropertyDescriptor pd=new PropertyDescriptor(field.getName(), clazz);
Method mt=pd.getReadMethod();
Object obj=mt.invoke(t);
prams.add(obj);
}
sb.deleteCharAt(sb.length()-1);
sb.append(" where "+pro.getProperty("idname")+"=?");
PropertyDescriptor pd=new PropertyDescriptor(pro.getProperty("idname"), clazz);
Method mt=pd.getReadMethod();
Object obj=mt.invoke(t);
prams.add(obj);
PreparedStatement ps=con.prepareStatement(sb.toString());
for (int i = 0; i < prams.size(); i++) {
ps.setObject(i+1,prams.get(i));
}
int count=ps.executeUpdate();
if(count>0){
return true;
}
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return false;
}
/**
* 查询所有
* @return 实体类集合
*/
public List<T> findAll(){
Connection con=null;
PreparedStatement ps=null;
ResultSet rs=null;
try {
con=getConnection();
String sql="select * from"+pro.getProperty("tableName");
ps=con.prepareStatement(sql);
rs=ps.executeQuery();
List<T> list=new ArrayList<T>();
while(rs.next()){
T t=(T) clazz.newInstance();
Map<String,Field> map=new HashMap<String, Field>();
for (Field field : clazz.getDeclaredFields()) {
map.put(field.getName(),field);
}
int count=rs.getMetaData().getColumnCount();//每行多少列
for (int i = 0; i < count; i++) {
try {
Field field=map.get(rs.getMetaData().getColumnName(i+1).toLowerCase());
field.setAccessible(true);
if (field.getType().getName().equals(int.class.getName())|| field.getType().getName().equals(Integer.class.getName())) {
field.set(t, Integer.valueOf(rs.getObject(i + 1).toString()));
} else if (field.getType().getName().equals(Date.class.getName())) {
field.set(t, new Date(rs.getDate(i + 1).getTime()));
} else if (field.getType().getName().equals(Double.class.getName())|| field.getType().getName().equals(double.class.getName())) {
field.set(t, rs.getDouble(i + 1));
} else if (field.getType().getName().equals(
String.class.getName())) {
field.set(t, rs.getObject(i + 1).toString());
} else {
field.set(t, rs.getObject(i));
}
} catch (Exception e) {
e.printStackTrace();
}
}
list.add(t);
}
return list;
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
rs.close();
ps.close();
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return null;
}
****************************************************************************************************************************
每个实体类都配置了个Properties:用来存放每个实体类的类名(相当于数据库里的表明)和数据库里的主键自动增长列
tableName=[user]
MainKeyType=identity
idname=id
***********************************************
我的UserDao只要继承BaseDao就行:
public class UserDao extends BaseDao<User>
**********************************************
我的工具类用来返回 读取每个实体类的类名(相当于数据库里的表明)和数据库里的主键自动增长列的Properties:
public class MainKey {
public static Properties getMainKeyType(Class clazz){
Properties pro=new Properties();
String path=clazz.getName().replace(".", "/")+".Properties";
System.out.println(path);
try {
pro.load(MainKey.class.getClassLoader().getResourceAsStream(path));
} catch (IOException e) {
e.printStackTrace();
}
return pro;
*******************************************************
Main方法测试:
public static void main(String[] args) throws IOException {
UserDao ud=new UserDao();
User user=new User();
user.setId(2);
user.setAge(22);
user.setName("sp");
user.setPhone(138438);
ud.save(user);
// ud.update(user);
// System.out.println(ud.delete(1));
//MainKey.getMainKeyType(User.class);
}
}
}
通过反射封装JDBC的更多相关文章
- jdbc操作mysql(四):利用反射封装
前言 有了前面利用注解拼接sql语句,下面来看一下利用反射获取类的属性和方法 不过好像有一个问题,数据库中的表名和字段中带有下划线该如何解决呢 实践操作 工具类:获取connection对象 publ ...
- MySQL数据库学习笔记(十一)----DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- MySQL数据库学习笔记(十)----JDBC事务处理、封装JDBC工具类
[声明] 欢迎转载,但请保留文章原始出处→_→ 生命壹号:http://www.cnblogs.com/smyhvae/ 文章来源:http://www.cnblogs.com/smyhvae/p/4 ...
- JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法
JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 * 可以由Connection得到 */ 具体的应用代码: @Te ...
- MySQL JDBC事务处理、封装JDBC工具类
MySQL数据库学习笔记(十)----JDBC事务处理.封装JDBC工具类 一.JDBC事务处理: 我们已经知道,事务的概念即:所有的操作要么同时成功,要么同时失败.在MySQL中提供了Commit. ...
- DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类)
DAO设计模式实现数据库的增删改查(进一步封装JDBC工具类) 一.DAO模式简介 DAO即Data Access Object,数据访问接口.数据访问:故名思义就是与数据库打交道.夹在业务逻辑与数据 ...
- 【转】JDBC学习笔记(5)——利用反射及JDBC元数据编写通用的查询方法
转自:http://www.cnblogs.com/ysw-go/ JDBC元数据 1)DatabaseMetaData /** * 了解即可:DatabaseMetaData是描述数据库的元数据对象 ...
- Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法
先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...
- 一、JDBC的概述 二、通过JDBC实现对数据的CRUD操作 三、封装JDBC访问数据的工具类 四、通过JDBC实现登陆和注册 五、防止SQL注入
一.JDBC的概述###<1>概念 JDBC:java database connection ,java数据库连接技术 是java内部提供的一套操作数据库的接口(面向接口编程),实现对数 ...
随机推荐
- nrf51822裸机教程-GPIOTE
GPIO通常都会具有中断功能,上一讲的GPIO中并没有涉及到中断的相关寄存器. 51822将GPIO的中断相关做成了一个单独的模块GPIOTE,这个模块不仅提供了GPIO的中断功能,同时提供了 通过t ...
- Cloudera Hadoop什么是CDH及CDH版本介绍
本文引用自:Cloudera Hadoop什么是CDH及CDH版本介绍http://www.aboutyun.com/thread-6788-1-1.html(出处: about云开发) 云技术新兴的 ...
- Spring冲刺阶段二(1)
我们首先是根据同学们的评价来找补自己的不足之处,其中同学们反应最多的是我们的界面不够好看,但是我觉得虽然不好看但算是比较简洁.其次是没有体现内网在其中发挥的作用,这点我们还没有实现. 根据这些不足之处 ...
- storyboard中xib文件不加载问题
今天在用Xcode6自定义视图控制器时附带了一个XIB文件,然后把自定义的类绑定到storyboard的ViewController,如图所示 , 发现RootViewController对应的xi ...
- SqlServer2008R2 如何插入多条数据
列id 为自增列 insert into Websites2values('Google','https://www.google.cm/','USA',1),('淘宝','https://www.t ...
- qt 打开串口 UI卡死
imx6在qt中打开调试串口时,ui总是会卡死.调试串口已经被文件系统占用,而在qt的app中使用open函数却能够调用open函数,打开成功,造成ui卡死,并且调试串口也卡死.本文记录这个问题的解决 ...
- CentOS 6.8内核版本升级(升级至3.10)(转)
1.查看当前版本 [root@www.linuxidc.com docker]# cat /etc/issue CentOS release 6.8 (Final) Kernel \r on an \ ...
- EncodingAESKey
关键字:EncodingAESKey 公众平台消息体签名及加解密方案概述 1.新增消息体签名验证,用于公众平台和公众账号验证消息体的正确性 2.针对推送给微信公众账号的普通消息和事件消息,以及推送给设 ...
- python中新式类和经典类的区别
1).python在类中的定义在py2-3版本上是使用的有新式类和经典类两种情况,在新式类和经典类的定义中最主要的区别是在定义类的时候是否出现引用object;如:经典类:Class 类名::而新式类 ...
- markdown语法集锦
参考:http://wowubuntu.com/markdown/#blockquote 1. 标题 # 一级标题 ## 二级标题 ### 三级标题 共六级标题 2. 列表 有序列表:1,2,3: 无 ...