我正在开发允许用户使用jpa/Criteria从数据库动态选择一个或多个用户的软件。从几个条件中选择jpa
编辑/更新: - 我现在使用ands增长的谓词。问题是我没有指出正确的字段,而只是一个字符串,其中java正在寻找用户输入的内容。 - 我仍然必须检查如何按照我的建议去做。
当用户输入D输入为PC_Name,d为名称和C Vorname,冗长的EclipseLink显示我:
[EL Fine]: sql: 2012-07-25 15:44:13.173--ServerSession(24105143)--Connection(13480046)--Thread(Thread[main,5,main])--SELECT PERSONALNUMMER, GEBURTSTAG, GRUPPE, IP, MOBIL, NAME, PC_NAME, TELEFON, VORNAME FROM MITARBEITERTABELLE WHERE ((? LIKE ? AND ? LIKE ?) AND ? LIKE ?)
bind => [PC_Name, %d%, Name, %b%, Vorname, %c%]
这证实了我在说什么,当我输入n的名字,我获取整个数据库,因为ñ总是属于命名..
末的编辑/更新
这里是SQL版本,它的工作原理:
try{
String selectString ="SELECT * FROM mitarbeitertabelle WHERE ";
selectString=StringModulierung(selectString);
PreparedStatement selectMitarbeiter = con.prepareStatement(selectString);
int i =1;
if(isNameSuche()){selectMitarbeiter.setString (i,this.wc+_Name+this.wc); i++;}
if(isVornameSuche()){ selectMitarbeiter.setString (i, this.wc+_Vorname+this.wc); i++;}
if(isPersonalnummerSuche()){selectMitarbeiter.setString (i, this.wc+_Personalnummer+this.wc); i++;}
if(isPC_NameSuche()){selectMitarbeiter.setString (i, this.wc+_PC_Name+this.wc); i++;}
if(isIPSuche()){selectMitarbeiter.setString (i, this.wc+_IP+this.wc); i++;}
if(isTelefonSuche()){ selectMitarbeiter.setString (i, this.wc+_Telefon+this.wc); i++;}
if(isGeburtstagSuche()){selectMitarbeiter.setString (i, this.wc+_Geburtstag+this.wc); i++;}
if(isGruppeSuche()){ selectMitarbeiter.setString (i, this.wc+_Gruppe+this.wc); i++;}
if(isMobilSuche()){ selectMitarbeiter.setString (i, this.wc+_Mobil+this.wc); i++;}
System.out.println(selectMitarbeiter.toString());
ResultSet ergebnis=selectMitarbeiter.executeQuery();`
有:
public String StringModulierung(String str){
boolean erster=true;
if(isNameSuche()){ str=str.concat("Name LIKE ? ");
erster=false;
}
if(isVornameSuche()){ if(erster){str=str.concat("Vorname LIKE ? ");erster=false;
}else{str=str.concat("AND Vorname LIKE ? ");}
}
if(isPersonalnummerSuche()){ if(erster){str=str.concat("Personalnummer LIKE ? ");erster=false;
}else{str=str.concat("AND Personalnummer LIKE ? ");}
}
if(isPC_NameSuche()){ if(erster){str=str.concat("PC_Name LIKE ? ");erster=false;
}else{str=str.concat("AND PC_Name LIKE ? ");}
}
if(isIPSuche()){ if(erster){str=str.concat("IP LIKE ? ");erster=false;
}else{str=str.concat("AND IP LIKE ? ");}
}
if(isTelefonSuche()){ if(erster){str=str.concat("Telefon LIKE ? ");erster=false;
}else{str=str.concat("AND Telefon LIKE ? ");}
}
if(isGeburtstagSuche()){ if(erster){str=str.concat("Geburtstag LIKE ? ");erster=false;
}else{str=str.concat("AND Geburtstag LIKE ? ");}
}
if(isGruppeSuche()){ if(erster){str=str.concat("Gruppe LIKE ? ");erster=false;
}else{str=str.concat("AND Gruppe LIKE ? ");}
}
if(isMobilSuche()){ if(erster){str=str.concat("Mobil LIKE ? ");erster=false;
}else{str=str.concat("AND Mobil LIKE ? ");}
}
return str;
}
这里就是我和JPA完成:
CriteriaBuilder cb = EM.getCriteriaBuilder();
CriteriaQuery<Mitarbeiter2> q = cb.createQuery(Mitarbeiter2.class);
Root<Mitarbeiter2> mit= q.from(Mitarbeiter2.class);
ParameterExpression<String> pc_name = cb.parameter(String.class,"PC_Name_p");
ParameterExpression<String> ip = cb.parameter(String.class,"IP_p");
ParameterExpression<String> pers_num = cb.parameter(String.class,"Personalnummer_p");
ParameterExpression<String> name = cb.parameter(String.class,"Name_p");
ParameterExpression<String> vorname = cb.parameter(String.class,"Vorname_p");
ParameterExpression<String> telefon = cb.parameter(String.class,"Telefon_p");
ParameterExpression<String> geburtstag = cb.parameter(String.class,"Geburtstag_p");
ParameterExpression<String> gruppe = cb.parameter(String.class,"Gruppe_p");
ParameterExpression<String> mobil = cb.parameter(String.class,"Mobil_p");
Predicate p = cb.conjunction();
if(isPC_NameSuche()){
p = cb.and(p, cb.like(pc_name, this.getWc()+_PC_Name+this.getWc()));
}
if(isIPSuche()) {
p = cb.and(p, cb.like(ip,this.getWc()+_IP+this.getWc()));
}
if(isPersonalnummerSuche()) {
p = cb.and(p, cb.like(pers_num, this.getWc()+_Personalnummer+this.getWc()));}
if(isNameSuche()){
p = cb.and(p, cb.like(name, this.getWc()+_Name+this.getWc()));
}
if(isVornameSuche()) {
p = cb.and(p, cb.like(vorname, this.getWc()+_Vorname+this.getWc()));}
if(isTelefonSuche()) {
p = cb.and(p, cb.like(telefon, this.getWc()+_Telefon+this.getWc()));}
if(isGeburtstagSuche()){
p = cb.and(p, cb.like(geburtstag, this.getWc()+_Geburtstag+this.getWc()));}
if(isGruppeSuche()) {
p = cb.and(p, cb.like(gruppe, this.getWc()+_Gruppe+this.getWc()));}
if(isMobilSuche()) {
p = cb.and(p, cb.like(mobil, this.getWc()+_Mobil+this.getWc()));}
q.where(p);
q.select(mit);
TypedQuery<Mitarbeiter2> tq = EM.createQuery(q);
tq.setParameter("PC_Name_p", "PC_Name"); // searches this.getWc()+_Mobil+this.getWc() in PC_Name !
tq.setParameter("IP_p", "IP");
tq.setParameter("Personalnummer_p", "Personalnummer");
tq.setParameter(name/**entered by user*/, "Name"/**should be the field */);
tq.setParameter("Vorname_p", "Vorname");
tq.setParameter("Telefon_p", "Telefon");
tq.setParameter("Geburtstag_p","Geburtstag");
tq.setParameter("Gruppe_p", "Gruppe");
tq.setParameter("Mobil_p" ,"Mobil");
List<Mitarbeiter2> ergebnis= tq.getResultList();
我结合这两个以下解决方案:
为了动态添加where条件,您可以使用一个 列表,其中每个谓词定义如下:
> Predicate p = cb.like(...);
,也可以动态修改单个预测是这样的:
> Predicate p = cb.conjunction(); for (filter : filters) {
> p = cb.and(p, cb.like(...)); }
和
当你q.where您设置的WHERE表达。
它不会追加,意思是说,您调用的最后一个q.是为查询设置的那个 。
你需要做的是建立一个布尔表达式(我认为ANDs是 你想要的)。
然后在和用户q.where设置表达式。
感谢您的帮助;)。
Harald
您在哪里设置您定义的参数的值? – 2012-07-24 11:35:29
Ups,我忘记了。现在我设置了参数,我没有抛出异常,但是如果我在字段中什么也不写,并选择它(isField())是真的,那么我得到我的整个数据库,否则我什么也得不到。我假设我没有正确使用通配符,并且它不被识别。 Mayne有一个更好的方法来使用标准来修改这个动态sql代码。我编辑我的代码。 – user1548451 2012-07-25 08:26:24
如果您多次更改问题的内容,我们如何帮助您?现在我看到你已经实现了我的答案的一半,甚至没有引用它,并且你没有实现另一部分,没有解释原因。 – perissf 2012-07-25 14:49:39