利用反射对dao层进行重写

本文探讨如何利用反射来创建通用DAO层,通过反射获取实体类信息,拼接SQL语句,实现增删改查功能。适用于Oracle、MySQL等数据库。
摘要由CSDN通过智能技术生成

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 = 
// 对overload测试的文件:OverloadTest.java public class OverloadTest { // 下面几个方法用来验证可以通过定义不同的参数类型和参数的数目进行方法重载。 public void fun(){ System.out.println("method fun in OverloadTest, no parameter"); } public void fun(float f) { System.out.println("method fun in OverloadTest, parameter type: float"); } public void fun(int i){ System.out.println("method fun in OverloadTest, parameter type: int"); } public void fun(int i1, int i2) { System.out.println("method fun in OverloadTest, parameter type: int, int"); } // 下面的两个方法用来验证可以通过定义不同的参数顺序进行方法重载。 // 需要注意:这里的参数肯定不是相同的类型,否则的顺序的先后就毫无意义。 public void fun1(int i, float f) { System.out.println("method fun1 in OverloadTest, sequence of parameters is: int, float"); } public void fun1(float f, int i) { System.out.println("method fun1 in OverloadTest, sequence of parameters is: float, int"); } // 下面的两个方法用来验证方法抛出的异常对于重载的影响. // 无论是异常的类型还是异常的个数都不会对重载造成任何的影响。 public void fun2() throws TestException { System.out.println("fun2 in OverloadTest, exception: TestException"); } public void fun2(int i) throws TestException, TestException1 { System.out.println("fun2 in OverloadTest, exception: TestException, TestException1"); } public void fun2(float f) throws Exception { System.out.println("fun2 in OverloadTest, exception: Exception"); } // 不能通过抛出的异常类型来重载fun方法。 //public void fun(int i) throws Exception { // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception"); //} // ? 不能通过返回值重载fun方法。 //public boolean fun(int i) throws Exception { // System.out.println("method fun in OverloadTest, parameter type: int, exception: Exception, return: boolean"); // return true; //} private void fun3() { } // 不能通过不同的访问权限进行重载 public void fun3() { } public static void main(String[] args) { // 这里只是定义了OverloadTest的实例,所以test不会调用 // OverloadTest1中的方法。 OverloadTest test = new OverloadTest1(); // 这里定义了OverloadTest1的实例,因为OverloadTest1是OverloadTest // 的子类,所以test1会调用OverloadTest中的方法。 OverloadTest1 test1 = new OverloadTest1(); try { int i = 1, j = 2, m = 3; // 这里不会调用OverloadTest1的fun方法 // test.fun(i, m, j); test1.fun(i, j, m); test1.fun(); // 这个调用不会执行,因为fun3()在OverloadTest中访问权限是priavte //test1.fun3(); test1.fun3(i); } catch(Exception e) { } } } class OverloadTest1 extends OverloadTest{ // 在子类中重载fun public void fun(int i, int m, int n) { System.out.println("Overload fun1 in OverloadTest1, parameter type: int, int, int"); } // 这个不是对父类中方法的重载,只是一个新的方法。 public void fun3(int i) { System.out.println("fun2 in OverloadTest1"); } } // 对override测试的文件:OverrideTest.java public class OverrideTest { public void fun() throws TestException { System.out.println("method fun in OverrideTest"); } private void fun1() { System.out.println("method fun1 in OverrideTest"); } public static void main(String[] args) { OverrideTest test = new OverrideTest1(); try { test.fun(); test.fun1(); } catch(Exception e) { } } } class OverrideTest1 extends OverrideTest{ // 以下正常Override public void fun() throws TestException2 { System.out.println("fun in OverrideTest1"); } // 不能Override父类中的方法,因为它定义了不同的异常类型和 // 返回值。 //public int fun() throws TestException1 { // System.out.println("method fun in Test"); // return 1; //} // 不能Override父类中的方法,因为它抛出了比父类中非法范围 // 更大的异常。 //public void fun() throws Exception { // System.out.println("fun in OverrideTest1"); //} // 这个方法并没有Override父类中的fun1方法,因为这个方法在 // 父类是private类型,所以这里只是相当于定义了一个新方法。 public void fun1() { System.out.println("method fun1 in Test"); } } class TestException extends Exception{ public TestException(String msg) { super(msg); } } class TestException1 extends TestException { public TestException1(String msg) { super(msg); } } class TestException2 extends TestException { public TestException2(String msg) { super(msg); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值