• hibernate-第二章-关系映射


    一,持久化类

    持久化类就是之前写过的实体类

    持久化类必须符合javabean规范,属性必须有set和get方法;

    持久化类的属性类型可以是8种基本类型或对应的包装类,通常定义包装类型,因为包装类型可以兼容null(private int id;---------private Integer id)

    在对象关系映射文件(xxx.hbm.xml)中,property元素的access属性来指定访问持久化类属性的方式

      access="field" 表示hibernate通过反射访问属性,可以不写set 和get方法

      access="noop"表示实体类中没有对应的属性,但是数据库有

      access="property" 默认值,表示hibernate通过属性的set 和get 方法访问属性

      对象标识符

    通常来说主键字段取名为"ID"

    主键字段为整形

    主键的set 方法权限设置为private,防止随意修改

    二,主键生成器

    主要负责我们生成数据库表中主键字段的值,通常有下面几种的配置:

    (1):increment

      对int,short,long的数据列生成自动增长主键

    (2):identity

      对SQLserver 和MySql等数据库支持自动增长的数据库

    (3):sequence:

      对Oracle和db2等支持序列的数据库

    (4):uuid

      对字符串采用uuid算法产生一个唯一的字符串主键

    (5):native

      根据底层的数据库支持情况自动选择identity,sequence,适合跨多种数据库的系统

    若要修改主键生成器,需要在xxx.hbm.xml中配置

    <id name="id" type="int">
                <column name="ID" />
                <generator class="native" />
     </id>

    三、1 vs 多

    1、准备数据库和表

    create table dept(

             deptId int not null primary key auto_increment,

             deptName varchar(20) not null

    )                   

    insert into dept values(0,'财务部');

    insert into dept values(0,'开发部');

    insert into dept values(0,'业务部');

    insert into dept values(0,'产品部');

    create table emp(

             empId int not null primary key auto_increment,

             deptId int references  dept(deptId),

             empNo char(4) not null unique,

             empName varchar(20) not null,

             empSex int not null,

             empBirth date not null

    )

    insert into emp values(0,1,'E001','小明',0,'2010-10-10');

    insert into emp values(0,1,'E002','小红',0,'2011-10-11');

    insert into emp values(0,2,'E100','小芳',1,'2012-10-12');

    insert into emp values(0,2,'E101','小王',1,'2013-10-13');

    insert into emp values(0,3,'E200','小李',1,'2014-10-14');

    insert into emp values(0,3,'E201','小赵',0,'2015-10-15');

    2、创建maven项目

    <!-- MySQL数据库驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.2</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-core</artifactId>
            <version>5.2.17.Final</version>
        </dependency>

    3、实体类

    @Setter
    @Getter
    public class Dept {
        private Integer deptId;//主键
        private String deptName;//部门名称
    }
    @Setter
    @Getter
    public class Emp {
        private Integer empId; //主键
        private Integer deptId; //部门外键
        private String empNo;//员工编号
        private String empName;//员工姓名
        private Integer empSex;//员工性别
        private String empBirth;//员工生日
    }

    4、hibernate.cfg.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="hibernate.connection.password">123456</property>
            <property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/hibernate-test?characterEncoding=utf-8</property>
            <property name="hibernate.connection.username">root</property>
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            
            <!-- 是否显示SQL语句   true-显示 -->
            <property name="hibernate.show_sql">true</property>
        </session-factory>
    </hibernate-configuration>

    5、xxx.bhm.xml

    Dept.hbm.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>
        <class name="com.yujun.maven.po.Dept" table="dept">
            <id name="deptId" type="int">
                <column name="deptId" />
                <generator class="native" />
            </id>
            <property name="deptName" type="java.lang.String">
                <column name="deptName" />
            </property>
            
            <!-- set就是用来配置集合属性   name:实体类中属性名 -->
            <set name="emps">
                <!-- key用来配置外键     column:外键字段名-->
                <key>
                    <column name="deptId"></column>
                </key>
                <!-- 1-多    class:配置的set集合的泛型-->
                <one-to-many class="com.yujun.maven.po.Emp"/>
            </set>
        </class>
    </hibernate-mapping>

    Emp.hbm.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>
        <class name="com.yujun.maven.po.Emp" table="emp">
            <id name="empId" type="int">
                <column name="empId" />
                <generator class="native" />
            </id>
            <property name="empNo" type="java.lang.String">
                <column name="empNo" />
            </property>
            <property name="empName" type="java.lang.String">
                <column name="empName" />
            </property>
            <property name="empSex" type="int">
                <column name="empSex" />
            </property>
            <property name="empBirth" type="java.lang.String">
                <column name="empBirth" />
            </property>
            
            <!-- 多-1    name:实体类中的属性名    class:属性对应的类 -->
            <many-to-one name="dept" class="com.yujun.maven.po.Dept">
                <!-- 外键字段 -->
                <column name="deptId"></column>
            </many-to-one>
        </class>
    </hibernate-mapping>

    6、加载映射文件

    在hibernate.cfg.xml中

    <mapping resource="com/yujun/maven/po/Dept.hbm.xml"/>
    <mapping resource="com/yujun/maven/po/Emp.hbm.xml"/>

    7、查询部门获取部门的所有员工

    public class Demo1 {
    
        public static void main(String[] args) {
            // 1配置对象
            Configuration config = new Configuration().configure();
            // 2会话工厂
            SessionFactory factory = config.buildSessionFactory();
            // 3会话对象
            Session session = factory.openSession();
    
            //查询一个部门
            Dept dept = session.get(Dept.class, 1);//立即发送SQL语句去数据库中查询
            System.out.println(dept);
            
            //获取dept对象中所有员工信息
            Set<Emp> emps = dept.getEmps(); //默认使用延迟加载(懒加载)
            System.out.println("1-----------------------------");
            emps.forEach(System.out::println);
            
            // 关闭
            session.close();
            System.exit(0);
        }
    
    }

    8、查询员工获取部门

    public class Demo2 {
    
        public static void main(String[] args) {
            // 1配置对象
            Configuration config = new Configuration().configure();
            // 2会话工厂
            SessionFactory factory = config.buildSessionFactory();
            // 3会话对象
            Session session = factory.openSession();
    
            //查询一个员工
            Emp emp = session.get(Emp.class, 2);
            System.out.println(emp);
            
            //这个员工的部门
            Dept dept = emp.getDept(); //默认是延迟加载
            System.out.println(dept);
            // 关闭
            session.close();
            System.exit(0);
        }
    
    }

    四、级联操作和控制权

    操作一个对象,会一并操作被关联的对象

    比如:删除一个部门,顺带给把此部门下的所有员工删除;

    增删改、这里我们只讲解级联删除;

    先删除从表,再删主表(推荐)

    级联操作:cascade告知hibernate对于关联的对象应该如何操作,取值:none、save-update、delete、all,默认是none-无级联操作,双方都可以配置级联操作

    控制权:inverse告知hibernate对于外键的维护由谁来取得控制权;取值:true、false;

    false表示控制权在己方,true-表示控制权在对方。

    对于1-多关系,我们把控制权交给多的一方,也就是需要我们在1方的set节点中配置:inverse="true"

    通常我们不需要配置级联操作,太危险;默认就好

    dept.hbm.xml

    <!-- set就是用来配置集合属性   name:实体类中属性名       cascade="delete"表示级联删除员工-->
            <!-- inverse="true"表示控制权,控制权控制外键由谁维护,默认是false,false-控制权在己方      true-控制权在对方 -->
            <set name="emps" cascade="delete" inverse="true">
                <!-- key用来配置外键     column:外键字段名-->
                <key>
                    <column name="deptId"></column>
                </key>
                <!-- 1-多    class:配置的set集合的泛型-->
                <one-to-many class="com.yujun.maven.po.Emp"/>
            </set>
    public class Demo3 {
    
        public static void main(String[] args) {
            // 1配置对象
            Configuration config = new Configuration().configure();
            // 2会话工厂
            SessionFactory factory = config.buildSessionFactory();
            // 3会话对象
            Session session = factory.openSession();
            //4事务
            Transaction tran = session.beginTransaction();
            
            //查询一个部门
            Dept dept = session.get(Dept.class, 2);
            //删除部门
            session.delete(dept);
            //如果设置了级联删除,那么先删除部门对应的员工,再删除部门
            //如果没有设置级联删除,那么只会删除部门,员工表的deptID字段数据被设置为null
            tran.commit();
            // 关闭
            session.close();
            System.exit(0);
        }
    
    }

    五、多-多

    1、数据库和表

    -- 学生表
    create table student(
        stuId int not null primary key auto_increment,
        stuName varchar(20) not null
    )
    -- 课程表
    create table course(
        couId int not null primary key auto_increment,
        couName varchar(20) not null
    )
    -- 选课表
    create table xuanke(
        xkId int not null primary key auto_increment,
        studentId int references student(stuId),
        courseId int references course(couId)
    )
    insert into student value(0,'小二');
    insert into student value(0,'小三');
    insert into course values(0,'Struts2');
    insert into course values(0,'Hibernate');
    insert into course values(0,'Spring');
    insert into xuanke values(0,1,1);
    insert into xuanke values(0,1,2);
    insert into xuanke values(0,2,1);
    insert into xuanke values(0,2,2);
    insert into xuanke values(0,2,3);

    2、实体类

    @Setter
    @Getter
    public class Course {
        private Integer couId;
        private String couName;
        private Set<Student> stus; //多个学生
        
        
        @Override
        public String toString() {
            return "Course [couId=" + couId + ", couName=" + couName + "]";
        }
    }
    @Setter
    @Getter
    public class Student {
        private Integer stuId;
        private String stuName;
        private Set<Course> cous; //多门课程
        
        @Override
        public String toString() {
            return "Student [stuId=" + stuId + ", stuName=" + stuName + "]";
        }
        
    }

    3、xxx.hbm.xml

    student.hbm.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>
        <class name="com.yujun.maven.po.Student" table="student">
            <id name="stuId" type="int">
                <column name="stuId" />
                <generator class="native" />
            </id>
            <property name="stuName" type="java.lang.String">
                <column name="stuName" />
            </property>
            
            <!-- table:表示管理的第三方的表名 -->
            <set name="cous" table="xuanke">
                <!-- 此表在第三方表中的外键字段 -->
                <key>
                    <column name="studentId"></column>
                </key>
                <!-- 多-多   column:第三方表中的外键-->
                <many-to-many column="courseId" class="com.yujun.maven.po.Course"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>

    course.hbm.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>
        <class name="com.yujun.maven.po.Course" table="course">
            <id name="couId" type="int">
                <column name="couId" />
                <generator class="native" />
            </id>
            <property name="couName" type="java.lang.String">
                <column name="couName" />
            </property>
            
            <!-- table:表示管理的第三方的表名 -->
            <set name="stus" table="xuanke">
                <!-- 此表在第三方表中外键字段 -->
                <key>
                    <column name="courseId"></column>
                </key>
                <!-- 多-多   column:第三方表中的外键-->
                <many-to-many column="studentId" class="com.yujun.maven.po.Student"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>

    需要再hibernate.cfg.xml中引用映射文件

    <mapping resource="com/yujun/maven/po/Student.hbm.xml"/>
    <mapping resource="com/yujun/maven/po/Course.hbm.xml"/>

    4、查询案例

    根据一个学生,查询相应的选课

    public class Demo4 {
    
        public static void main(String[] args) {
            // 1配置对象
            Configuration config = new Configuration().configure();
            // 2会话工厂
            SessionFactory factory = config.buildSessionFactory();
            // 3会话对象
            Session session = factory.openSession();
    
            //查询一个学生
            Student student = session.get(Student.class, 2);
            System.out.println(student);
            
            //查询这个学生的所选的课程
            Set<Course> cous = student.getCous();
            cous.forEach(System.out::println);
            
            // 关闭
            session.close();
            System.exit(0);
        }
    
    }

    六、1 - 1

    1-1的关系,在实际开发中不是特别多,若要使用1-1关系映射,可以在双方的xxx.hbm.xml中使用<one-to-one/>进行配置

  • 相关阅读:
    C# 中实现累加校验和计算
    勇哥发布的B站视频,包含视觉、运动控制、机器人、C#开发,干货满满,推荐搞工控行业的朋友观看
    Windows Server 2012无法安装 .NET3.5安装角色或功能失败,找不到源文件
    cdh6.3 hive2.1.1升级hive2.3.8
    年少轻狂诗——送给所有年轻人和中年人
    git提交到代码到远程仓库,合并分支提示entirely different commit histories(备忘)
    工作日统计工具(python)
    ansible优质 网站
    Django生产环境静态资源404问题
    基于ansible二次开发
  • 原文地址:https://www.cnblogs.com/faded8679/p/10776243.html
Copyright © 2020-2023  润新知