高级BaseDao封装

发表时间:2017-05-11 16:55:31 浏览量( 16 ) 留言数( 0 )

学习目标:

1、了解Java的历史

2、为什么要学习Java语言

3、端正学习态度


学习过程:

事实上我们还可以进一步的封装,因为对数据库的每一个表的操作几乎都包含增删改,还有根据id进行查询,以及查询全部等等基本的方法,所有我们也可以可把所有的这些方法都封装到FatherDao中,你可以观察一下所有sql语句,除了表名称,属性名称不同之外都是一样的,所有我们可以动态的构造这些sql语句。当然在封装之前我们首先也是需要定下一个命名规则:

Table名称和对应的pojo类前面加"tb_"。如:表tb_user,对应pojo类就是User。

所有的表的id都是自增的,且命名是:pojo类名_id,如上表它的id就应该命名为:user_id

一、修改FatherDao

代码如下:

public class FatherDao<T> extends BaseDao {

	private Class<T> clazz;

	public FatherDao(Class<T> clazz) {
		this.clazz = clazz;
	}

	// 获得表的名称
	private String getTableName() {
		return "tb_" + clazz.getSimpleName();
	}

	private String getid() {
		return clazz.getSimpleName() + "_id";
	}

	// 获得所有的数据库的字段名称 形式如:字段1,字段2,... id除外
	private String getFiedName() {
		StringBuffer sb = new StringBuffer();
		Field[] fields = clazz.getDeclaredFields();
		for (Field field : fields) {
			if (!field.getName().endsWith("Id")) {
				sb.append(fieldNameToClumeName(field.getName()) + ",");
			}
		}
		return sb.substring(0, sb.length() - 1).toString();
	}

	// 获得所有的数据库的字段名称 形式如:字段1,字段2,... id除外
	private String getFiedNameWhat() {
		StringBuffer sb = new StringBuffer();
		Field[] fields = clazz.getDeclaredFields();
		for (int i = 0; i < fields.length - 1; i++) {
			sb.append("?,");

		}
		return sb.substring(0, sb.length() - 1).toString();
	}

	// 所有的get方法的返回值 id不需要
	public Object[] getAllGetResutn(T t) {
		try {
			// 1、通过反射技术获得所有的属性。
			Field[] fields = clazz.getDeclaredFields();
			Object[] objects = new Object[fields.length - 1];//
			int i = 0;
			for (Field field : fields) {
				if (!field.getName().endsWith("Id")) {
					// 获得对应的get方法。
					String getMethod = "get"
							+ field.getName().substring(0, 1).toUpperCase()
							+ field.getName().substring(1);
					// System.out.println(setMethod);
					Method method = clazz.getDeclaredMethod(getMethod);
					// 调用方法
					objects[i++] = method.invoke(t);

				}
			}
			return objects;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;

	}

	public int add(T t) {
		String sql = "insert into " + getTableName() + "(" + getFiedName()
				+ ") values(" + getFiedNameWhat() + ")";

		System.out.println("sql=" + sql);

		// 所有的get方法的返回值,除了id
		int result = execOnceUpdate(sql, getAllGetResutn(t));

		return 0;
	}

	public int del(int id) {
		String sql = "delete from " + getTableName() + " where " + getid()
				+ "=?";

		int result = execOnceUpdate(sql, new Object[] { id });

		return result;
	}

	public int update(T t) {

		// String sql="update 标明+set 字段=?"

		return 0;
	}

	public T findById(int id) {

		T t = null;

		String sql = "select * from " + getTableName() + " where " + getid()
				+ "=?";
		resultSet = execOnceQuery(sql, new Object[] { id });
		try {
			if (resultSet.next()) {
				t = rs2Object(resultSet);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			closeAll();
		}

		return t;
	}

	public List<T> findAll() {

		List<T> ts = new ArrayList<T>();
		String sql="select * from "+getTableName();
		resultSet=execOnceQuery(sql, null);
		try {
			while(resultSet.next()){
				T t=rs2Object(resultSet);
				ts.add(t);
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			closeAll();
		}

		return ts;
	}

	// Result Object
	public T rs2Object(ResultSet resultSet) {
		T t = null;
		try {
			t = clazz.newInstance();
			// 1、通过反射技术获得所有的属性。
			Field[] fields = clazz.getDeclaredFields();
			for (Field field : fields) {
				// 获得对应的set方法。
				String setMethod = "set"
						+ field.getName().substring(0, 1).toUpperCase()
						+ field.getName().substring(1);
				// System.out.println(setMethod);
				Method method = clazz.getDeclaredMethod(setMethod,
						field.getType());
				// 调用方法
				method.invoke(t, resultSet.getObject(fieldNameToClumeName(field
						.getName())));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}

		return t;
	}

	// userId >> user_id
	// userName >> user_name
	private String fieldNameToClumeName(String fieldName) {

		if (fieldName == null) {
			return null;

		}

		StringBuilder sb = new StringBuilder();

		boolean upperCase = false;

		for (int i = 0; i < fieldName.length(); i++) {
			char c = fieldName.charAt(i);
			boolean nextUpperCase = true;
			if (i < (fieldName.length() - 1)) {
				nextUpperCase = Character.isUpperCase(fieldName.charAt(i + 1));
			}
			if ((i >= 0) && Character.isUpperCase(c)) {
				if (!upperCase || !nextUpperCase) {
					if (i > 0)
						sb.append("_");
				}
				upperCase = true;
			} else {
				upperCase = false;
			}
			sb.append(Character.toLowerCase(c));

		}

		return sb.toString();

	}

}

二、测试这个FatherDao

你可以把原来的UserDao基本的增删改已经根据id查询和查询全部这些方法实现全部删除。代码如下:

 public class UserDao extends FatherDao<User>{

	public UserDao() {
		super(User.class);
	}

}

写一个Run测试类,虽然UserDao什么具体的方法都没有写,但是已经继承了FatherDao的这些方法了。

public static void main(String[] args) {
		
		UserDao userDao=new UserDao();

		User user=new User();
		user.setUserName("名称");
		user.setUserEmail("liubao@tom.com");
		user.setUserPass("12346");
		
		userDao.add(user);
		
		userDao.del(1);
		
		userDao.findById(2);
		
		userDao.findAll();
		
	}