JDBC结果集转实体对象 支持实体属性(驼峰命名法)到数据库列名转换

工作中有时候不得不使用JDBC进行查询,此时最麻烦的就是手工从结果集中获取数据的过程,这里博主写了一个简单的工具类去做JDBC结果集和对应实体之间的转换,代码如下:

	/**
	 * 转换数据 JDBC结果集转实体
	 *
	 * @param resultSet 结果集
	 * @param clazz	实体字节码文件对象
	 * @param <T>	实体类型
	 * @throws Exception  sql异常 NoClass异常等等
	 */
	public static <T> List<T> exchangeData(ResultSet resultSet, Class<T> clazz) throws Exception {
		//获取全部类方法  包括父类的
		Method[] declaredMethods = clazz.getMethods();
		List<T> list = new ArrayList<>();
		ResultSetMetaData metaData = resultSet.getMetaData();
		while (resultSet.next()) {
			//反射实例化对象
			T obj = clazz.newInstance();
			//遍历类调用方法
			for (Method method : declaredMethods) {
				//获取方法名
				String name = method.getName();
				if (!name.startsWith("set")){
					//只要setter
					continue;
				}
				//获取数据库名 驼峰命名法转数据库字段命名法
				String dbName = getDbName(name);
				//遍历数据库所有列
				for (int i = 1; i <= metaData.getColumnCount(); i++) {
					//抓取指定列赋值
					if (metaData.getColumnName(i).equals(dbName)) {
						if (resultSet.getObject(i) != null) {
							//赋值
							setValue(obj,method,resultSet,i);
						}
						break;
					}
				}
			}
			list.add(obj);
		}
		return list;
	}

	/**
	 *  赋值操作,
	 *  	主要是处理数据类型
	 *  		此处只简单处理下基本数据类型和Date类型
	 * @param obj	泛型对象
	 * @param method	方法
	 * @param resultSet	结果集
	 * @param i	脚标
	 * @param <T>	泛型
	 */
	private static <T> void setValue(T obj, Method method, ResultSet resultSet, int i) throws SQLException, InvocationTargetException, IllegalAccessException {
		//Setter方法只有一个参数,获取参数类型名称
		String name = method.getParameterTypes()[0].getName().toLowerCase();
		if (name.contains("string")){
			method.invoke(obj, resultSet.getString(i));
		}
		else if (name.contains("short")){
			method.invoke(obj,resultSet.getShort(i));
		}
		else if (name.contains("int") || name.contains("integer")){
			method.invoke(obj,resultSet.getInt(i));
		}
		else if (name.contains("long")){
			method.invoke(obj,resultSet.getLong(i));
		}
		else if (name.contains("float")){
			method.invoke(obj,resultSet.getFloat(i));
		}
		else if (name.contains("double")){
			method.invoke(obj,resultSet.getDouble(i));
		}
		else if (name.contains("boolean")){
			method.invoke(obj,resultSet.getBoolean(i));
		}
		else if (name.contains("date")){
			method.invoke(obj,resultSet.getDate(i));
		}

		else {
			method.invoke(obj, resultSet.getObject(i));
		}

	}

	/**
	 * 实体setter名称转对应数据库列的列名
	 * 		需要遵守命名规范,java(驼峰命名法),数据库(全小写,单词间用'_'隔开)
	 * @param name setter名称
	 * @return	数据库列名
	 */
	private static String getDbName(String name) {
		//根据setter命名规则获取对应的属性名
		name = name.substring(3,4).toLowerCase()+name.substring(4);
		//获取数据库对应列名
		StringBuffer buffer = new StringBuffer();
		char[] nameChars = name.toCharArray();
		for (char nameChar : nameChars) {
			if (nameChar >= 'A' && nameChar <= 'Z') {
				//将大写字母转换为下划线和对应的小写字母组合
				buffer.append("_").append(String.valueOf(nameChar).toLowerCase());
			} else {
				buffer.append(String.valueOf(nameChar));
			}
		}
		return buffer.toString();
	}

测试代码:

	public static void main(String[] args) throws Exception {
		Class.forName("com.mysql.jdbc.Driver");
		Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/my_blog?characterEncoding=UTF" +
				"-8", "root", "123123");
		String sql = "select * from resource ";
		assert connection != null;
		PreparedStatement preparedStatement = connection.prepareStatement(sql);
		ResultSet resultSet = preparedStatement.executeQuery();
		List<Resource> resources = exchangeData(resultSet, Resource.class);
		resources.forEach(System.out::println);
	}

测试结果:

Resource{id=96, className='RoleResource', classDescription='角色管理接口', action='UPDATE', path='/api/role', description='更新'}
Resource{id=98, className='RoleResource', classDescription='角色管理接口', action='SELECT', path='/api/role', description='分页查询'}
Resource{id=99, className='RoleResource', classDescription='角色管理接口', action='DELETE', path='/api/role/{id}', description='删除单个'}
Resource{id=100, className='RoleResource', classDescription='角色管理接口', action='SELECT', path='/api/role/{id}', description='查询单个'}
Resource{id=101, className='RoleResource', classDescription='角色管理接口', action='DELETE', path='/api/role', description='批量删除'}
Resource{id=102, className='RoleAccessResource', classDescription='角色权限接口', action='UPDATE', path='/api/roleAccess', description='更新'}
Resource{id=103, className='RoleAccessResource', classDescription='角色权限接口', action='ADD', path='/api/roleAccess', description='新增'}
Resource{id=104, className='RoleAccessResource', classDescription='角色权限接口', action='SELECT', path='/api/roleAccess', description='分页查询'}
Resource{id=105, className='RoleAccessResource', classDescription='角色权限接口', action='DELETE', path='/api/roleAccess/{id}', description='删除单个'}
Resource{id=106, className='RoleAccessResource', classDescription='角色权限接口', action='SELECT', path='/api/roleAccess/{id}', description='查询单个'}
Resource{id=107, className='RoleAccessResource', classDescription='角色权限接口', action='DELETE', path='/api/roleAccess', description='批量删除'}
Resource{id=108, className='UserResource', classDescription='用户管理接口', action='UPDATE', path='/api/user', description='更新'}
Resource{id=109, className='UserResource', classDescription='用户管理接口', action='ADD', path='/api/user', description='新增'}
Resource{id=110, className='UserResource', classDescription='用户管理接口', action='SELECT', path='/api/user', description='分页查询'}
Resource{id=111, className='UserResource', classDescription='用户管理接口', action='DELETE', path='/api/user/{id}', description='删除单个'}
Resource{id=112, className='UserResource', classDescription='用户管理接口', action='SELECT', path='/api/user/{id}', description='查询单个'}
Resource{id=113, className='UserResource', classDescription='用户管理接口', action='DELETE', path='/api/user', description='批量删除'}
Resource{id=114, className='UserResource', classDescription='用户管理接口', action='OTHER', path='/api/user/Logout', description='登出'}
Resource{id=115, className='UserResource', classDescription='用户管理接口', action='OTHER', path='/api/user/addRole', description='给用户添加角色'}
Resource{id=116, className='RoleResource', classDescription='角色管理接口', action='ADD', path='/api/role', description='新增'}

使用比较简单,采用的盆友记得点赞!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值