后台CRUD通用封装(简)

admin后台代码通用封装


#重点封装类
CommonDao
/*
如果在mycat分库分表的情况下,可以提供多个方法支持不同分片算法的数据crud,这里演示较为常用的查询,即非复合分片的CRUD实现
@mapper:使用该注解,结合@select等标签来省略配置文件
*/

	public interface CommonDao{
	//不带条件查询所有
	@Select("select *from ${tableName} limit  #{start} ,#{ size}")
	@ResultType(HashMap.class)
	List<HashMap> list(@param("tableName")String tableName,@param("start")int start,@param("size")int size)

	//根据list查询count总数
 	@Select("select count(*) from ${tableName}")
 	@ResultType(Integer.class)
	int listCount(@param("tableName")String tableName);
	
	//根据条件查询list
	@Select("select * from ${tableName} where 1=1 ${where}  limit  #{start} ,#{size}")    //where ==> and  name  = 11 and password = ddd
	@ResultType(HashMap.calss)
	List<HashMap> listForWhere(@param("tableName") String tableName,@param("where") String where,@param(“start”) int start , @Param(size) int size);

	//ListCountForWhere
    @Select("select count(*) from ${tableName} where 1=1 ${where}") //where ==> and  name  = 11 and password = ddd
	@ResultType(HashMap.calss)
	//不需要分页了
	int listCountForWhere(@param("tableName") String tableName,@param("where") String where);
	
	//修改,返回修改了多少行 ,where是条件, sets中存放的是值
	@Update"update ${tableName} set ${sets} where 1=1 ${where }"//set ⇒  name=xxx ,password =xsdfd
	@ResultType(Integer.class)
	int  update(@param("tableName") String tableName,@param("where") String where, @param("sets")String sets)
	
	@Insert("insert into ${tableName} (${fileds}  values(${valuse})")
	@ResultType(Integer.class)
	int  insert(@param("tableName") String tableName ,@param("")String fileds ,Stirng values)  
	//这里在拼接表名的时候一定要使用$符号,因为$符号是拼接,而#号是
	
	@Delete("delete from ${tableName} where 1= 1 $ {where} limit 1")
	@ResultType(Integer.class)
	int delete(@param("tableName") String tableName, @param("where") String where)
}
在完成动态方法的编写之后,我们需要加上@mapper注解,将通用的dao加入到管理容器当中的,用于serice层的注入。同时在我们的编写sqlConfig中添加@mapperConfig将该类识别为一个mapper。

编写完通用的service之后,编写一个通用的service:

	  public interface CommonService{
	  		//加载通用的数据列表 ,包括了我们的无条件查询,无条件的统计     有条件的统计   有条件的统计
  		ResponseResult list(CommonDto dto);
  		//修改该通用的数据列表,新增也使用这个方法,利用dto中的model属性进行区分。
  		ResponseResult  update(CommonDto dto);
  		//删除通用的数据列表
  		 ResponseResult delete(CommonDto  dto);
  }

编写service的是实现类commonServcieImpl类,实现通用的CRUD的业务处理
parseValue: 方法过滤和替换引起SQL注入的关键字符;注filed和value都需要过滤
doFilter:用于依据name查找对应后置增强的Bean,如果查得,则执行对应增强的后置处理
getWhere:拼接where条件字符串,支持like,between,=等条件查询
getSets:拼接修改的set语句的值
getInsertSql:拼接新增Sql的字段和值的字符串。

	 public class CommonServiceImpl  implement Commservice{
		private  CommonDao commondao;
		private ApplicationContext context;	  		
		//加载通用的数据列表 ,包括了我们的无条件查询,无条件的统计     有条件的统计   有条件的统计
  		ResponseResult list(CommonDto dto){
			//先判断对应的表是否具有加载列表的权限,拿到具体对应的某一张表
			if(dto.getName().isList){
			return ResponseResult.errorResult(AppHttpCodeEunm.NO_OPERATOR_AUTH);
			}  
			//查询,有可能会有条件,条件汆子啊CommonDto当中,查询的时候呀我们使用的where.
			getWhere(dto);
			String tableName=dto.getName().name().toLowerCase();
			//起始值
			int start = (dto.getPage()-1)*dto.getSize();
			if(start<-1){
			start = 0;
			}	
			list<?> list =null;
			int total=0;
			//判断是带条件查询还是不带条件查询,根据两者的不同,调用不同的方法
			if(StringUtils.isEmpty(where)){
				list =commonDao.list(tableName,dto.getPage(),dto.getSize());
				total=commonDao.listCount(tableName);
			
			}else{
				//带条件的查询
				list = commonDao.listForWhere(talbeName,where,start,dto.getSize());	
				total = commonDao.listCountForWhere(tableName,where);	
		}	//返回的话,统一返回map,里面封装着list和total;
			Map<String,Object> map=new HashMap<>();
			map.put("list",list);
			map.put("total",total);
		
			//后处理的bean
			doFilter(dto,"list");
			retrun ResponseResult.okResult(map);
		};

		//我们当前只有接口,没有现实类,如果谁要做后置逻辑的和增强,谁就去实现这个接口。
		private void doFilter(CommonDto dto,String list){
			 BaseCommonFilter baseCommonFilter=findFilter(dto);
			 if(baseCommonFilter!=null){
			//处理具体的方法
			AUser adUser= AdminThreadLocalUtils.getUser();
			if("insert".equals(name)){
				baseCommonFilter.doInsertAfter(adUser,dto);
			}
			if("update".equal(name)){
				baseCommonFilter.doupdatetAfter(adUser,dto);
			}
			if("list".equal(name)){
			   baseCommonFilter.doListAfter(adUser,dto);
		}
			if("delete".equal(name)){
			   baseCommnFilter.doDeleteAfter(adUser,dto);
		}
		
		}	
		}
		//从spirng容器当中获取当前的Filter
		private BaseCommonFilter findFilter(commonDto dto){
			String name=dto.getName().name();
			//这里为什么不能直接注入,是因为filter是由需要增强的对象自己编写的,是需要在运行的过程中手动的判断
			if(context.containsBean(name)){
			return context.getBean(name.BaseCommonFilter.class);
			}
			return null;
		}	

		//拼接查询条件来用的,通过dto拿到dto,然后进行循环,然后在循环的的时候拿到各个字段,在循环的时候去拼接各个字符串
		private String getWhere(CommonDto dto){
			StringBuffer where= new StringBuffer;;
			if(dto.getWhere()!=null){
				dto.getWhere.stream().forEach(w->{ 
					//防止sql注入,以及字段为空,字段的值不能相等,所以field不能等于value;
					if(StringUtlis.isNotEmpty(w.getFiled())&&StringUtils.isNotEmpty(w.getValue())&&!w.getFiled().equalsIgnoreCase(w.getValue())){
					//这里已经拿到了field的值了,直接拼接sql不就行了嘛;
					String tempF=parseValue(w.getFiled());
					String tempV=parseValue(w.getValue());
					//filed当中不能是光有数字,而且经过防sql注入的过滤之后,filed和value也是不能相等
					if(!tempF.matches("\\d*")&&!tempF.equalsIgnoreCase(tempV)){
						if("eq".eqy)
						where.append(" and ").append(tempF).append("= \'").append(tempV).append("\'");	
					if("like".equals(w.getType())){
					 where.append(" and  ").append(tempF).append("like \'%").append(tempV).append("%\'");
					if"bwtween".equals(w.getType())){
					String[] temp=tempV.split(",");
					where.append(" and  " ).append(tempF).append(temp[0]).append(" and  ").append(tempF).append(temp[0]).append(" and ").append(temp[1]);
					
			}
			}
			}			
			} 			
		});
			}
		}
		
  		//修改该通用的数据列表,新增也使用这个方法,利用dto中的model属性进行区分。
  		ResponseResult  update(CommonDto dto){
		String model=dto.getModel();
		String tableName=dto.getName.name().tolowerCase();
		if("add".equals(model)){
			//新增,新增需不要加where,不需要,如果传入的dto当中存在
			if(StringUtils.isNotEmpty(where)){
				return ResponseResult.errorResult(AppHttpCodeEnum.PARA_INVALID,"新增数据不能设置条件");
			}else{
				//插入一条数据的方法。
				return addData(dto,talbeName,update);
			}
		}else{
			//修改
				if(StringUtils.isEmpty){
					return Response.errorResult(AppHttpCodeEunm.PARA_INVALID,"修改田条件不能为空");
				}
				return updateData(dto,tableName);
		}	
return null;
}
  		//删除通用的数据列表
  		 ResponseResult delete(CommonDto  dto){

			String where=getWhere(dto)
			String TableName=dto.geName().name().toLowerCase
			if(!dto.getName().isDelete()){
			
			return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPEATOR_AUTH);	
			}
			if(StringUtils.isEmpty(where)){
			return ResponseResult.errorResult(AppHttpCodeEnum.PRAM_INVALID,"删除条件不合法");
			int temp=commonDao.delete(tableName,where);
			if(temp>0){
			doFilter(dto,"delete");
}
				return Response.okResult(temp);
				}
                        			}
 





	//为了防止sql注入,我们需要替换一些敏感的符号,就是对filed做一个判断,使用正则表达式,将可能出现的,w.getValue()
	private String parseValue(String field){
		if(StringUtils.isNotEmpty(filed){
			return filed.replaceAll(".*([';#%+|(--)]).*","");
		}
    return field;
		}


		
//新增逻辑
private ResponseResult	addData(CommonDto dto ,String talbeName){
		String[] sql=getInsertSql(dto);
		if(!dto.getName().isAdd()){
		return ResponseResult.errorResult(AppHttpCodeEnum.No_OPreator_auth);
}	if(sql==null){
		return ResponseResult.errorResult(AppHttpCodeEnum.PARAM_INVALID,"传入的参数值不能为空");
		int temp =commDao.insert(tableName,sql[0],sql[1]);
		if(temp>0){
			doFilter(dto,"add");
		}
		return ResponseResult.okResult(temp);
}
}

private String[] getInsertSql(CommonDto dto){
	//拼接插入的字符串
	StringBuffer fileds=new StringBuffer();
	StringBufer values =new StringBuffer():
	AtomicInteger count=new AtomicInteger();
	if(dto.getSets()=null){
		dto.getSets().stream().forEach(
  		w->{
			if(StringUtils.isEmpty(w.getVaule())){
				//后期我们来判断这个count,如果count有值,则表示sql语句中存在为空的情况,我们就不能正常返回这个sql语句。
				count.incrementAndGet();
		}
		else{
			//匹配替换当前的单引号,百分号,注释,
			String tempF=parseValue(w.getFiled());
			String tempV=paraseValue(w.getValue())
			if(!tempF.matches("\\d*")&&!tempF.equlasIgnoreCase(tempV)){
			if(fileds.lenth>0){
				fileds.append(",");
				values.append(",");
			}
			fileds.append(tempF);
			values.append("\'").append(tempV).append("\'");		
			//name,password,item -- > 'zhangsan','123','sss' 
			
			
			}
	
		}
	});


		}
	if(count.get()>0){
		return null;
	}
	return new String[]{fileds.toStirng,values.toStirng()};
}
//更新一条数据
private ResponseResult updateData(CommonDto dto,String tableName,String where){
		String sets=getSets(dto);
		if(dto.getName().isUpdate()){
		return ResponseResult.errorResult(AppHttpCodeEnum.NO_OPREARTOR_AUTH);
	}
		if(StringUtils.isEmpty(sets)){
		return ResponseResult.errorResult(ApphttpCodeEnum.PARA_INVALID,"修改的参数值不能为空");
}
		int temp   =		commonDao.update(tableName,where,sets);
		if(temp>0){
			doFilter(dto,"update");
	}
		retrun ResponseResult.oKResult(temp)}

//拼接更新条件 where ,sets  set ==>name=xxx ,password=xsdfaf;
	private String getSets(CommonDto dto){
	StringBuffer sets=new  StringBuffer();
	AtomicInteger count=new AtomicInteger();
	if(dto.getSets()!=null){
	  dto.getSets.stream.forEach(w->{
		if(StringUtils.isEmpty(w.getValue())){
			cout.increamentAndGet();
		}else{
		String  tempF=parseValue(w.gertFiled());
		String tempV=praseValue(w.getValue());
		if(!tempF.matches("\\d*")&&tempF.equalsIsIgnoreCase(tempV)){
			if(sets.lenth()>0){
				set.append(",");
}
			sets.append(tempF).append("='/'").append(tempV).append("\'");
   }
   } 
  });
}
	if(count.get()>0){ 
		retrun null;
	}
	return sets.toString();
}

  }



CommonDto类.这里封装的dto类,是由前端封装过来的。

public class CommonDto{
		private Integer size;
		private Integer page;
		private String model;
		private CommonTableEunm name;
		private List<CommonTableEunm> where;
		private List<CommonWhereDto> sets;
}
//CommonWhereDto类
public class CommonWhereDto{

}

Controller端的编写:
CommonController:

@RestController
@RequestMapping("/api/v1/admin/common")
public class CommonController{
		@Autowired
		private CommonService commonService;
		
		@PostMapping("/list")
		public ResponseResult  list(@RequestBody commonDto dto){
		return  commonService.list(dto);
}	
		@PostMapping("/update")
		public ResponseResult	 update(@RquestBody CommonDto dto){
		return commonService.update(dto);
}

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值