Java Hibernate:设置多变量搜索的参数和来自其他表的数据
我正在开发一个SpringMVC应用程序,在这个应用程序中,我想用上面提到的一些条件在数据库中搜索。不幸的是,他们大约有10-12人。所以我之前问过一个问题,如何将它们分解成小块,检查其中哪些不是null,并将它们用作参数。通过使用下面提到的StringBuilder,我取得了部分成功 我遇到的问题是如何为非空值设置query.setParameter(“variablename”,variablename)。首先是一个例子:Java Hibernate:设置多变量搜索的参数和来自其他表的数据,java,spring,hibernate,spring-mvc,search,Java,Spring,Hibernate,Spring Mvc,Search,我正在开发一个SpringMVC应用程序,在这个应用程序中,我想用上面提到的一些条件在数据库中搜索。不幸的是,他们大约有10-12人。所以我之前问过一个问题,如何将它们分解成小块,检查其中哪些不是null,并将它们用作参数。通过使用下面提到的StringBuilder,我取得了部分成功 我遇到的问题是如何为非空值设置query.setParameter(“variablename”,variablename)。首先是一个例子: @Override public List<Student&
@Override
public List<Student> addHostSearchHistory(HostSearchHistory hostSearchHistory, Long hostId) {
session = this.sessionFactory.getCurrentSession();
Host host = (Host) session.get(Host.class,hostId);
host.getHostSearchHistorySet().add(hostSearchHistory);
hostSearchHistory.setHsHistory(host);
session.save(hostSearchHistory);
session.flush();
StringBuilder sb = new StringBuilder();
sb.append("from Student as s where ");
if(!(hostSearchHistory.getCountry().equals(""))){
sb.append("s.country=:").append(hostSearchHistory.getCountry());
}
if(!(hostSearchHistory.getCity().equals(""))){
sb.append("OR s.city=:").append(hostSearchHistory.getCity());
}
if(!(hostSearchHistory.getDrivingLicense().equals(""))){
sb.append("OR s.studentDetails.drivingLicense=").append(hostSearchHistory.getDrivingLicense());
}
if(!(hostSearchHistory.getGender().equals(""))){
sb.append("OR s.gender=").append(hostSearchHistory.getGender());
}
if(!(hostSearchHistory.getMotherTongue().equals(""))){
sb.append("OR s.studentDetails.motherTongue=:").append(hostSearchHistory.getMotherTongue());
}
if(!(hostSearchHistory.getSmoker().equals(""))){
sb.append("OR s.studentDetails.smoker=").append(hostSearchHistory.getSmoker());
}
if(!(hostSearchHistory.getPreviousAuPair().equals(""))){
sb.append("OR s.studentDetails.previouslyAuPair=").append(hostSearchHistory.getPreviousAuPair());
}
if(!(hostSearchHistory.getWillingToWork().equals(""))){
sb.append("OR s.studentDetails.willingToWork=").append(hostSearchHistory.getWillingToWork());
}
if(!(hostSearchHistory.getWorkForSingleParent().equals(""))){
sb.append("OR s.studentDetails.workForSingleParent=").append(hostSearchHistory.getWorkForSingleParent());
}
if(!(hostSearchHistory.getWorkingForDisabledChild().equals(""))){
sb.append("OR s.studentDetails.workingForDisabledChild").append(hostSearchHistory.getWorkingForDisabledChild());
}
sb.append(" order by s.registrationDate desc");
Query query = session.createQuery(sb.toString());
if(!(hostSearchHistory.getCountry().equals(""))){
query.setParameter("country",hostSearchHistory.getCountry());
}
if(!(hostSearchHistory.getCity().equals(""))){
query.setParameter("city",hostSearchHistory.getCity());
}
if(!(hostSearchHistory.getDrivingLicense().equals(""))){
query.setParameter("drivingLicense",hostSearchHistory.getDrivingLicense());
}
if(!(hostSearchHistory.getGender().equals(""))){
query.setParameter("gender",hostSearchHistory.getGender());
}
if(!(hostSearchHistory.getMotherTongue().equals(""))){
query.setParameter("motherTongue",hostSearchHistory.getMotherTongue());
}
if(!(hostSearchHistory.getSmoker().equals(""))){
query.setParameter("smoker",hostSearchHistory.getSmoker());
}
if(!(hostSearchHistory.getPreviousAuPair().equals(""))){
query.setParameter("previouslyAuPair",hostSearchHistory.getPreviousAuPair());
}
if(!(hostSearchHistory.getWillingToWork().equals(""))){
query.setParameter("willingToWork",hostSearchHistory.getWillingToWork());
}
if(!(hostSearchHistory.getWorkForSingleParent().equals(""))){
query.setParameter("workForSingleParent",hostSearchHistory.getWorkForSingleParent());
}
if(!(hostSearchHistory.getWorkingForDisabledChild().equals(""))){
query.setParameter("workingForDisabledChild",hostSearchHistory.getWorkingForDisabledChild());
}
List<Student> studentList = query.list();
for(Student student : studentList){
System.out.println("Student name is "+student.getUsername());
}
return studentList;
}
学生信息模型:
@Entity
@Table(name = "studentinfo")
public class StudentInfo {
@Id
@Column(name="infoid")
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator = "student_info_gen")
@SequenceGenerator(name = "student_info_gen",sequenceName = "student_info_seq")
private Long studentInfoId;
@OneToOne
@JoinColumn(name = "studentid",nullable = false)
private Student studentDetails;
public Student getStudentDetails() {
return studentDetails;
}
public void setStudentDetails(Student studentDetails) {
this.studentDetails = studentDetails;
}
}
谢谢你的帮助 这是我项目中的一个示例,我不会建议更好的方法,但会在您的查询中显示一些缺失的点。我也有较长的查询,但编写此查询以保持简单。我使用
CreateQuery
方法:
@Override
public List<CampaignCode> queryCampaignCode(Merchant merchant, PaymentSystemType paymentSystemType, Date now) {
if (merchant == null) {
new IllegalArgumentException("Merchant parameter can not be null!");
}
StringBuilder sb = new StringBuilder();
sb.append("FROM ").append(CampaignCode.class.getName()).append(" WHERE merchant=:merchant");
if (paymentSystemType != null) {
sb.append("AND paymentSystemType=:paymentSystemType ");
}
if (now != null) {
sb.append(" AND :now BETWEEN startDate AND endDate ");
}
//Return current session
Query query = getSession().createQuery(sb.toString());
if (paymentSystemType != null) {
query.setParameter("paymentSystemType", paymentSystemType);
}
if (now != null) {
query.setParameter("now", now);
}
query.setParameter("merchant", merchant);
return query.list();
}
@覆盖
公共列表查询CampaignCode(商户,付款系统类型PaymentSystemType,当前日期){
如果(商户==null){
新的IllegalArgumentException(“商户参数不能为空!”);
}
StringBuilder sb=新的StringBuilder();
sb.append(“FROM”).append(activitycode.class.getName()).append(“其中merchant=:merchant”);
如果(paymentSystemType!=null){
sb.追加(“和paymentSystemType=:paymentSystemType”);
}
如果(现在!=null){
sb.附加(“和:现在介于开始日期和结束日期之间”);
}
//返回当前会话
Query Query=getSession().createQuery(sb.toString());
如果(paymentSystemType!=null){
query.setParameter(“paymentSystemType”,paymentSystemType);
}
如果(现在!=null){
setParameter(“现在”,现在);
}
query.setParameter(“商户”,商户);
返回query.list();
}
merchant
对象,它是一直设置的,所以我在创建sql时没有任何语法错误。在您的示例中,如果用户只设置了国家/地区,则在运行时会出现sql语法异常,请谨慎使用和用法。
String#equals
方法进行检查,如果我的所有参数都是字符串,我始终信任ApacheStringUtils#isBlank
(我的示例不是这样,但在您的示例中,我更喜欢StringUtils#isBlank
)Student.class.getName()
)中获取表名会很好,这样,如果更改了类名,查询就会知道编辑后,如果未设置国家/地区、城市或其他参数,则仍会出现我的第一个场景。我认为您可以通过使用。您只需将所有参数值设置为示例对象(
null
值将被忽略,因此任何null
值都不会包含在生成的SQL中)。它看起来像这样
Student s = new Student();
s.setCountry(hostSearchHistory.getCountry());
s.setCity(hostSearchHistory.getCity());
...
StudentDetails sd = new StudentDetails();
sd.setDrivingLicense(hostSearchHistory.getDrivingLicense());
sd.setSmoker(hostSearchHistory.getSmoker());
...
Criteria crit = session.createCriteria(Student.class);
crit.add(Example.create(s));
crit.createCriteria("studentDetails").add(Example.create(sd));
List<Student> studentList = crit.list();
Student s=新学生();
s、 setCountry(hostSearchHistory.getCountry());
s、 setCity(hostSearchHistory.getCity());
...
StudentDetails sd=新的StudentDetails();
sd.setDrivingLicense(hostSearchHistory.getDrivingLicense());
sd.setSmoker(hostSearchHistory.getSmoker());
...
Criteria crit=session.createCriteria(Student.class);
标准添加(示例创建);
crit.createCriteria(“studentDetails”).add(Example.create(sd));
List studentList=crit.List();
有一些限制,如忽略
id
字段以及关联(否则仅将sd
设置为s
就足够了)。您可以使用Criteria API。你可以在这里找到一个例子:@Faton:我已经编辑了我的主要帖子以包含完整的方法,对吗。对我来说,更重要的是,我是否能以我现有的方式引用一对一实体。非常感谢。声明@OneToOne似乎是正确的。如果以这种方式构建查询,请不要忘记在所有字段都为null/空时处理该情况。@Faton:我是通过检查字符串来实现的。。。是吗?如果所有字符串都是空的,您将得到以下“来自学生as s where order by s.registrationDate desc”。
Student s = new Student();
s.setCountry(hostSearchHistory.getCountry());
s.setCity(hostSearchHistory.getCity());
...
StudentDetails sd = new StudentDetails();
sd.setDrivingLicense(hostSearchHistory.getDrivingLicense());
sd.setSmoker(hostSearchHistory.getSmoker());
...
Criteria crit = session.createCriteria(Student.class);
crit.add(Example.create(s));
crit.createCriteria("studentDetails").add(Example.create(sd));
List<Student> studentList = crit.list();