Câu trả lời:
Đây là đoạn mã hql mà chúng tôi sử dụng. (Tên đã được thay đổi để bảo vệ danh tính)
String queryString = "select distinct f from Foo f inner join foo.bars as b" +
" where f.creationDate >= ? and f.creationDate < ? and b.bar = ?";
return getHibernateTemplate().find(queryString, new Object[] {startDate, endDate, bar});
Cần lưu ý rằng distinct
từ khóa trong HQL không ánh xạ trực tiếp với distinct
từ khóa trong SQL.
Nếu bạn sử dụng distinct
từ khóa trong HQL, thì đôi khi Hibernate sẽ sử dụng distinct
từ khóa SQL, nhưng trong một số trường hợp, nó sẽ sử dụng một biến kết quả để tạo ra các kết quả khác biệt. Ví dụ: khi bạn đang sử dụng một phép nối bên ngoài như thế này:
select distinct o from Order o left join fetch o.lineItems
Không thể lọc ra các bản sao ở cấp SQL trong trường hợp này, vì vậy Hibernate sử dụng a ResultTransformer
để lọc các bản sao sau khi truy vấn SQL đã được thực hiện.
làm điều gì đó như thế này vào lần sau
Criteria crit = (Criteria) session.
createCriteria(SomeClass.class).
setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
List claz = crit.list();
Bạn cũng có thể sử dụng Criteria.DISTINCT_ROOT_ENTITY
với truy vấn Hibernate HQL.
Thí dụ:
Query query = getSession().createQuery("from java_pojo_name");
query.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);
return query.list();
Tôi đã gặp một số vấn đề với máy biến áp kết quả kết hợp với truy vấn HQL. Khi tôi cố gắng
final ResultTransformer trans = new DistinctRootEntityResultTransformer();
qry.setResultTransformer(trans);
nó đã không hoạt động. Tôi đã phải chuyển đổi thủ công như thế này:
final List found = trans.transformList(qry.list());
Với Criteria API, máy biến áp hoạt động tốt.
Truy vấn chính của tôi trông giống như thế này trong mô hình:
@NamedQuery(name = "getAllCentralFinancialAgencyAccountCd",
query = "select distinct i from CentralFinancialAgencyAccountCd i")
Và tôi vẫn không nhận được kết quả mà tôi cho là "khác biệt". Chúng chỉ khác biệt dựa trên tổ hợp khóa chính trên bảng.
Vì vậy, DaoImpl
tôi đã thêm một thay đổi một dòng và cuối cùng nhận được lợi nhuận "khác biệt" mà tôi muốn. Một ví dụ là thay vì nhìn thấy 00 bốn lần, bây giờ tôi chỉ nhìn thấy nó một lần. Đây là mã tôi đã thêm vào DaoImpl
:
@SuppressWarnings("unchecked")
public List<CacheModelBase> getAllCodes() {
Session session = (Session) entityManager.getDelegate();
org.hibernate.Query q = session.getNamedQuery("getAllCentralFinancialAgencyAccountCd");
q.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY); // This is the one line I had to add to make it do a more distinct query.
List<CacheModelBase> codes;
codes = q.list();
return codes;
}
Tôi hy vọng điều này đã giúp! Một lần nữa, điều này có thể chỉ hoạt động nếu bạn đang tuân theo các phương pháp mã hóa triển khai dịch vụ, dao và loại mô hình của dự án.
Giả sử bạn có một Đối tượng khách hàng được ánh xạ tới bảng CUSTOMER_INFORMATION và bạn muốn nhận danh sách Tên khách hàng đầu tiên riêng biệt. Bạn có thể sử dụng đoạn mã dưới đây để làm tương tự.
Query distinctFirstName = session.createQuery("select ci.firstName from Customer ci group by ci.firstName");
Object [] firstNamesRows = distinctFirstName.list();
Tôi hy vọng nó sẽ giúp. Vì vậy, ở đây chúng tôi đang sử dụng nhóm theo thay vì sử dụng từ khóa riêng biệt.
Ngoài ra, trước đây tôi thấy khó sử dụng từ khóa riêng biệt khi tôi muốn áp dụng nó cho nhiều cột. Ví dụ, tôi muốn lấy danh sách firstName riêng biệt, lastName sau đó nhóm theo sẽ đơn giản hoạt động. Tôi đã gặp khó khăn trong việc sử dụng khác biệt trong trường hợp này.
Tôi đã có câu trả lời cho Ngôn ngữ truy vấn ngủ đông để sử dụng các trường Riêng biệt. Bạn có thể sử dụng * CHỌN DISTINCT (TO_CITY) TỪ FLIGHT_ROUTE *. Nếu bạn sử dụng truy vấn SQL , nó sẽ trả về Danh sách chuỗi. Bạn không thể sử dụng nó giá trị trả về bởi Lớp thực thể. Vì vậy, Câu trả lời để giải quyết loại vấn đề đó là sử dụng HQL với SQL .
FROM FLIGHT_ROUTE F WHERE F.ROUTE_ID IN (SELECT SF.ROUTE_ID FROM FLIGHT_ROUTE SF GROUP BY SF.TO_CITY);
Từ câu lệnh truy vấn SQL, nó nhận DISTINCT ROUTE_ID và đầu vào dưới dạng Danh sách. Và truy vấn IN lọc TO_CITY riêng biệt khỏi IN (Danh sách).
Loại trả về là loại thực thể Bean. Vì vậy, bạn có thể thực hiện nó trong AJAX chẳng hạn như AutoComplement .
Có thể tất cả đều ổn
Bạn có thể cho bạn từ khóa riêng biệt trong trình tạo tiêu chí của bạn như thế này.
CriteriaBuilder builder = session.getCriteriaBuilder();
CriteriaQuery<Orders> query = builder.createQuery(Orders.class);
Root<Orders> root = query.from(Orders.class);
query.distinct(true).multiselect(root.get("cust_email").as(String.class));
Và tạo phương thức khởi tạo trường trong lớp mô hình của bạn.
Nếu bạn cần sử dụng từ khóa mới cho DTO tùy chỉnh trong câu lệnh đã chọn của mình và cần các yếu tố khác biệt , hãy sử dụng từ khóa mới bên ngoài mới như sau-
select distinct new com.org.AssetDTO(a.id, a.address, a.status) from Asset as a where ...