Логическое ИЛИ между Критерием и Критерием - PullRequest
1 голос
/ 29 января 2012

У меня есть следующие классы моделей:

@Entity
@Table(name = "title")
public final class Title extends ModelData<Title>
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Integer titleID;

    @Column(name = "title")
    private String title;

    @Column(name = "description")
    private String description;

    @OneToMany(cascade = CascadeType.ALL, mappedBy = "title")
    private Set<Book> books;
}

@Entity
@Table(name = "book")
public final class Book extends ModelData<Book>
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "bookID")
    private int bookID;

    @ManyToOne(cascade = CascadeType.PERSIST, fetch = FetchType.EAGER)
    @JoinColumn(name = "titleID")
    private Title title;

    @Column(name = "edition")
    private Integer edition;

    @Column(name = "isbn")
    private String ISBN;
}

Я хочу написать запрос Criteria, эквивалентный следующему SQL;

Select 
        t.title, b.edition 
    from 
        books b, title t
    where 
        b.titleID = t.titleID
    and 
        (b.edition=4 OR t.title LIKE '%Java%);

Я попробовал следующее:

Criteria c = session.createCriteria(Book.class);

Criteria titleCriteria = c.createCriteria("title");
titleCriteria.add(Restrictions.like("title", "%Java%");

Criterion edition = Restrictions.eq("edition", 4);

LogicalExpression orExp = Restrictions.or(edition, titleCriteria); //cannot do this

Как мне достичь вышеуказанного?

Спасибо.

Ответы [ 4 ]

1 голос
/ 08 ноября 2012

Другая идея

Преобразовать ваши критерии в поле формулы и оценивать как нормальные критерии

Добавить поле формулы в файл сопоставления или аннотации к вашим классам

<property name="titlename" type="string"
formula="(Select title.title from title 
    where title.titleID= titleID)"/>

затем

Criteria c = session.createCriteria(Book.class)
Criteria titleCriteria = c.createCriteria("title");
titleCriteria.add(Restrictions.like("titlename", "%Java%");
Criterion edition = Restrictions.eq("edition", 4);
LogicalExpression orExp = Restrictions.or(edition, titleCriteria); //CAN< do this!!!
1 голос
/ 29 января 2012
public class MyDTO {
  private String dtoTitle;
  private String dtoEdition;
  // + setters/getters
}


Criteria c = session.createCriteria(Book.class,"b");
c.createAlias("title", "t");
c.add(
    Restrictions.disjunction()
    .add( Restrictions.like("t.title", "%Java%") )
    .add( Restrictions.eq("b.edition", 4) )
);
c.setProjection( 
    Projections.projectionList()
    .add( Projections.property("t.title"), "dtoTitle" )
    .add( Projections.property("b.edition"), "dtoEdition" )
);
c.setResultTransformer(Transformers.aliasToBean(MyDTO.class));
List<MyDTO> result = (List<MyDTO>)c.list();

Что-то вроде этого должно работать нормально.

На дао, использующем много критериев, вы должны рассмотреть возможность использования статического импорта.

0 голосов
/ 29 января 2012

Для более чем 2 условий ИЛИ удобнее читать:

c.add(
   Restrictions.disjunction()
            .add(Restrictions.eq(...))
            .add(Restrictions.eq(...))
            .add(Restrictions.eq(...))
   )
0 голосов
/ 29 января 2012

Я думаю, ты этого хочешь.Я не проверял его, поэтому могут быть небольшие ошибки, но основная идея верна.

Criteria c = session.createCriteria(Book.class); 
Criterion titleCriterion = Restrictions.like("title.title", "%Java%"); 
Criterion edition = Restrictions.eq("edition", 4); 
c.add( Restrictions.or( edition, titleCriterion ));
...