1 多对多操作
1.1 多对多配置
与一对多时操作类似。
- 创建实体类用户和角色
- 实体类间相互表示(都用set集合表示)
- 配置映射关系(基本配置、多对多关系配置)
- 将映射文件引入核心配置文件中
各个步骤如下
- 创建实体类并相互表示
public class Role {
private Integer roleId;
private String roleName;
private String roleMemo;
private Set<User> userSet = new HashSet<>();
public Set<User> getUserSet() {
return userSet;
}
public void setUserSet(Set<User> userSet) {
this.userSet = userSet;
}
public Integer getRoleId() {
return roleId;
}
public void setRoleId(Integer roleId) {
this.roleId = roleId;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getRoleMemo() {
return roleMemo;
}
public void setRoleMemo(String roleMemo) {
this.roleMemo = roleMemo;
}
}
public class User {
private Integer userId;
private String userName;
private String userPassword;
private Set<Role> roleSet = new HashSet<>();
public Set<Role> getRoleSet() {
return roleSet;
}
public void setRoleSet(Set<Role> roleSet) {
this.roleSet = roleSet;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getUserPassword() {
return userPassword;
}
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
}
- 配置映射文件
<hibernate-mapping>
<class name="User" table="user">
<id name="userId" type="int">
<column name="uid"/>
<generator class="native"/>
</id>
<property name="userName" type="java.lang.String">
<column name="uname"/>
</property>
<property name="userPassword" type="java.lang.String">
<column name="upsw"/>
</property>
<!-- name 为集合名称,table 为第三章表名称,需要和role里的第三张表一致-->
<set name="roleSet" table="user_role">
<!-- 配置当前的映射文件在第三张表中的外键名称-->
<key column="uid"></key>
<!-- class 集合实体类全路径、column为集合实体类在第三张表外键名称-->
<many-to-many class="Role" column="rid"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping>
<class name="Role" table="role">
<id name="roleId" type="int">
<column name="rid"/>
<generator class="native"/>
</id>
<property name="roleName" type="java.lang.String">
<column name="rname"/>
</property>
<property name="roleMemo" type="java.lang.String">
<column name="rmemo"/>
</property>
<set name="userSet" table="user_role">
<key column="rid"> </key>
<many-to-many class="User" column="uid"/>
</set>
</class>
</hibernate-mapping>
- 导入核心配置文件
<mapping resource="user.hbm.xml"/>
<mapping resource="Role.hbm.xml"/>
1.2级联保存
- 同一对多操作,映射文件中添加配置cascade="save-update"
(场景:根据用户保存角色,在用户映射文件中配置)
//建立关系
user1.getRoleSet().add(role1);
user1.getRoleSet().add(role2);
user2.getRoleSet().add(role2);
user2.getRoleSet().add(role3);
//保存用户
session.save(user1);
session.save(user2);
1.3 级联删除
- 同一对多cascade="delete"
<set name="roleSet" table="user_role" cascade="save-update,delete">
<!-- 配置当前的映射文件在第三张表中的外键名称-->
<key column="uid"></key>
<!-- class 集合实体类全路径、column为集合实体类在第三张表外键名称-->
<many-to-many class="Role" column="rid"/>
</set>
User user = session.get(User.class,3);
session.delete(user);
即可删除,但注意,在sql 中做多对多删除应先删除在第三张表中的对应数据。在本例中应该先删除user_role表中uid = 3的数据,再删除user表中uid = 3的数据。
1.4 维护第三张表
- 即假设这样一个场景,uid 为1的用户突然添加一个对应的角色或减少一个对应的角色。
User user = session.get(User.class,1);
Role role = session.get(Role.class,3);
//将rid = 3的变为uid = 1的角色
user.getRoleSet().add(role);
user.getRoleSet().remove(role);
2 Hibernate中各种查询方式
2.1 对象导航查询
- 简单点说就是从对象的集合中把数据取出来就行了。
Customer cus = session.get(Customer.class,1);
Set<Contacter> set = cus.getContacter();
2.2 HQL查询(Hibernate query language)
- 与sql区别在于sql操作表和字段,hql操作类和属性
- 查询表中所有数据
Query query = session.createQuery("from User");
List<User> userList = query.list();
for (User user : userList) {
System.out.println(user.getUserId() + "::" + user.getUserName());
}
- 条件查询
String s= "from User where userId = ? and userName = ?";
Query query = session.createQuery(s);
query.setParameter(0,1);
query.setParameter(1,"jacob");
List<User> userList = query.list();
for (User user : userList) {
System.out.println(user.getUserId() + "::" + user.getUserName());
}
- 模糊条件查询
String s= "from User where userName like ?0";
Query query = session.createQuery(s);
query.setParameter(0,"%o%");
List<User> userList = query.list();
for (User user : userList) {
System.out.println(user.getUserId() + "::" + user.getUserName());
}
- 排序查询
String s= "from User order by userId asc";
Query query = session.createQuery(s);
List<User> userList = query.list();
for (User user : userList) {
System.out.println(user.getUserId() + "::" + user.getUserName());
}
- 分页查询
String s= "from Customer";
Query query = session.createQuery(s);
query.setFirstResult(0);
query.setMaxResults(3);
List<User> userList = query.list();
for (User user : userList) {
System.out.println(user.getUserId() + "::" + user.getUserName());
}
tx.commit();
- 投影查询,注意别使用*号就行。
- 聚合函数的使用
String s= "select count (*) from User";
Query query = session.createQuery(s);
Object obj = query.uniqueResult();
long count = (long) obj;
System.out.println((int)count);
其他的聚合函数类似。
- 多表查询
String s= "from User u inner join u.roleSet";
Query query = session.createQuery(s);
//注意返回的是数组
List<Object[]> list = query.list();
Object[] obj = list.get(0);
if(obj[0] instanceof User){
User user = (User) obj[0];
System.out.println(user.getUserId());
}
想让返回的是对象应该向下面这样
String s= "from User u inner join fetch u.roleSet";
Query query = session.createQuery(s);
//注意返回的是数组
List<Object[]> list = query.list();
Object[] obj = list.get(0);
if(obj[0] instanceof User){
User user = (User) obj[0];
System.out.println(user.getUserId());
}
需要注意左连接时使用的是left outer join