BaseDao工具类

首先了解下BaseDao的字面意思

Base:基本的

Dao:Data  Access Object 数据访问对象,也称为数据访问层

使用BaseDao的好处:我们在初学java的JDBC的部分我们应该是经常会写对数据的增删改查,比如说对学生的增删改查,或者是老师的增删改查等等。。。然而这时你会发现你所写的很多代码都是重复的,这时你就会考虑到代码的优化问题,以及常提到的高内聚低耦合这个概念。

接下来就是常用的代码部分:

我们在写增删改的时候会发现增删改这三种的代码几乎是相同的,不同的就是sql语句,所以就先把简单的展示出来:

    /**
	 * 实现不同表的增删改
	 */
	protected void update(String sql, Object... args) throws SQLException {
		// 获取连接     相同
		Connection conn = ProxyUtil.conn;
		// 准备sql	不同
		// PreparedStatement	相同
		PreparedStatement ps = conn.prepareStatement(sql);
		// 填充占位符	相似
		for (int i = 0; i < args.length; i++) {
			ps.setObject((i + 1), args[i]);
		}
		// 执行sql	相同
		ps.executeUpdate();
		ps.close();
	}

相对而言,我们要实现的查询要复杂一点,要考虑的有点多,下面展示查询的代码:

    /**
	 * 实现不同表的查询
	 * 
	 * @throws SQLException
	 */
	protected List<T> getAll(String sql, Object... args) throws SQLException {
		List<T> ts = new ArrayList<>();
		// 获取连接 相同
		Connection conn = ProxyUtil.conn;
		// 准备sql 不同
		// PreparedStatement
		PreparedStatement ps = conn.prepareStatement(sql);
		// 填充占位符 相似
		for (int i = 0; i < args.length; i++) {
			ps.setObject((i + 1), args[i]);
		}
		// 执行sql 相同
		ResultSet rs = ps.executeQuery();
		// 获取元数据
		ResultSetMetaData rsmd = rs.getMetaData();
		// 通过元数据获取列的数量
		int columnCount = rsmd.getColumnCount();
		// 处理结果集 相似
		while (rs.next()) {
			T t = null;
			// 获取带泛型的父类
			Type genericSuperclass = this.getClass().getGenericSuperclass();
			// 强转为带泛型的父类类型
			ParameterizedType pt = (ParameterizedType) genericSuperclass;
			// 取出泛型
			Type[] actualTypeArguments = pt.getActualTypeArguments();
			// 取出第0个泛型
			Type type = actualTypeArguments[0];
			// 泛型的类型
			Class c = (Class) type;
			// 创建对象
			try {
				t = (T) c.newInstance();
			} catch (InstantiationException e) {
				e.printStackTrace();
			} catch (IllegalAccessException e) {
				e.printStackTrace();
			}
			// 取出所有的字段
			Field[] fields = c.getDeclaredFields();
			// 遍历列
			for (int i = 1; i <= columnCount; i++) {
				// 取出列的值
				Object value = rs.getObject(i);
				// 取出当前列的名字,表的字段名
				String columnLabel = rsmd.getColumnLabel(i);
				// set属性值
				Field f = null;
				a: for (Field field : fields) {
					// 类中字段名
					String fieldName = field.getName();
					// 找到列名和类中的字段名相同的字段
					if (columnLabel.equalsIgnoreCase(fieldName)) {
						f = field;
						break a;
					}
				}
				if (f != null) {
					// 改为可以修改
					f.setAccessible(true);
					try {
						if (value instanceof Date) {
							f.set(t, ((Date) value).toLocalDate());
						} else {
							f.set(t, value);
						}
					} catch (IllegalArgumentException e) {
						// 获取field的类型
						Class<?> fieldClass = f.getType();
						try {
							// 创建对象,可能是teacher
							Object fieldValue = fieldClass.newInstance();
							// 取出fieldClass类中的id字段
							Field fieldClassIdField = fieldClass.getDeclaredField("id");
							// 把value赋给上一步获取的id字段
							fieldClassIdField.setAccessible(true);
							fieldClassIdField.set(fieldValue, value);
							// 把fieldValue赋给f字段
							f.set(t, fieldValue);
						} catch (InstantiationException | IllegalAccessException | NoSuchFieldException
								| SecurityException | IllegalArgumentException e1) {
							e1.printStackTrace();
						}
					} catch (IllegalAccessException e) {
						e.printStackTrace();
					}
				}
			}
			ts.add(t);
		}
		// 关闭连接
		ps.close();
		rs.close();
		return ts;
	}

查询的代码量看着是有点吓人,但是自己能够懂每一步是要实现什么就行了。其实关于关闭连接这个也是可以在写一个通用的方法,就又可以减少代码量了。每一条代码都有一些关键的注释,如果说不理解的也可以直接搜

这里我们实现的查询是一个集合,一般来说我们要查询的数据都是比较多的,查一条的比较少。在这里呢,查询一条指定的数据的代码就不展示了,说说思路吧,查询一条也就是返回的不是集合,应该是一个对象,然后其他的代码基本上是相似的,就把集合改改就是了。

有了BaseDao之后呢,就可以结合数据库中的事务去实现一些功能,有关事务的理解下次再给小伙伴们讲解

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值