Java Spring/roo自定义查找器
我想创建一个定制的finder(作为一名web开发老手,但在Java、Spring和Roo方面却是一个完全的新手) 下面的第一个方法来自我的“资产”视图控制器类。这是您第一次点击资产管理页面时发生的情况——它返回一个视图和一批当前活动的资产。它工作得很好:Java Spring/roo自定义查找器,java,spring,spring-mvc,spring-roo,Java,Spring,Spring Mvc,Spring Roo,我想创建一个定制的finder(作为一名web开发老手,但在Java、Spring和Roo方面却是一个完全的新手) 下面的第一个方法来自我的“资产”视图控制器类。这是您第一次点击资产管理页面时发生的情况——它返回一个视图和一批当前活动的资产。它工作得很好: @RequestMapping("/assets") public ModelAndView listAssets() { ModelAndView mav = new ModelAndView(); mav.setViewN
@RequestMapping("/assets")
public ModelAndView listAssets() {
ModelAndView mav = new ModelAndView();
mav.setViewName("admin/asset");
Collection<com.myapp.model.Asset> assets = com.myapp.model.Asset.findAllAssets() ;
mav.addObject("assets", assets);
return mav;
}
@RequestMapping(“/assets”)
公共模型和视图列表资产(){
ModelAndView mav=新ModelAndView();
mav.setViewName(“管理员/资产”);
集合资产=com.myapp.model.Asset.findAllAssets();
mav.addObject(“资产”,资产);
返回mav;
}
所以现在我想让一个“POST”请求发送到该URL,接受资产搜索表单的提交,该表单包含资产对象的几个关键属性的字段
(现在我正在我的视图控制器中对finder进行编码,我知道最终我会将其下推到model类。现在我只是为了方便起见在这里使用它。另外,我知道我不必给出对象的完全限定名,我已经将我的控制器命名为与它所对话的模型相同的名称,所以直到我重新命名为止。)我不知道,我正在努力解决这个问题。)
我从我生成的一些Roo Finder那里借用了一些代码,最终得到:
@RequestMapping(value = "/assets", method = RequestMethod.POST)
public ModelAndView searchAssets(
@RequestParam("category") String category,
@RequestParam("year") String year,
@RequestParam("manufacturer") String manufacturer,
@RequestParam("drive_type") String driveType,
@RequestParam("subcategory") String subcategory,
@RequestParam("serial") String serial,
@RequestParam("listing_type") String listingType,
@RequestParam("hours") String hours,
@RequestParam("model") String model,
@RequestParam("mileage") String mileage ) {
ModelAndView mav = new ModelAndView();
mav.setViewName("admin/asset");
EntityManager em = com.myapp.model.Asset.entityManager();
TypedQuery<Asset> q = em.createQuery("SELECT o FROM Asset AS o ", Asset.class);
Collection<Asset> assets = q.getResultList();
mav.addObject("assets", assets);
return mav;
}
@RequestMapping(value=“/assets”,method=RequestMethod.POST)
公共模型和视图搜索资产(
@RequestParam(“类别”)字符串类别,
@RequestParam(“年”)字符串年份,
@RequestParam(“制造商”)字符串制造商,
@RequestParam(“驱动器类型”)字符串驱动器类型,
@RequestParam(“子类别”)字符串子类别,
@RequestParam(“串行”)字符串串行,
@RequestParam(“列表类型”)字符串listingType,
@RequestParam(“小时”)字符串小时,
@RequestParam(“模型”)字符串模型,
@RequestParam(“里程”)字符串(里程){
ModelAndView mav=新ModelAndView();
mav.setViewName(“管理员/资产”);
EntityManager em=com.myapp.model.Asset.EntityManager();
TypedQuery q=em.createQuery(“从资产中选择o作为o”,Asset.class);
集合资产=q.getResultList();
mav.addObject(“资产”,资产);
返回mav;
}
因此,问题是:
1) 有没有办法获取我的参数集合,而不是将它们烘焙到方法签名中?因为我有点讨厌这样
2) 有没有一种方法可以迭代我的参数并以这种方式生成查询字符串的WHERE子句?我不想对这里给我的领域有太多的了解,我需要能够处理这些领域,我大部分不会拥有所有领域。因此,如果有意义的话,我更愿意以迭代方式而不是声明方式构建查询
您将如何在这里构建select语句
编辑(解决方案):
@madth3为我指明了正确的方向。这是我最后得到的,我很自豪:
public static TypedQuery<Asset> findAssetsByWebRequest( WebRequest request) {
ArrayList<String> wheres = new ArrayList<String>();
Iterator<String> i = request.getParameterNames();
while (i.hasNext()) {
String fieldname = i.next();
String value = request.getParameter(fieldname);
if (value.length() == 0) {
continue;
}
if (fieldname.equals("manufacturer") || fieldname.equals("model") ) {
value = value.replace('*', '%');
if (value.charAt(0) != '%') {
value = "%" + value;
}
if (value.charAt(value.length() - 1) != '%') {
value = value + "%";
}
wheres.add(" o." + fieldname + " LIKE '" + value + "'");
}
else if (fieldname.contains("min")) {
fieldname = fieldname.replace("min", "").toLowerCase();
wheres.add(" o." + fieldname + " >= '" + value + "' ");
}
else if (fieldname.contains("max")) {
fieldname = fieldname.replace("max", "").toLowerCase();
wheres.add(" o." + fieldname + " <= '" + value + "' ");
}
else {
wheres.add(" o." + fieldname + " = '" + value + "' ");
}
}
String query = "SELECT o FROM Asset AS o ";
if (wheres.size() > 0) {
query += " WHERE ";
for (String clause: wheres) {
query += clause + " AND ";
}
query += " 1 = 1 ";
}
EntityManager em = Asset.entityManager();
TypedQuery<Asset> q = em.createQuery(query, Asset.class);
return q;
}
publicstatictypedqueryfindassetsbywebrequest(WebRequest请求){
ArrayList,其中s=新的ArrayList();
迭代器i=request.getParameterNames();
while(i.hasNext()){
字符串fieldname=i.next();
字符串值=request.getParameter(fieldname);
如果(value.length()==0){
继续;
}
if(fieldname.equals(“制造商”)| | fieldname.equals(“型号”)){
value=value.replace('*','%');
if(value.charAt(0)!=“%”{
value=“%”+值;
}
if(value.charAt(value.length()-1)!=“%”{
值=值+“%”;
}
式中。添加(“o.”+fieldname+“LIKE”“+value+”);
}
else if(fieldname.contains(“min”)){
fieldname=fieldname.replace(“min”,”).toLowerCase();
其中。添加(“o.”+fieldname+“>=”“+value+””);
}
else if(fieldname.contains(“max”)){
fieldname=fieldname.replace(“max”,”).toLowerCase();
其中,add(“o.”+fieldname+”Spring roo可以为您生成查找程序:
类型:
finder list
将列出所有具有一个属性的finder,您可以使用可选参数设置属性的数量好吧,按照传统方式。。。
Java中的Servlets标准定义了对象请求,其中有带参数的映射(散列、字典),所以您可以像这样访问它们
public ModelAndView searchAssets(HttpRequest request) {
StringBuilder builder = new StringBuilder();
for (String param : request.getParameterNames()) {
value = request.getParameter(param);
builder.append(param);
builder.append("="); // or LIKE
builder.append("\'" + value "\'");
builder.append(" AND ");
}
// deleting the last " AND "
builder.delete(builder.length-5, builder.length);
// In the entity create a method that executes a query with the string
// If the parameter names are column names then you'd have to use a nativeQuery
// You'd have to look it up in JPA
List<Asset> list = Asset.search(builder.toString());
// put the list in the ModelAndView
}
公共模型和视图搜索资产(HttpRequest请求){
StringBuilder=新的StringBuilder();
for(字符串参数:request.getParameterNames()){
value=request.getParameter(param);
builder.append(参数);
builder.append(“=”;//或类似
builder.append(“\'”+值“\'”);
建造商。附加(“和”);
}
//删除最后一个“和”
builder.delete(builder.length-5,builder.length);
//在实体中,创建使用字符串执行查询的方法
//如果参数名是列名,则必须使用nativeQuery
//你得在JPA上查一下
List=Asset.search(builder.toString());
//将列表放在ModelAndView中
}
我发表了评论,但我更愿意在回答中解释我的方法:
我认为最好像Raloh下面所说的那样(使用Roo生成的代码),使用POJO作为参数而不是WebRequest来创建一个自定义查找器,这样就不会与MVC产生依赖关系
尝试创建一个POJO,例如AssetFilter,其中包含要在finder中使用的属性
public static TypedQuery<Asset> findAssetsByFilter(AssetFilter filter) {
If (filter.getManufacturer()!=null) where.append(" AND ...")
}
publicstatictypedqueryfindassetsbyfilter(AssetFilter过滤器){
If(filter.getManufacturer()!=null)where.append(“AND…”)
}
控制器将根据请求创建POJO过滤器,您可以在任何地方使用该查找器,甚至可以为其创建集成测试。没错,
public static TypedQuery<Asset> findAssetsByFilter(AssetFilter filter) {
If (filter.getManufacturer()!=null) where.append(" AND ...")
}