我正在尝试使用Hibernate来访问我们的权限管理的持久数据,但我对它很陌生并努力获取我需要的数据。
我有一个带有ID和名称的Users表,一个带有ID和名称的Groups表,以及一个User / Groups映射,它只包含链接的组ID和用户ID。
我想要做的是获取给定组成员的所有名称,因此我想要执行的标准SQL查询是:
SELECT
u.NAME
FROM
USERS u
JOIN
GROUP_USERS gu
ON
u.ID = gu.USER_ID
JOIN
GROUPS g
ON
gu.GROUP_ID = g.ID
WHERE
g.NAME = 'test'
但是,尽管有几个小时的观看和演奏,我似乎无法到达任何地方。
我想使用Criteria,因为它们看起来更清晰,所以我的代码如下:
@Override
public final List<String> getGroupMembers(final String groupName) {
@SuppressWarnings("unchecked")
List<User> groupUsers = getHibernateTemplate().execute(new HibernateCallback<List<User>>() {
@Override
public List<User> doInHibernate(Session session) throws HibernateException, SQLException {
Criteria criteria = session.createCriteria(User.class)
.setFetchMode("GroupUsers", FetchMode.JOIN)
.setFetchMode("Group", FetchMode.JOIN)
.add(Restrictions.eq("name", groupName));
return criteria.list();
}
});
List<String> groupUsernames = new ArrayList<String>();
for (User groupUser : groupUsers) {
groupUsernames.add(groupUser.getName());
}
return groupUsernames;
}
但是当我测试它时,结果集是空的,根据日志,执行的查询是这样的:
select this_.ID as M1_4_0_, this_.NAME as M2_4_0_ from USERS this_ where this_.NAME=?
我让Hibernate使用hibernate.hbm2ddl.auto创建表,但后来将其删除,以便表格绝对是hibernate所期望的,但数据没有被清理。
非常感谢任何有关标准的帮助,所以提前感谢!
编辑:我正在使用xml映射文件:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.company">
<class name="com.company.Group" table="GROUPS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
和
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.company">
<class name="com.company.GroupUsers" table="GROUP_USERS">
<composite-id>
<key-many-to-one name="groupId" class = "Group" column="GROUP_ID" />
<key-many-to-one name="userId" class = "User" column="USER_ID" />
</composite-id>
</class>
</hibernate-mapping>
和
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.company">
<class name="com.company.User" table="USERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
</class>
</hibernate-mapping>
答案 0 :(得分:4)
您不需要映射用户组表,只需将用户和组之间的关系定义为多对多关系,请查看this和this有关如何映射多对多关系。
在您的情况下,它看起来像:
<hibernate-mapping package="com.company">
<class name="com.company.User" table="USERS">
<id name="id" column="ID" type="int">
<generator class="identity"/>
</id>
<property name="name" column="NAME" type="java.lang.String" unique="true" not-null="true"/>
<many-to-many name="userGroups"
target-entity="com.company.Group">
<join-table name="YOUR_USER_GROUP_TABLE">
<join-column name="USER_ID" />
<inverse-join-column name="GROUP_ID" />
</join-table>
</many-to-many>
</class>
并使用群组实体中的名称字段过滤您的用户,例如:
Criteria criteria = session.createCriteria(User.class);
criteria.createAlias("userGroups", "usrGrp",CriteriaSpecification.LEFT_JOIN);
criteria.add( Restrictions.eqProperty("usrGrp.name", "test") )
答案 1 :(得分:0)
将对象映射到表的方式不会受益于将Hibernate用作ORM。考虑一个更面向对象的模型,例如:
class Group {
private Set<User> users;
// ...
}
class User {
private Set<Group> groups;
//..
}
所以,你有一个经典的多对多关联。 Here你可以找到一个使用Hibernate进行这种映射的例子。