在很多初学java的人在写多条件查询的时候一般都是直接用 IF 判断进行拼接,这样很不美观,而且容易出问题,下面我在这里记录一下我是如何进行条件拼接的,下面我先说一下前提条件和思路:
第一步:获取从页面传过来的参数;
第二步:把参数添加到Map集合中;
第三步:进行参数类型的判断和拼接;
建一个实体类,如:
public class C_ChuangJianRenWu {
private int chuangJianRenWuID;public int getChuangJianRenWuID() {
return chuangJianRenWuID;
}
public void setChuangJianRenWuID(int chuangJianRenWuID) {
this.chuangJianRenWuID = chuangJianRenWuID;
}}
因为查询的时候也要用到,所有一般都会有对应的实体类;实体类在拼接参数的时候只是用来获取参数的类型来进行相对应的拼接;
把参数拼接到map中:
//接收页面的参数
String chuangJianRenWuID=Integer.valueOf(request.getParameter("chuangJianRenWuID"));
//把参数放入map集合中
// 相当 where cj.chuangJianRenWuID=chuangJianRenWuID 这样的一个条件 ,可以给别名,也可以直接给数据查询字段;
Map<String, Object> map=new HashMap<String, Object>();
map.put("cj.chuangJianRenWuID", chuangJianRenWuID);
map.put("HeTongFanHuiID", heTongFanHuiID);
它通过键值对的方式传值;
下面就是重点,如何处理拼接参数:
public static <T> String patchCondition(Map<String, Object> map,Class<T> obj){
StringBuffer stBuffer=new StringBuffer();//拼接字符串
Set<String> keySet=map.keySet();
Iterator<String> iterator=keySet.iterator();//迭代map的键
stBuffer.append(" Where 1=1");
while(iterator.hasNext()){
String Key=iterator.next();
String name="";
if (Key.indexOf(".")>-1) {//判断是否是别名,如果是就进行截断,获取后面的字段并且首字母转化为小写
String[] strs=Key.split("\\.");
name=strs[1].toString();
name = name.substring(0, 1).toLowerCase() + name.substring(1);//首字母转化为小写
}else {
name = Key.substring(0, 1).toLowerCase() + Key.substring(1);
}
try {
Class<?> type = obj.getDeclaredField(name).getType();//获取po中成员变量类型,根据类型判断进行拼接的格式
if (type.isAssignableFrom(String.class)) {//判断类型是否为string类型
if (Tools.isNotNull(map.get(Key).toString())) { //是否为空判断, //找相似的数据;
//map.get(Key) 是获取和键对应的值;
stBuffer.append(" and "+Key+" like '%"+map.get(Key)+"%'");
}
}
if (type.isAssignableFrom(int.class)) {
if (!(map.get(Key).toString()).equals("0")) {
stBuffer.append(" and "+Key+"="+map.get(Key));
}
}
if (type.isAssignableFrom(boolean.class)) {
stBuffer.append(" and "+Key+"="+map.get(Key));
}
} catch (NoSuchFieldException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return stBuffer.toString();//返回拼接好的where条件
}
//判断为空否
public class Tools {
public static boolean isNotNull( String value ) {
if( value == null || "".equals( value.trim()) || "null".equalsIgnoreCase(value) ) {
return false;
}
return true;
}}
//输出的拼接参数格式,上面的实体类和map集合只是模板,并不是根据上面的po和map模板输出的拼接条件;
输出的拼接条件:Where 1=1 and ht.HeTongMingChen like '%合同%' and ht.HeTongZhuangTaiID=2 and ht.HeTongFanHuiID=1 and kh.KeHuMC like '%老张%'
为什么要 1=1呢?
大家想想 我才拼接参数时 stBuffer.append(" Where 1=1"); 在前面先添加where 的,如果参数都为空 那输出的条件只是 一个where ;这样如果拼接到查询语句中就是这样了:select * from table where 不可能不报异常啊,所有1=1 就是为了杜绝这种情况而存在的,当然不但1=1可以,2=2也可以,类似这些条件的都可以;
如果嫌弃速度慢就可以把判断值是否为空放到判断类型是否对应外面;让它先判断它为不为空,再进行条件类型的判断;这样可以减少反射获取类型的时间,这里我就不进行更改了;
注意:我使用的数据库是mysql ,可能别的数据库语句会有一些差异;
如建议请多多指教,互相交流,共同进步.....