当我们使用SpringDataJpa写sql查询数组时,如果数据库查询出来的数据为空,结果会是怎样的呢
接口类
public interface Dao extends PagingAndSortingRepository {
@Query("select eneity from table")
List<String> getList();
}
测试类:
public class Demo01 {
@Resource
private static Dao dao;
public static void main(String[] args) {
List<String> list = dao.getList();
System.out.println(list == null);
}
}
这时候运行,打印出来的结果是false,违背了我们一直以来的思想,为什么数据库数据为空的时候,我们查询出来的不是Null,而是一个空集合呢。
我在网上翻阅了很久,也没有找到一篇合理的解释,最后只能换一个角度去思考,jpa的底层实现是对Hibrenate进行了封装,所以我开始找Hibernate的源码,因为Hibernate源码太过复杂,多层调用,我给大家分享一下查找的入口和最终结果:
入口类:
package org.hibernate;
public interface Query {
List list() throws HibernateException;
}
最终实现类:
package org.hibernate.loader;
public abstract class Loader {
private List doQuery(SessionImplementor session, QueryParameters queryParameters, boolean returnProxies) throws SQLException, HibernateException {
RowSelection selection = queryParameters.getRowSelection();
int maxRows = hasMaxRows(selection) ? selection.getMaxRows() : 2147483647;
int entitySpan = this.getEntityPersisters().length;
ArrayList hydratedObjects = entitySpan == 0 ? null : new ArrayList(entitySpan * 10);
PreparedStatement st = this.prepareQueryStatement(queryParameters, false, session);
ResultSet rs = this.getResultSet(st, queryParameters.hasAutoDiscoverScalarTypes(), queryParameters.isCallable(), selection, session);
EntityKey optionalObjectKey = getOptionalObjectKey(queryParameters, session);
LockMode[] lockModesArray = this.getLockModes(queryParameters.getLockOptions());
boolean createSubselects = this.isSubselectLoadingEnabled();
List subselectResultKeys = createSubselects ? new ArrayList() : null;
ArrayList results = new ArrayList();
try {
this.handleEmptyCollections(queryParameters.getCollectionKeys(), rs, session);
EntityKey[] keys = new EntityKey[entitySpan];
if (log.isTraceEnabled()) {
log.trace("processing result set");
}
int count;
for(count = 0; count < maxRows && rs.next(); ++count) {
if (log.isTraceEnabled()) {
log.debug("result set row: " + count);
}
Object result = this.getRowFromResultSet(rs, session, queryParameters, lockModesArray, optionalObjectKey, hydratedObjects, keys, returnProxies);
results.add(result);
if (createSubselects) {
subselectResultKeys.add(keys);
keys = new EntityKey[entitySpan];
}
}
if (log.isTraceEnabled()) {
log.trace("done processing result set (" + count + " rows)");
}
} finally {
session.getBatcher().closeQueryStatement(st, rs);
}
this.initializeEntitiesAndCollections(hydratedObjects, rs, session, queryParameters.isReadOnly(session));
if (createSubselects) {
this.createSubselects(subselectResultKeys, queryParameters, session);
}
return results;
}
}
在这里,我们能清楚的看到,查询的底层是先new了一个ArrayList,然后去查询往里面赋值,如果查询出来没有数据的话,那么会直接将这个ArrayList返回,就会导致返回结果是一个空集合,所以这里我们在判断有没有查询出数据的时候,千万不要单纯用是否为Null去判断,推荐方法为 :
list.isEmpty() 和 CollectionUtils.isEmpty(list)