反射写一个通用的dao层

  • 1. 学了反射,就得学会搞事情
  • 2. 反射写dao具体实现

1. 学了反射,就得学会搞事情

  • 我想怎么对实体类操作,就对实体类操作

  • 想实现通用的dao,要满足的条件:

    1. 实体类名与表名一样
    2. 实体字段名与表字段名一样
    3. 实体类定义的属性顺序与表名字段名顺序一样
    4. 使用dao修改,增加时,实体类的属性都要有赋值,因为根据反射拿到所有属性值,和属性名,来拼接成sql语句滴
  • 如何用反射操作操作

    1. 拼接sql语句
    2. 拿到表名
    3. 拿到实体类的字段
    4. 拿到字段的值

2. 反射写dao具体实现

  • BaseDao 拿到连接和释放资源
package com.lovely.dao;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class BaseDao {static {try {Class.forName("oracle.jdbc.OracleDriver");} catch (ClassNotFoundException e) {e.printStackTrace();}}public static Connection getConn() {Connection conn = null;String url = "jdbc:oracle:thin:@127.0.0.1:1521:orcl";try {conn = DriverManager.getConnection(url, "scott", "scott");} catch (SQLException e) {e.printStackTrace();}return conn;}public static void closeAll(Connection conn, PreparedStatement ps, ResultSet rs) {try {if (rs != null)rs.close();if (ps != null)ps.close();if (conn != null)conn.close();} catch (SQLException e) {e.printStackTrace();}}
}
  • 增删改查万能写法
package com.lovely.dao;import java.lang.reflect.Field;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;public class CommonDao {/*** @param entity 给定一个初始化参数的实体,来做添加操作* @return 返回数据库受影响行数*/public int add(Object entity) {int count = -1;Class<?> c = entity.getClass();StringBuffer sql = new StringBuffer();// insert into tab_name values (seq_student.nextval, ?, ?, ? ...);sql.append("insert into " + c.getSimpleName() + " values (seq_" + c.getSimpleName() + ".nextval");// 拿到实体类私有属性对象的数组Field[] fs = c.getDeclaredFields();Field.setAccessible(fs, true);// 排除主键for (int j = 1; j < fs.length; j++) {sql.append(", ?");}sql.append(")");System.out.println(sql);Connection conn = BaseDao.getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql.toString());// 赋值for (int i = 1; i < fs.length; i++) {ps.setObject(i, fs[i].get(entity));}count = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, null);}   return count;}/*** * @param c 描述类的类对象* @return 这张表在数据库里面所有的数据*/public List<Object> queryAll(Class<?> c) {ArrayList<Object> list = new ArrayList<Object>();String sql = "SELECT * FROM " + c.getSimpleName();Connection conn = BaseDao.getConn();PreparedStatement ps = null;ResultSet rs = null;conn = BaseDao.getConn();try {ps = conn.prepareStatement(sql);rs = ps.executeQuery();Field[] fs = c.getDeclaredFields();Field.setAccessible(fs, true);while (rs.next()) {// 创建实体类对象Object entity = c.newInstance();// 为实体类的每个属性赋值for (int i = 0; i < fs.length; i++) {// 取结果集中的值Object value = rs.getObject(fs[i].getName());// oracle 和 Java 中的类型不一样  设置属性值时 可能报错if (fs[i].getType() == Integer.class) {value = rs.getInt(fs[i].getName());} else if (fs[i].getType() == Double.class) {value = rs.getDouble(fs[i].getName());} else if (fs[i].getType() == Timestamp.class) {value = rs.getTimestamp(fs[i].getName());}// Can not set java.sql.Timestamp field com.lovely.entity.Product.pdate to java.sql.Date// 属性是Timstamp类型 Oracle获取的值是 java.sql.Date类型  /*if (fs[i].getType() == Timestamp.class && value.getClass() == java.sql.Date.class) {// 转型java.sql.Date d = (Date) value; value = new Timestamp(d.getTime());}*/// 为实体类属性赋值fs[i].set(entity, value);}list.add(entity);}} catch (SQLException e) {e.printStackTrace();} catch (InstantiationException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, rs);}return  list;}/*** * @param entity 传入主键即可* @return 返回主键对应的对象*/public Object queryOne(Object entity) {Object obj = null;Class<?> c = entity.getClass();Field[] fs = c.getDeclaredFields();Field.setAccessible(fs, true); // 可访问私有属性String sql = "select * from " + c.getSimpleName() + " where " + fs[0].getName() + " = ?";Connection conn = BaseDao.getConn();PreparedStatement ps = null;ResultSet rs = null;try {ps = conn.prepareStatement(sql);ps.setObject(1, fs[0].get(entity));rs = ps.executeQuery();if (rs.next()) {// 创建当前实体类对象obj = c.newInstance();for (int i = 0; i < fs.length; i++) {// 结果集中每个列的值Object value = rs.getObject(fs[i].getName());// 判断属性值的类型if (fs[i].getType() == Integer.class) {value = rs.getInt(fs[i].getName());} else if (fs[i].getType() == Double.class) {value = rs.getDouble(fs[i].getName());} else if (fs[i].getType() == java.sql.Timestamp.class) {value = rs.getTimestamp(fs[i].getName());}// 为每个属性设置值fs[i].set(obj, value);}}} catch (Exception e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, rs);}return obj; }/*** * @param entity 要修改的实体对象 实体对象的值都得被初始化* @return 返回受影响行数*/public int update(Object entity) {int count = -1;Class<?> c = entity.getClass();StringBuffer sql = new StringBuffer();// update tab_name set * = ?, * = ?, * = ? ... where primary_key = ?sql.append("update " + c.getSimpleName() + " set ");Field[] fs = c.getDeclaredFields();Field.setAccessible(fs, true);// 拼接列名try {for (int i = 1; i < fs.length; i++) {if (i < fs.length - 1)sql.append(fs[i].getName() + " = ?, ");elsesql.append(fs[i].getName() + " = ? ");}} catch (IllegalArgumentException e) {e.printStackTrace();}// 拼接条件sql.append("where " + fs[0].getName() + " = ?");System.out.println(sql);Connection conn = BaseDao.getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql.toString());// 设置 sql 中参数的值for (int i = 1; i < fs.length; i++) {ps.setObject(i, fs[i].get(entity));}// 设置主键值ps.setObject(fs.length, fs[0].get(entity));count = ps.executeUpdate();} catch (SQLException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, null);}return count;}/*** * @param entity 要被删除的对象,传入主键即可* @return 返回受影响行数*/public int delete(Object entity) {int count = -1;Class<?> c = entity.getClass();Field primaryKey = c.getDeclaredFields()[0];primaryKey.setAccessible(true);String sql = "delete from " + c.getSimpleName() + " where " + primaryKey.getName() + " = ?";Connection conn = BaseDao.getConn();PreparedStatement ps = null;try {ps = conn.prepareStatement(sql);ps.setObject(1, primaryKey.get(entity));count = ps.executeUpdate();} catch (SQLException | IllegalArgumentException | IllegalAccessException e) {e.printStackTrace();} finally {BaseDao.closeAll(conn, ps, null);}return count;}}
  • 本代码适用Oracle,mysql,sqlserver稍微改变下可用。

利用反射对dao层进行重写相关推荐

  1. 注解和反射实现dao层增删改查

    注解和反射写dao 1. 注解的使用 2. 使用注解体现映射关系 针对上一篇文章,使用xml映射文件和反射实现dao,提出了扩展功能,利用注解来体现实体类和表的映射关系 本文是上一篇文章的扩展 使用反 ...

  2. 利用反射和xml配置文件手写一个小型的框架

    通用的增删改查 1. 利用xml配置实体类和数据库表名的映射关系 2. 根据xml设计,用正确的数据结构映射类封装好xml信息 3. 得到数据库连接前,读取xml信息,用map封装成映射数据 4. 写 ...

  3. 轻量级DAO层实践初体验

    最近快被 Hibernate 给坑哭了,有了自己动手实现 ORM 映射 DAO 的冲动. 工作之余折腾了快一星期,总算是有点小成就. 现打算将过程记录下来,方便自己后续回顾填补遗漏. 回到顶部 1. ...

  4. 边做边学小型封装--利用主流框架进行Dao层通用化,Spring3.0+Hibernate3.3.2通用Dao层整合(四)...

    了解Dao层的创建和HibernateSupportDao后,忘了要把Spring3.0的Jar包加进去lib文件夹里面,由于Spring3.0开始没有把所有需要有关联的Jar包跟功能整合包放在一起, ...

  5. Spring Boot微信点餐——实战开发DAO层

    0. 修改grade镜像,使用阿里云地址,以便于快速加载依赖 参照大佬博客 =====> 阿里云maven镜像 # 项目目录下的build.gradlerepositories {maven { ...

  6. dao层如何调用对象_以k8s集群管理为例,大牛教你如何设计优秀项目架构

    架构设计一直是技术人的关注热点,如何设计一个更优的架构对于实际的业务来说至关重要.本文腾讯云专家将从自身从事的一个k8s集群管理项目为例,重点剖析在项目开发过程中的三次架构演进历程,即针对项目最早版本 ...

  7. 【用户画像】标签任务开发流程(源码之实体类、工具类、配置文件、DAO层)

    文章目录 一 代码实现 0 开发主线 1 实体类 (1)TagInfo (2)TaskInfo (3)TaskTagRule 2 工具类 (1)连接sql的工具类 测试 (2)专门读取properti ...

  8. java dao层_JavaWeb Dao层架构设计

    Java Web Dao层设计 UML设计图 Dao层设计 实体类 package cn.zzuli.oa.domain; public class Role { } package cn.zzuli ...

  9. 关于service层、dao层,以及O/R Mapping之间的思考

    部门最近正式进入oo的开发,采用了类似于petshop4的层次结构,简单来说,service层调用dao(当然是用配置文件+反射的方式),dao通过ibatis.net完成从数据库中的table到do ...

最新文章

  1. JavaEE互联网轻量级框架整合开发(书籍)阅读笔记(1):Mybatis和Hibernate概念理解...
  2. centos nginx不是命令_Nginx 在CentOS 6/7 上的安装与使用
  3. 初识图机器学习(part3)--图数据挖掘
  4. 一张图告诉你为什么是服务网关
  5. 在FF与IE中使用数据岛
  6. 初识openwrt(下)
  7. 实用UI设计需要学什么软件?
  8. 新年的第一天学习状态感慨
  9. GD32F103实战笔记
  10. 推荐一个好组件Javascript文本比较工具
  11. 上位机软件系统开发工具简介
  12. 阻容感基础01:从宇宙起源到阻容感(1)
  13. urdf 学习与制作
  14. 今晚直播 |现实环境中的强化学习如何解决?你不可错过的RL终极奥义
  15. 网络重置后WLAN网络找不到怎么办?
  16. 深访杨超越杯编程大赛发起人 还原硬核粉丝追星全过程
  17. 8个实用、强大、超厉害的软件推荐,快收藏吧!
  18. 截取计算机全屏画面的方法有,电脑怎么截图全屏 详细方法介绍
  19. Docker 教学版本-v1.0.0
  20. 表设计工具EZDML下载

热门文章

  1. 前端学习(1486):postman测试接口
  2. 前端学习(487):css选择器下
  3. 玩转oracle 11g(20):ora-00604和ora-00018
  4. 宿舍管理系统项目管理师_2020下半年信息系统项目管理师真题——案例分析(带解析)...
  5. display:table-cell自适应布局下连续单词字符换行
  6. Vue基础之Vue列表渲染
  7. 数据科学家令人惊叹的排序技巧
  8. php实时股票,php基于curl实现的股票信息查询类实例
  9. Burp破解安装(1.7和2.0)
  10. ListString^^ 引用空间