diff --git a/base/src/main/java/tk/mybatis/mapper/provider/ExampleProvider.java b/base/src/main/java/tk/mybatis/mapper/provider/ExampleProvider.java
index dcd4dbca8..587eb4883 100644
--- a/base/src/main/java/tk/mybatis/mapper/provider/ExampleProvider.java
+++ b/base/src/main/java/tk/mybatis/mapper/provider/ExampleProvider.java
@@ -54,6 +54,9 @@ public String selectCountByExample(MappedStatement ms) {
if (isCheckExampleEntityClass()) {
sql.append(SqlHelper.exampleCheck(entityClass));
}
+ if (getConfig().isSafeSelect()) {
+ sql.append(SqlHelper.exampleHasAtLeastOneCriteriaCheck("_parameter"));
+ }
sql.append(SqlHelper.exampleCountColumn(entityClass));
sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.exampleWhereClause());
@@ -105,6 +108,9 @@ public String selectByExample(MappedStatement ms) {
if (isCheckExampleEntityClass()) {
sql.append(SqlHelper.exampleCheck(entityClass));
}
+ if (getConfig().isSafeSelect()) {
+ sql.append(SqlHelper.exampleHasAtLeastOneCriteriaCheck("_parameter"));
+ }
sql.append("distinct");
//支持查询指定列
sql.append(SqlHelper.exampleSelectColumns(entityClass));
diff --git a/base/src/main/java/tk/mybatis/mapper/provider/base/BaseDeleteProvider.java b/base/src/main/java/tk/mybatis/mapper/provider/base/BaseDeleteProvider.java
index ab58a667c..748e03056 100644
--- a/base/src/main/java/tk/mybatis/mapper/provider/base/BaseDeleteProvider.java
+++ b/base/src/main/java/tk/mybatis/mapper/provider/base/BaseDeleteProvider.java
@@ -54,7 +54,7 @@ public String delete(MappedStatement ms) {
StringBuilder sql = new StringBuilder();
//如果设置了安全删除,就不允许执行不带查询条件的 delete 方法
if (getConfig().isSafeDelete()) {
- sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getColumns(entityClass)));
+ sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getColumns(entityClass), isNotEmpty()));
}
// 如果是逻辑删除,则修改为更新表,修改逻辑删除字段的值
if (SqlHelper.hasLogicDeleteColumn(entityClass)) {
diff --git a/base/src/main/java/tk/mybatis/mapper/provider/base/BaseSelectProvider.java b/base/src/main/java/tk/mybatis/mapper/provider/base/BaseSelectProvider.java
index 051c62f69..002c4dcd3 100644
--- a/base/src/main/java/tk/mybatis/mapper/provider/base/BaseSelectProvider.java
+++ b/base/src/main/java/tk/mybatis/mapper/provider/base/BaseSelectProvider.java
@@ -25,6 +25,7 @@
package tk.mybatis.mapper.provider.base;
import org.apache.ibatis.mapping.MappedStatement;
+import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
@@ -51,6 +52,9 @@ public String selectOne(MappedStatement ms) {
//修改返回值类型为实体类型
setResultType(ms, entityClass);
StringBuilder sql = new StringBuilder();
+ if (getConfig().isSafeSelect()) {
+ sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getColumns(entityClass), isNotEmpty()));
+ }
sql.append(SqlHelper.selectAllColumns(entityClass));
sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.whereAllIfColumns(entityClass, isNotEmpty()));
@@ -68,6 +72,9 @@ public String select(MappedStatement ms) {
//修改返回值类型为实体类型
setResultType(ms, entityClass);
StringBuilder sql = new StringBuilder();
+ if (getConfig().isSafeSelect()) {
+ sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getColumns(entityClass), isNotEmpty()));
+ }
sql.append(SqlHelper.selectAllColumns(entityClass));
sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.whereAllIfColumns(entityClass, isNotEmpty()));
@@ -110,6 +117,9 @@ public String selectByPrimaryKey(MappedStatement ms) {
public String selectCount(MappedStatement ms) {
Class> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
+ if (getConfig().isSafeSelect()) {
+ sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getColumns(entityClass), isNotEmpty()));
+ }
sql.append(SqlHelper.selectCount(entityClass));
sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.whereAllIfColumns(entityClass, isNotEmpty()));
diff --git a/base/src/main/java/tk/mybatis/mapper/provider/base/BaseUpdateProvider.java b/base/src/main/java/tk/mybatis/mapper/provider/base/BaseUpdateProvider.java
index 9f2e8335d..9fe1e106a 100644
--- a/base/src/main/java/tk/mybatis/mapper/provider/base/BaseUpdateProvider.java
+++ b/base/src/main/java/tk/mybatis/mapper/provider/base/BaseUpdateProvider.java
@@ -25,6 +25,7 @@
package tk.mybatis.mapper.provider.base;
import org.apache.ibatis.mapping.MappedStatement;
+import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.MapperHelper;
import tk.mybatis.mapper.mapperhelper.MapperTemplate;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
@@ -48,6 +49,9 @@ public BaseUpdateProvider(Class> mapperClass, MapperHelper mapperHelper) {
public String updateByPrimaryKey(MappedStatement ms) {
Class> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
+ if (getConfig().isSafeUpdate()) {
+ sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getPKColumns(entityClass), isNotEmpty()));
+ }
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.updateSetColumns(entityClass, null, false, false));
sql.append(SqlHelper.wherePKColumns(entityClass, true));
@@ -63,6 +67,9 @@ public String updateByPrimaryKey(MappedStatement ms) {
public String updateByPrimaryKeySelective(MappedStatement ms) {
Class> entityClass = getEntityClass(ms);
StringBuilder sql = new StringBuilder();
+ if (getConfig().isSafeUpdate()) {
+ sql.append(SqlHelper.notAllNullParameterCheck("_parameter", EntityHelper.getPKColumns(entityClass), isNotEmpty()));
+ }
sql.append(SqlHelper.updateTable(entityClass, tableName(entityClass)));
sql.append(SqlHelper.updateSetColumns(entityClass, null, true, isNotEmpty()));
sql.append(SqlHelper.wherePKColumns(entityClass, true));
diff --git a/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByFieldTest.java b/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByFieldTest.java
index fb6112950..1e9ed2ee7 100644
--- a/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByFieldTest.java
+++ b/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByFieldTest.java
@@ -15,6 +15,7 @@ public class SafeDeleteByFieldTest extends BaseTest {
protected Config getConfig() {
Config config = super.getConfig();
config.setSafeDelete(true);
+ config.setNotEmpty(true);
return config;
}
@@ -40,6 +41,19 @@ public void testSafeDeleteNull() {
}
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeDeleteEmptyString() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Country country = new Country();
+ country.setCountryname("");
+ mapper.delete(country);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeDeleteByExample() {
SqlSession sqlSession = getSqlSession();
@@ -62,4 +76,17 @@ public void testSafeDeleteByExampleNull() {
}
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeDeleteByExampleWithEmptyStringCriterion() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Example example = new Example(Country.class);
+ example.createCriteria().andEqualTo("countryname", "");
+ mapper.deleteByExample(example);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
}
diff --git a/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByMethodTest.java b/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByMethodTest.java
index 8259de8b2..be026d4c9 100644
--- a/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByMethodTest.java
+++ b/base/src/test/java/tk/mybatis/mapper/base/delete/SafeDeleteByMethodTest.java
@@ -15,6 +15,7 @@ public class SafeDeleteByMethodTest extends BaseTest {
protected Config getConfig() {
Config config = super.getConfig();
config.setSafeDelete(true);
+ config.setNotEmpty(true);
//和 SafeDeleteByFieldTest 测试的区别在此,这里将会使后面调用 EntityField.getValue 时,使用 getter 方法获取值
config.setEnableMethodAnnotation(true);
return config;
@@ -42,6 +43,19 @@ public void testSafeDeleteNull() {
}
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeDeleteEmptyString() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Country country = new Country();
+ country.setCountryname("");
+ mapper.delete(country);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeDeleteByExample() {
@@ -65,6 +79,19 @@ public void testSafeDeleteByExampleNull() {
}
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeDeleteByExampleWithEmptyStringCriterion() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Example example = new Example(Country.class);
+ example.createCriteria().andEqualTo("countryname", "");
+ mapper.deleteByExample(example);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeDeleteByExampleWithNullValueCriterion() {
SqlSession sqlSession = getSqlSession();
diff --git a/base/src/test/java/tk/mybatis/mapper/base/select/SafeSelectByFieldTest.java b/base/src/test/java/tk/mybatis/mapper/base/select/SafeSelectByFieldTest.java
new file mode 100644
index 000000000..f036eeef5
--- /dev/null
+++ b/base/src/test/java/tk/mybatis/mapper/base/select/SafeSelectByFieldTest.java
@@ -0,0 +1,142 @@
+package tk.mybatis.mapper.base.select;
+
+import org.apache.ibatis.exceptions.PersistenceException;
+import org.apache.ibatis.session.SqlSession;
+import org.junit.Assert;
+import org.junit.Test;
+import tk.mybatis.mapper.base.BaseTest;
+import tk.mybatis.mapper.base.Country;
+import tk.mybatis.mapper.base.CountryMapper;
+import tk.mybatis.mapper.entity.Config;
+import tk.mybatis.mapper.entity.Example;
+import tk.mybatis.mapper.entity.model.CountryExample;
+
+public class SafeSelectByFieldTest extends BaseTest {
+
+ @Override
+ protected Config getConfig() {
+ Config config = super.getConfig();
+ config.setSafeSelect(true);
+ config.setNotEmpty(true);
+ return config;
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelect() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.select(new Country());
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectNull() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.select(null);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectEmptyString() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Country country = new Country();
+ country.setCountryname("");
+ mapper.select(country);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectCountEmptyString() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Country country = new Country();
+ country.setCountryname("");
+ mapper.selectCount(country);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectByExample() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.selectByExample(new Example(Country.class));
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectByExampleNull() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.selectByExample(null);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectByExampleWithEmptyStringCriterion() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Example example = new Example(Country.class);
+ example.createCriteria().andEqualTo("countryname", "");
+ mapper.selectByExample(example);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeSelectByGeneratedExampleWithEmptyStringCriterion() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ CountryExample example = new CountryExample();
+ example.createCriteria().andCountrynameEqualTo("");
+ mapper.selectByExample(example);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test
+ public void testSafeSelectWithCondition() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Country country = new Country();
+ country.setCountryname("China");
+ Assert.assertEquals(1, mapper.select(country).size());
+
+ Example example = new Example(Country.class);
+ example.createCriteria().andEqualTo("countryname", "China");
+ Assert.assertEquals(1, mapper.selectByExample(example).size());
+
+ CountryExample generatedExample = new CountryExample();
+ generatedExample.createCriteria().andCountrynameEqualTo("China");
+ Assert.assertEquals(1, mapper.selectByExample(generatedExample).size());
+
+ Assert.assertEquals(183, mapper.selectAll().size());
+ } finally {
+ sqlSession.close();
+ }
+ }
+}
diff --git a/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByFieldTest.java b/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByFieldTest.java
index a2689de79..d5d66f45e 100644
--- a/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByFieldTest.java
+++ b/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByFieldTest.java
@@ -18,6 +18,28 @@ protected Config getConfig() {
return config;
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeUpdateByPrimaryKeyNull() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.updateByPrimaryKey(new Country());
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeUpdateByPrimaryKeySelectiveNull() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.updateByPrimaryKeySelective(new Country());
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeUpdate() {
SqlSession sqlSession = getSqlSession();
@@ -29,6 +51,19 @@ public void testSafeUpdate() {
}
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeUpdateWithEmptyStringCriterion() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Example example = new Example(Country.class);
+ example.createCriteria().andEqualTo("countryname", "");
+ mapper.updateByExample(new Country(), example);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeUpdateNull() {
SqlSession sqlSession = getSqlSession();
diff --git a/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByMethodTest.java b/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByMethodTest.java
index 002a508d0..723934e4d 100644
--- a/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByMethodTest.java
+++ b/base/src/test/java/tk/mybatis/mapper/base/update/SafeUpdateByMethodTest.java
@@ -20,6 +20,28 @@ protected Config getConfig() {
return config;
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeUpdateByPrimaryKeyNull() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.updateByPrimaryKey(new Country());
+ } finally {
+ sqlSession.close();
+ }
+ }
+
+ @Test(expected = PersistenceException.class)
+ public void testSafeUpdateByPrimaryKeySelectiveNull() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ mapper.updateByPrimaryKeySelective(new Country());
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeUpdate() {
SqlSession sqlSession = getSqlSession();
@@ -31,6 +53,19 @@ public void testSafeUpdate() {
}
}
+ @Test(expected = PersistenceException.class)
+ public void testSafeUpdateWithEmptyStringCriterion() {
+ SqlSession sqlSession = getSqlSession();
+ try {
+ CountryMapper mapper = sqlSession.getMapper(CountryMapper.class);
+ Example example = new Example(Country.class);
+ example.createCriteria().andEqualTo("countryname", "");
+ mapper.updateByExample(new Country(), example);
+ } finally {
+ sqlSession.close();
+ }
+ }
+
@Test(expected = PersistenceException.class)
public void testSafeUpdateNull() {
SqlSession sqlSession = getSqlSession();
diff --git a/core/src/main/java/tk/mybatis/mapper/entity/Config.java b/core/src/main/java/tk/mybatis/mapper/entity/Config.java
index da0c06139..610331e3e 100644
--- a/core/src/main/java/tk/mybatis/mapper/entity/Config.java
+++ b/core/src/main/java/tk/mybatis/mapper/entity/Config.java
@@ -86,6 +86,10 @@ public class Config {
* 安全更新,开启后,不允许更新全表,如 update table set xx=?
*/
private boolean safeUpdate;
+ /**
+ * 安全查询,开启后,不允许执行不带查询条件的条件查询方法
+ */
+ private boolean safeSelect;
/**
* 控制通过主键进行操作(select, update, delete)时,是否拼接逻辑删除字段的条件(默认 true,保持兼容)
*
@@ -318,6 +322,14 @@ public void setSafeUpdate(boolean safeUpdate) {
this.safeUpdate = safeUpdate;
}
+ public boolean isSafeSelect() {
+ return safeSelect;
+ }
+
+ public void setSafeSelect(boolean safeSelect) {
+ this.safeSelect = safeSelect;
+ }
+
public boolean isLogicDeleteByKey() {
return logicDeleteByKey;
}
@@ -423,6 +435,8 @@ public void setProperties(Properties properties) {
this.safeDelete = Boolean.valueOf(properties.getProperty("safeDelete"));
//safeUpdate
this.safeUpdate = Boolean.valueOf(properties.getProperty("safeUpdate"));
+ //safeSelect
+ this.safeSelect = Boolean.valueOf(properties.getProperty("safeSelect"));
// 控制通过主键进行操作(select, update, delete)时,是否拼接逻辑删除字段的条件(默认 true,保持兼容)
String logicDeleteByKey = properties.getProperty("logicDeleteByKey");
if (StringUtil.isNotEmpty(logicDeleteByKey)) {
diff --git a/core/src/main/java/tk/mybatis/mapper/mapperhelper/SqlHelper.java b/core/src/main/java/tk/mybatis/mapper/mapperhelper/SqlHelper.java
index 080189153..dac7d7121 100644
--- a/core/src/main/java/tk/mybatis/mapper/mapperhelper/SqlHelper.java
+++ b/core/src/main/java/tk/mybatis/mapper/mapperhelper/SqlHelper.java
@@ -576,6 +576,18 @@ public static String updateSetColumnsIgnoreVersion(Class> entityClass, String
* @return
*/
public static String notAllNullParameterCheck(String parameterName, Set columnSet) {
+ return notAllNullParameterCheck(parameterName, columnSet, false);
+ }
+
+ /**
+ * 不是所有参数都是 null 或空字符串的检查
+ *
+ * @param parameterName 参数名
+ * @param columnSet 需要检查的列
+ * @param notEmpty 是否判断 String 类型 != ''
+ * @return
+ */
+ public static String notAllNullParameterCheck(String parameterName, Set columnSet, boolean notEmpty) {
StringBuilder sql = new StringBuilder();
sql.append("");
+ sql.append("', ");
+ sql.append(notEmpty);
+ sql.append(")\"/>");
return sql.toString();
}
@@ -598,9 +612,22 @@ public static String notAllNullParameterCheck(String parameterName, Set");
+ sql.append(parameterName).append(", ");
+ sql.append(notEmpty);
+ sql.append(")\"/>");
return sql.toString();
}
diff --git a/core/src/main/java/tk/mybatis/mapper/util/OGNL.java b/core/src/main/java/tk/mybatis/mapper/util/OGNL.java
index 2fe0b38af..4e67e8ba9 100644
--- a/core/src/main/java/tk/mybatis/mapper/util/OGNL.java
+++ b/core/src/main/java/tk/mybatis/mapper/util/OGNL.java
@@ -32,6 +32,7 @@
import tk.mybatis.mapper.mapperhelper.EntityHelper;
import tk.mybatis.mapper.mapperhelper.SqlHelper;
+import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.*;
@@ -71,18 +72,32 @@ public static boolean checkExampleEntityClass(Object parameter, String entityFul
* @return
*/
public static boolean notAllNullParameterCheck(Object parameter, String fields) {
+ return notAllNullParameterCheck(parameter, fields, false);
+ }
+
+ /**
+ * 检查 parameter 对象中指定的 fields 是否全是 null 或空字符串,如果是则抛出异常
+ *
+ * @param parameter
+ * @param fields
+ * @param notEmpty
+ * @return
+ */
+ public static boolean notAllNullParameterCheck(Object parameter, String fields, boolean notEmpty) {
if (parameter != null) {
try {
Set columns = EntityHelper.getColumns(parameter.getClass());
Set fieldSet = new HashSet(Arrays.asList(fields.split(",")));
for (EntityColumn column : columns) {
- if (fieldSet.contains(column.getProperty())) {
+ if (fieldSet.contains(column.getProperty()) && !isLogicDeleteColumn(column)) {
Object value = column.getEntityField().getValue(parameter);
- if (value != null) {
+ if (isEffectiveValue(value, notEmpty)) {
return true;
}
}
}
+ } catch (MapperException e) {
+ throw e;
} catch (Exception e) {
throw new MapperException(SAFE_DELETE_ERROR, e);
}
@@ -111,31 +126,26 @@ public static boolean notEmptyCollectionCheck(Object parameter, String error) {
* @return
*/
public static boolean exampleHasAtLeastOneCriteriaCheck(Object parameter) {
+ return exampleHasAtLeastOneCriteriaCheck(parameter, true);
+ }
+
+ public static boolean exampleHasAtLeastOneCriteriaCheck(Object parameter, boolean notEmpty) {
if (parameter != null) {
try {
- if (parameter instanceof Example) {
- List criteriaList = ((Example) parameter).getOredCriteria();
- if (criteriaList != null && criteriaList.size() > 0) {
- for (Example.Criteria criteria : criteriaList) {
- if (criteria != null && criteria.isValid()) {
- return true;
- }
+ List> criteriaList = getOredCriteria(parameter);
+ if (criteriaList != null && criteriaList.size() > 0) {
+ boolean hasCriterion = false;
+ for (Object criteria : criteriaList) {
+ if (criteriaHasCriterion(criteria, notEmpty)) {
+ hasCriterion = true;
}
}
- } else {
- Method getter = parameter.getClass().getDeclaredMethod("getOredCriteria");
- Object list = getter.invoke(parameter);
- if (list != null && list instanceof List) {
- List criteriaList = (List) list;
- if (criteriaList.size() > 0) {
- for (Object criteria : criteriaList) {
- if (criteria instanceof Example.Criteria && ((Example.Criteria) criteria).isValid()) {
- return true;
- }
- }
- }
+ if (hasCriterion) {
+ return true;
}
}
+ } catch (MapperException e) {
+ throw e;
} catch (Exception e) {
throw new MapperException(SAFE_DELETE_ERROR, e);
}
@@ -143,6 +153,120 @@ public static boolean exampleHasAtLeastOneCriteriaCheck(Object parameter) {
throw new MapperException(SAFE_DELETE_EXCEPTION);
}
+ private static List> getOredCriteria(Object parameter) throws Exception {
+ if (parameter instanceof Example) {
+ return ((Example) parameter).getOredCriteria();
+ }
+ Method getter = parameter.getClass().getMethod("getOredCriteria");
+ if (!getter.isAccessible()) {
+ getter.setAccessible(true);
+ }
+ Object list = getter.invoke(parameter);
+ if (list instanceof List) {
+ return (List>) list;
+ }
+ return null;
+ }
+
+ private static boolean criteriaHasCriterion(Object criteria, boolean notEmpty) throws Exception {
+ if (criteria == null) {
+ return false;
+ }
+ List> criterionList = getCriteriaList(criteria);
+ if (criterionList != null) {
+ boolean hasCriterion = false;
+ for (Object criterion : criterionList) {
+ if (criterion != null) {
+ emptyCriterionValueCheck(criterion, notEmpty);
+ hasCriterion = true;
+ }
+ }
+ return hasCriterion;
+ }
+ Boolean valid = invokeBoolean(criteria, "isValid");
+ return valid != null && valid;
+ }
+
+ private static List> getCriteriaList(Object criteria) throws Exception {
+ if (criteria instanceof Example.Criteria) {
+ return ((Example.Criteria) criteria).getAllCriteria();
+ }
+ Object list = invoke(criteria, "getAllCriteria");
+ if (list instanceof List) {
+ return (List>) list;
+ }
+ list = invoke(criteria, "getCriteria");
+ if (list instanceof List) {
+ return (List>) list;
+ }
+ return null;
+ }
+
+ private static void emptyCriterionValueCheck(Object criterion, boolean notEmpty) throws Exception {
+ Boolean noValue = invokeBoolean(criterion, "isNoValue");
+ if (Boolean.TRUE.equals(noValue)) {
+ return;
+ }
+ Boolean singleValue = invokeBoolean(criterion, "isSingleValue");
+ if (Boolean.TRUE.equals(singleValue) && isEmptyConditionValue(invoke(criterion, "getValue"), notEmpty)) {
+ throw new MapperException(SAFE_DELETE_EXCEPTION);
+ }
+ Boolean betweenValue = invokeBoolean(criterion, "isBetweenValue");
+ if (Boolean.TRUE.equals(betweenValue)
+ && (isEmptyConditionValue(invoke(criterion, "getValue"), notEmpty)
+ || isEmptyConditionValue(invoke(criterion, "getSecondValue"), notEmpty))) {
+ throw new MapperException(SAFE_DELETE_EXCEPTION);
+ }
+ Boolean listValue = invokeBoolean(criterion, "isListValue");
+ if (Boolean.TRUE.equals(listValue) && isEmptyConditionValue(invoke(criterion, "getValue"), notEmpty)) {
+ throw new MapperException(SAFE_DELETE_EXCEPTION);
+ }
+ }
+
+ private static Boolean invokeBoolean(Object target, String methodName) throws Exception {
+ Object value = invoke(target, methodName);
+ if (value instanceof Boolean) {
+ return (Boolean) value;
+ }
+ return null;
+ }
+
+ private static Object invoke(Object target, String methodName) throws Exception {
+ try {
+ Method method = target.getClass().getMethod(methodName);
+ if (!method.isAccessible()) {
+ method.setAccessible(true);
+ }
+ return method.invoke(target);
+ } catch (NoSuchMethodException e) {
+ return null;
+ }
+ }
+
+ private static boolean isLogicDeleteColumn(EntityColumn column) {
+ return column.getEntityField().isAnnotationPresent(LogicDelete.class);
+ }
+
+ private static boolean isEffectiveValue(Object value, boolean notEmpty) {
+ return !isEmptyConditionValue(value, notEmpty);
+ }
+
+ private static boolean isEmptyConditionValue(Object value, boolean notEmpty) {
+ if (value == null) {
+ return true;
+ }
+ if (notEmpty && value instanceof String && StringUtil.isEmpty((String) value)) {
+ return true;
+ }
+ if (value instanceof Collection && ((Collection) value).isEmpty()) {
+ return true;
+ }
+ if (value.getClass().isArray() && Array.getLength(value) == 0) {
+ return true;
+ }
+ return false;
+ }
+
/**
* 是否包含自定义查询列
*