Hibernate框架之多表查询

1、多表设计(总结)

(1)多表关系
        1)一对一:
            表的设计原则(分表原则):
                优化表的性能
                基于语意化分表     
            一对一的两张表 之间的关系怎么维护?
                主外键
                相同主键值
       2)一对多:
            建表原则:
                在一的一方有主键   主表
                多的一方有与主表的主键相关联外键    从表
        3)多对多
            建表原则:
                两种主表(业务表) 中间存在一张中间表 
                中间表内部维护两个外键
                中间表分为两种:
                    仅仅维护关系的中间表
                    不仅存在维护关系的外键 还有其他业务字段 例如:订单表     订单项表     商品表
(2)多表设计
        1)根据业务设计表模型
        2)分析表的关系:    分方向  看一条(起始表)
        3)一对一设计:     

学生表            学籍表

        4)一对多设计:

客户表        联系人表
百度          张三
jd            李四
google        王武
              赵六
              田七
              孙八

        5)多对多设计(权限5张表):
            1、通过用户名和密码才能登陆
            2、系统有不同的职务
            3、不同的职务可以有不同的权限


            
用户表            职务表(角色表)            权限表(菜单表、功能表)    
            
张三                CEO                        查下自己薪资
李四                CTO                        查看全部人薪资
王武                CFO                        请假
田七                COO                        批假
                    程序员                    查看项目进度
                                              查看项目金额
                                                    
                                                    
     用户角色关系表            角色权限关系表

2、Hibernate一对多的操作

实体类结构:

//客户表:
private long cust_id;//客户编号(主键)
private String cust_name;//客户名称(公司名称)
private String cust_source;//客户信息来源
private String cust_industry;//客户所属行业
private String cust_level;//客户级别
private String cust_phone;//固定电话
private String cust_mobile;//移动电话
private Set<Linkman> linkmanSet = new HashSet<Linkman>();//多的一方集合

//联系人表
private long lkm_id;//'联系人编号(主键)',
private String lkm_name;// '联系人姓名',
private String lkm_gender;//'联系人性别',
private String lkm_phone;//'联系人办公电话',
private String lkm_mobile;//'联系人手机',
private String lkm_email;// '联系人邮箱',
private String lkm_qq;//'联系人qq',
private String lkm_position;// '联系人职位',
private String lkm_memo;//'联系人备注',
//lkm_cust_id` bigint(32) NOT NULL COMMENT '客户id',
private Customer customer;//一的一方对象

配置映射关系:

<!--客户表关系映射-->
<hibernate-mapping>
    <class name="com.itheima.domain.Customer" table="cst_customer">
        <id name="cust_id" column="cust_id">
            <generator class="native"></generator>
        </id>
        <property name="cust_name" column="cust_name"></property>
        <property name="cust_source" column="cust_source"></property>
        <property name="cust_industry" column="cust_industry"></property>
        <property name="cust_level" column="cust_level"></property>
        <property name="cust_phone" column="cust_phone"></property>
        <property name="cust_mobile" column="cust_mobile"></property>

        <!-- 
			配置一对多  一个Customer 对应多个 联系人
			private Set<Linkman> linkmans = new HashSet<>();
			
			Set标签name属性:Set集合的名称     (当前实体使用哪个变量与对方维护关系)
			key标签的column:外键的名称
			one-to-many标签的class:对方的全限定名

            级联保存:在保存一方时 于此同时保存与该方有关系的其他对象
			    cascade="save-update"
		    级联删除:在删除一方时 于此同时删除与该方有关系的另一方
			    cascade="delete"
		    放弃外键维护权
			    inverse="true"
			    inverse直译:反转(反转外键维护权)		该方放弃外键维护权
            查询:延迟加载  lazy="true/false"  
		        查询一的一方 多的一方默认是延迟加载

            结论:
			在开发中 习惯在一的一方配置级联操作(cascade)  在一的一方配置放弃外键维护权
			
		 -->
        <set name="linkmanSet" cascade="save-update,delete" inverse="true">
            <key column="lkm_cust_id"></key>
            <one-to-many class="com.itheima.domain.Linkman"></one-to-many>
        </set>
    </class>
</hibernate-mapping>

<!--联系人表关系映射-->
<hibernate-mapping>
    <class table="cst_linkman" name="com.itheima.domain.Linkman">
        <id name="lkm_id" column="lkm_id">
            <generator class="native"></generator>
        </id>
        <property name="lkm_name" column="lkm_name"></property>
        <property name="lkm_gender" column="lkm_gender"></property>
        <property name="lkm_phone" column="lkm_phone"></property>
        <property name="lkm_mobile" column="lkm_mobile"></property>
        <property name="lkm_email" column="lkm_email"></property>
        <property name="lkm_qq" column="lkm_qq"></property>
        <property name="lkm_position" column="lkm_position"></property>
        <property name="lkm_memo" column="lkm_memo"></property>

        <!-- 
			配置多对一
			private Customer customer;
			
				name:当前实体使用哪个变量与对方维护关系
				class:对方的全限定
				column:外键名称
			
		 -->
        <many-to-one name="customer" column="lkm_cust_id" class="com.itheima.domain.Customer"></many-to-one>
    </class>
</hibernate-mapping>

配置核心参数:

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>

        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <mapping resource="com/itheima/domain/Customer.hbm.xml"/>
        <mapping resource="com/itheima/domain/Linkman.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

测试:

public class OneToManyTets {

    //对象导航查询
    @Test
    public void test3(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();

        Customer customer = session.get(Customer.class, 5l);
        Set<Linkman> linkmanSet = customer.getLinkmanSet();
        for(Linkman linkman : linkmanSet){
            System.out.println(linkman.getLkm_id()+"   "+linkman.getLkm_name());
        }

        //测试导航对象
        Linkman linkman = session.get(Linkman.class, 1l);
        System.out.println("Customer:"+customer.getCust_name());
        System.out.println("Linkman:"+linkman.getLkm_name());

        transaction.commit();
        HibernateUtils.close(session);
    }

    //级联删除
    @Test
    public void test2(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();

        //Linkman linkman = session.get(Linkman.class, 6l);
        //session.delete(linkman);
        Customer customer = session.get(Customer.class, 9l);
        session.delete(customer);

        transaction.commit();
        HibernateUtils.close(session);
    }

    //一对多存储、级联保存
    @Test
    public void test1(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();

        Customer customer = new Customer();
        Linkman linkman1 = new Linkman();
        Linkman linkman2 = new Linkman();
        customer.setCust_name("CF");
        linkman1.setLkm_name("盖比");
        linkman2.setLkm_name("拉伦多");
        //维护关系
        customer.getLinkmanSet().add(linkman1);
        customer.getLinkmanSet().add(linkman2);
        linkman1.setCustomer(customer);
        linkman2.setCustomer(customer);
        //保存
        session.save(customer);
        //session.save(linkman1);
        //session.save(linkman2);

        transaction.commit();
        HibernateUtils.close(session);
    }
}

3、Hibernate多对多的操作

实体类结构

//用户实体类
    private long user_id;//'用户id',
    private String user_code;// '用户账号',
    private String user_name;// '用户名称',
    private String user_password;// '用户密码',
    private String user_state;// '1:正常,0:暂停',
    private Set<Role> roles = new HashSet<Role>();//多对多集合

//角色实体类
    private long role_id;
    private String role_name;//'角色名称',
    private String role_memo;// '备注',
    private Set<User> users = new HashSet<User>();//多对多集合

配置映射关系

<!--用户关系配置-->
<hibernate-mapping>
    <class name="com.itheima.domain.User" table="sys_user">
        <id name="user_id" column="user_id">
            <generator class="native"></generator>
        </id>
        <property name="user_code" column="user_code"></property>
        <property name="user_name" column="user_name"></property>
        <property name="user_password" column="user_password"></property>
        <property name="user_state" column="user_state"></property>

		<!-- 配置多对多 
				name:set集合的名称
				key的column:当前实体在中间表中的外键名称(别人引用我的外键)
				many-to-many的class:对方的全限定名
				many-to-many的column:代表对方的外键名称(我引用别人的外键)
				table:中间表名称
		-->
        <set name="roles" table="sys_user_role" inverse="true">
            <key column="user_id"></key>
            <many-to-many class="com.itheima.domain.Role" column="role_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>


<!--角色关系配置-->
<hibernate-mapping>
    <class name="com.itheima.domain.Role" table="sys_role">
        <id name="role_id" column="role_id">
            <generator class="native"></generator>
        </id>
        <property name="role_name" column="role_name"></property>
        <property name="role_memo" column="role_memo"></property>

        <set name="users" table="sys_user_role">
            <key column="role_id"></key>
            <many-to-many class="com.itheima.domain.User" column="user_id"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

配置核心配置参数

<hibernate-configuration>
    <session-factory>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.connection.password">root</property>

        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <mapping resource="com/itheima/domain/Role.hbm.xml"/>
        <mapping resource="com/itheima/domain/User.hbm.xml"/>
    </session-factory>
</hibernate-configuration>

测试

public class ManyToManyTest {
    @Test
    public void test02(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();

        //给用户添加角色
        User user = session.get(User.class, 9l);
        Role role = session.get(Role.class,13l);
        role.getUsers().add(user);
        session.save(role);

        transaction.commit();
        HibernateUtils.close(session);
    }

    @Test
    public void test01(){
        Session session = HibernateUtils.openSession();
        Transaction transaction = session.beginTransaction();

        //添加用户和角色
        User user01 = new User();
        User user02 = new User();
        Role role01 = new Role();
        Role role02 = new Role();
        user01.setUser_name("魔兽世界");
        user02.setUser_name("LOL");
        role01.setRole_name("摩登莫西");
        role02.setRole_name("路西多亚");
        user01.getRoles().add(role01);
        user02.getRoles().add(role02);
        role01.getUsers().add(user01);
        role02.getUsers().add(user02);
        session.save(role01);
        session.save(role02);
        session.save(user01);
        session.save(user02);

        transaction.commit();
        HibernateUtils.close(session);
    }
}

猜你喜欢

转载自blog.csdn.net/aiyowei1106/article/details/81542918
今日推荐