优雅的判空操作_对需要频繁判空的对象entity的代码优化

优雅判空与Null对象模式
本文探讨了在频繁判空场景下对实体对象进行代码优化的方法,通过使用Null对象模式,可以简化调用流程,避免冗余的空值检查,提高代码的可读性和安全性。

优雅的判空操作 --> 对需要频繁判空的对象entity的代码优化

代码结构
结构

entity是本文用到的对象,里面还用到了entityReturn作为field和getEntityReturn的返回值,如下图红框
在这里插入图片描述

在这里插入图片描述
Entity对应的接口:entity是Ientity的实现类,Nullentity也是这个接口实现类
在这里插入图片描述
在这里插入图片描述

相同的,entityReturn也是相似的套路
在这里插入图片描述
在这里插入图片描述

看红色箭头->
在这里插入图片描述

简洁 放心 的 调用 过程 是下面这样的

int code = entityFactory.getEntity().returnEntityMethod().getCode();

对比下面这种

	entity entity = entityFactory.getEntity();
	if(entity !=null){
		//dosomething
		entityReturn entityReturn = entity.returnEntityMethod()
		if(entityReturn !=null){
			int code = entityReturn.getcode();
		}else{
			//do nothing
		}
	}else{
		//do nothing
	}

wiki对这种优化的介绍->https://en.wikipedia.org/wiki/Null_object_pattern#Java

final Object res = SqlExecutor.query(source.getConnection(), querySql, new RsHandler<Object>() { @Override public Object handle(ResultSet resultSet) throws SQLException { List<RowInfo> rowInfoList = new ArrayList<>(); resultSet.setFetchSize(10000); resultSet.setFetchDirection(ResultSet.FETCH_FORWARD); while (resultSet.next()) { Boolean flag = false; //如果某一行的某个字段检测有异常,这一行的数据都要记下来,并且检测结果集里存下行ID String rowId = SnowFlakeUtil.newIdString(); for (FieldInfo info : param.fieldList) { DbValue dbValue = null; dbValue = DbValueFactory.fromResultSet(resultSet, info.fieldName, info.fieldType, param.dataSourceType); //单个字段检测,并保存结果集 final List<FieldValueCheckRes> checkResList = checker.check(param.tableId, info.id, dbValue, rowId,resultSet, param.tableInfo.getFields()); if (flag || checkResList.stream().count() > 0) { flag = true; } } //如果flag=true,存下这一行(最多存6万行) if (flag && rowInfoList.size() < 60000) { Map<String, Object> fieldInfo = new HashMap<>(); //遍历每行数据,获取结果并保存 ResultSetMetaData rsmd = resultSet.getMetaData(); int columnCount = rsmd.getColumnCount(); checker.getRecord().forEach(t -> { if (t.getFieldCount().get() == 0){ t.getFieldCount().getAndSet(columnCount); } }); // 遍历每一列 for (int i = 1; i <= columnCount; i++) { // 获取列名 String columnName = rsmd.getColumnName(i); // 获取列值 Object value = resultSet.getString(i); fieldInfo.put(columnName, value); } rowInfoList.add(new RowInfo(rowId, param.tableId, fieldInfo)); } } return rowInfoList; } }); hutools工具类优化
06-07
<think>我们在处理SQL查询结果时,通常需要将查询结果(例如数据库返回的ResultSet或查询得到的List<Map>)转换为更易用的数据结构,或者进行字段的映射、转换等操作。Hutool提供了丰富的工具类来简化这些操作。主要涉及的工具类包括:-`cn.hutool.db.DbUtil`:用于数据库操作的工具类,但注意Hutool的Db类封装了更便捷的数据库操作。-`cn.hutool.db.handler.RsHandler`:用于处理ResultSet,可以将ResultSet转换为各种形式。-`cn.hutool.core.convert.Convert`:用于类型转换。-`cn.hutool.core.collection.CollUtil`:集合工具类,可对集合进行各种操作。-`cn.hutool.json.JSONUtil`:JSON工具类,可以方便地将查询结果转换为JSON。优化方向:1.减少样板代码:如循环处理结果集,转换字段类型等。2.提高可读性:使用链式调用或函数式处理。3.性能优化:如使用缓存或批处理。以下是一些常见的优化场景和示例:###1.使用Db类执行查询并直接转换为Bean列表Hutool的`Db`类可以非常方便地执行SQL并转换结果。假设我们有一个User实体类,我们可以将查询结果直接转换为User对象的列表。```java//假设已经配置了数据源List<User>userList=Db.use().query("SELECT*FROMuserWHEREage>?",newBeanListHandler<>(User.class),18);```这里使用了`BeanListHandler`,它会自动将结果集的每一行转换为一个Bean对象(通过反射)。这大大简化了代码。###2.将查询结果转换为Map列表有时候我们并不需要定义实体类,只需要得到每一行的Map,那么可以使用`MapListHandler`。```javaList<Map<String,Object>>mapList=Db.use().query("SELECT*FROMuser",newMapListHandler());```###3.使用CollUtil进行集合操作当我们得到Map列表后,可以使用CollUtil工具类进行各种操作,例如:-分组:`CollUtil.groupByField(list,"fieldName")`-提取部分字段:`CollUtil.extract(list,"fieldName")`-过滤:`CollUtil.filter(list,filter)`例如,提取所有用户的姓名:```javaList<String>names=CollUtil.map(mapList,newRowFunc<String>(){@OverridepublicStringapply(Map<String,Object>map){return(String)map.get("name");}},String.class);```或者使用Lambda表达式:```javaList<String>names=CollUtil.map(mapList,map->(String)map.get("name"),String.class);```###4.使用Convert进行字段类型转换在从Map或Bean中获取值时,可能需要类型转换,Convert类可以简化转换代码并减少指针异常。例如:```java//获取一个字段并转换为Long类型Longvalue=Convert.toLong(map.get("id"));```###5.处理复杂结果(如将结果转换为树形结构)Hutool的`CollUtil`还提供了构建树结构的方法:```java//假设我们有一个包含id,parentId,name的列表List<TreeNode>treeNodes=CollUtil.buildTree(list);```###6.使用JSONUtil进行转换如果我们需要将查询结果返回给前端,可以直接转换为JSON:```javaStringjson=JSONUtil.toJsonStr(mapList);```###7.使用BeanUtil.fillBeanWithMap将Map转换为Bean如果我们得到的是Map,却想转换为Bean:```javaUseruser=BeanUtil.fillBeanWithMap(map,newUser(),false);```###8.使用Lambda进行高级集合操作结合Hutool的Lambda功能和Java8的Lambda表达式,可以更优雅地进行集合操作:```javaList<String>names=mapList.stream().map(map->Convert.toStr(map.get("name"))).collect(Collectors.toList());```###示例整合下面是一个完整的示例,展示如何从查询到处理的优化过程:```java//假设已经配置了数据源List<Map<String,Object>>mapList=Db.use().query("SELECT*FROMuserWHEREage>?",newMapListHandler(),18);//使用CollUtil的map方法提取name并去重List<String>names=CollUtil.distinct(CollUtil.map(mapList,map->Convert.toStr(map.get("name")),String.class));//或者直接使用Java8StreamAPIList<String>names=mapList.stream().map(map->Convert.toStr(map.get("name"))).distinct().collect(Collectors.toList());```###注意事项1.使用Hutool的数据库操作需要先配置数据源。可以使用`Db.use()`使用默认数据源,或者通过`Db.use(dataSource)`指定数据源。2.当处理大量数据时,注意内存占用和性能。可以考虑分页查询或使用结果集处理器逐步处理。3.转换过程中注意字段的命名规范,数据库字段名和JavaBean属性名的映射关系(下划线转驼峰默认支持)。通过使用Hutool,我们可以大大减少数据库结果处理的样板代码,提高开发效率。§§相关问题§§1.Hutool中有哪些常用工具类可以简化数据库操作?2.如何将Hutool的查询结果转换为树形结构?3.使用Hutool处理数据库结果时有哪些性能优化建议?</think> ### 如何使用 Hutool 优化 SQL 查询结果处理 在 Java 中处理 SQL 查询结果时,Hutool 提供了以下核心工具类进行优化(基于引用 [2][3]): #### ✅ 核心优化工具类 1. **`CollUtil` 集合工具类** - 转换结果集为 Bean 集合:`List<User> users = CollUtil.toList(rsHandler)` - 快速分组:`Map<String, List<User>> groupMap = CollUtil.groupByField(list, "deptId")` - 字段提取:`List<String> names = CollUtil.getFieldValues(list, "name")` 2. **`BeanUtil` 对象操作工具类** - Map → Bean 转换: ```java Map<String, Object> row = ... // 数据库行数据 User user = BeanUtil.toBean(row, User.class); ``` - 批量转换:`List<User> users = BeanUtil.copyToList(resultList, User.class)` 3. **`MapUtil` Map 工具类** - 字段过滤:`MapUtil.filter(row, new String[]{"id", "name"})` - 值处理:`MapUtil.removeNullValue(row)` #### ✅ 典型优化场景示例 1. **结果集 → 对象列表** ```java List<Map<String, Object>> rawResults = jdbcTemplate.queryForList(sql); List<User> users = rawResults.stream() .map(row -> BeanUtil.toBean(row, User.class)) .collect(Collectors.toList()); ``` 2. **动态字段提取** ```java List<Map<String, Object>> data = ...; List<Map<String, Object>> simplified = CollUtil.map(data, row -> { return MapUtil.of("id", row.get("id"), "name", row.get("user_name")); }, true); ``` 3. **结果集特殊处理** ```java // 使用 JSONUtil 处理复杂字段 data.forEach(row -> { String jsonData = Convert.toStr(row.get("json_col")); row.put("parsed_data", JSONUtil.parseObj(jsonData)); }); // 类型安全转换 Date createTime = Convert.toDate(row.get("create_time")); ``` #### ✅ 性能优化建议 1. **批量处理机制** 对大数据集使用分页: ```java PageResult<Map<String, Object>> paged = DbUtil.queryPage(ds, sql, pageNo, pageSize); ``` 2. **缓存重复操作** 对频繁转换的元数据使用缓存: ```java private static final TypeReference<User> USER_TYPE = new TypeReference<User>() {}; BeanUtil.toBean(row, USER_TYPE); ``` 3. **连接池优化**(结合引用 [3]) 在 `application.yml` 中配置: ```yaml hutool: db: max-active: 20 min-idle: 5 ``` #### ✅ 完整示例 ```java import cn.hutool.core.bean.BeanUtil; import cn.hutool.core.collection.CollUtil; import cn.hutool.db.Db; import cn.hutool.db.Entity; public class SqlResultOptimizer { public static void main(String[] args) { // 执行查询 (Hutool Db方式) List<Entity> rawResults = Db.use().query("SELECT * FROM user WHERE status=1"); // 结果集优化处理 List<User> users = CollUtil.map(rawResults, entity -> BeanUtil.toBean(entity, User.class), true); // 统计部门分组 Map<Integer, List<User>> deptMap = CollUtil.groupByField(users, "deptId"); } static class User { private Integer id; private String name; private Integer deptId; // getters/setters } } ``` ### 📍 最佳实践建议 1. **结果集规模**: - ≤ 1000 行:直接内存处理 - > 1000 行:强制分页+流式处理 2. **转换优先级**: ```mermaid graph TD A[原始结果集] --> B{是否需要复杂处理} B -- 是 --> C[保持Map结构+MapUtil操作] B -- 否 --> D[转换为Bean+BeanUtil] ``` 3. **异常处理**: ```java Convert.convertWithCheck(Integer.class, row.get("age"), 0) // 提供默认值 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值