Hibernate(三)

1 多对多操作

1.1 多对多配置

与一对多时操作类似。

  • 创建实体类用户和角色
  • 实体类间相互表示(都用set集合表示)
  • 配置映射关系(基本配置、多对多关系配置)
  • 将映射文件引入核心配置文件中
    各个步骤如下
  1. 创建实体类并相互表示
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;
    }
}
  1. 配置映射文件
<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>
  1. 导入核心配置文件
        <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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,230评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,261评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,089评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,542评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,542评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,544评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,922评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,578评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,816评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,576评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,658评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,359评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,937评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,920评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,859评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,381评论 2 342

推荐阅读更多精彩内容