我有一个要求,其中我必须使用Hibernate HQL加入两个不相关的对象。 这是样本POJO类
class Product{
int product_id;
String name;
String description;
}
和
Class Item{
int item_id;
String name;
String description;
int quantity;
int product_id; //Note that there is no composed product object.
}
现在我想执行一个类似的查询 select * from Product p left outer join Item i on p.product_id = i.item_id
我想要一个多维数组作为此查询的输出,这样我就可以拥有Product和Item的单独实例,而不是另一个实例。 在Hibernate中有没有办法做到这一点?
答案 0 :(得分:5)
通过存储关联对象的id而不是关联对象本身来表示对象之间的关联是不常见的。存储对象更具表现力和类型安全性,并且不需要对性能产生影响,因为hibernate具有延迟加载代理。
但是当然你可以在映射文件中加入未映射为关联的东西。引用hibernate reference manual:
可能会出现多个类 在笛卡尔积中或“交叉” 加入。
from Formula, Parameter from Formula as form, Parameter as param
查询可以返回多个对象 和/或作为类型数组的属性 对象[]:
select mother, offspr, mate.name from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
或作为清单:
select new list(mother, offspr, mate.name) from DomesticCat as mother inner join mother.mate as mate left outer join mother.kittens as offspr
或 - 假设班级为家庭 有一个合适的构造函数 - 作为 实际的类型安全Java对象:
select new Family(mother, mate, offspr) from DomesticCat as mother join mother.mate as mate left join mother.kittens as offspr
您可以为选定项指定别名 表达式使用as:
select max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n from Cat cat
这在一起使用时最有用 选择新地图:
select new map( max(bodyWeight) as max, min(bodyWeight) as min, count(*) as n ) from Cat cat
此查询从别名返回Map 选定的值。
将此与简单的where子句相结合,得到:
select product, item
from Product product, Item item
where item.product_id = product.product_id
修改:我错过了您想要外部加入。在这种情况下,我不知道除了映射关联之外的其他方法,因此您可以对其进行普通连接。请注意,这不需要特定形式的查询结果,即您仍然可以执行以下操作:
select product, item
from Item item
left join item.product as product
答案 1 :(得分:3)
有一种解决方法可以在hql here中加入id。
但是,我建议在这里使用本机SQL查询。
答案 2 :(得分:0)
您可以使用subselect
from Product p where p.product_id in (select item_id from Item)
答案 3 :(得分:0)
在select子句中尝试subselect:
forkapp.run(function($ionicPlatform, $rootScope, $firebaseAuth, $firebase, $window, $ionicLoading) {
$ionicPlatform.ready(function() {
// Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
// for form inputs)
var fb = new Firebase("https://glowing-torch-9862.firebaseio.com/");
if (window.cordova && window.cordova.plugins.Keyboard) {
cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
}
if (window.StatusBar) {
StatusBar.styleDefault();
}
$rootScope.userEmail = null;
$rootScope.baseUrl = 'https://glowing-torch-9862.firebaseio.com/';
var authRef = new Firebase($rootScope.baseUrl);
$rootScope.auth = $firebaseAuth(authRef);
$rootScope.show = function(text) {
$rootScope.loading = $ionicLoading.show({
content: text ? text : 'Loading..',
animation: 'fade-in',
showBackdrop: true,
maxWidth: 200,
showDelay: 0
});
};
$rootScope.hide = function() {
$ionicLoading.hide();
};
$rootScope.notify = function(text) {
$rootScope.show(text);
$window.setTimeout(function() {
$rootScope.hide();
}, 1999);
};
$rootScope.logout = function() {
$rootScope.auth.$logout();
$rootScope.checkSession();
};
$rootScope.checkSession = function() {
var auth = new FirebaseSimpleLogin(authRef, function(error, user) {
if (error) {
// no action yet.. redirect to default route
$rootScope.userEmail = null;
$window.location.href = '#/auth/signin';
} else if (user) {
// user authenticated with Firebase
$rootScope.userEmail = user.email;
$window.location.href = ('#/event');
} else {
// user is logged out
$rootScope.userEmail = null;
$window.location.href = '#/auth/signin';
}
});
};
}); //ionic platform ready
})