精华内容
下载资源
问答
  • 对象关系与实体关系映射
    千次阅读
    2021-01-19 07:02:29

    bitsCN.com

    mysql数据库对象关系映射

    1.对“对象关系映射”的理解

    a.对象:可以理解为java中的类

    b.关系:可以理解为数据库的表

    c.映射:这是因为java中的数据的类型与数据库的数据类型是有些不同的,如何将java中的类型的数据用数据库中的数据类型来存储起来,这就映射。

    同时,还有当java中的两个对象之间是有关系的,那么在存储在数据库中时,也需要用一种方式来体现出这种存在的关系,而不能是两个

    不相关的两张表,这也需要映射出来这种关系。

    2.表与表之间的关系类型可以分为以下四种:

    多对一,一对多,多对多,一对一

    3.分别对这四处种关系进行示例说明

    a.多对一(一对多和多对一,其实是看的角度不同,实际上可以看成同一种)员工与部门之间的关系

    有以下两个java对象:

    对象类:

    [java] Department int id; String name; Set employees=new HashSet(); Employee int id; String name; Department dept;

    员工与部门,这两者是典的多对一的关系,多个员工可以属于同一个部门,一个部门中可以有多个员工。

    注意:在实际开发时,如果要设计一个员工管理系统,那么在进行对象实体类的设计时,就是按照上面

    设计方式来设计员工类和部门类。在员工 类中有一个Department dept属性,而没有直接用int dept_no,

    因为样更加符面象对象的设计思想。

    对应的数据库的表为:

    [sql] create department( id int primary key, name varchar(20) ); [sql] create employee( id int primary key, name varchar(20), dept_id int, constraint dept_id_FK foreign key(dept_id) references department(id) );

    注:两个表之间的关系,多对一,用外键来体现。一般外键的应该放在多的一方,在这里也就是放在employee员工表中。

    b.多对多的关系 学生与老师之间的关系

    java类对象:

    [java] Teacher int id; String name; Set students=new HashSet(); Student int id; String name; Set teachers=new HashSet();

    对应的数据库中的表:

    [sql] create table teacher( id int primary key, name varchar(20) ); create table student( id int primary key, name varchar(20) );

    注:对于多对多的关系,应该创建第三张表来保存两张表的映射关系

    [sql] create table student_teacher( student_id int, teacher_id int, constraint student_teacher_PK primary key(student_id,teacher_id), constraint student_id_FK foreign key(student_id) references student(id), constraint teacher_id_FK foreign key(teacher_id) references teacher(id) );

    第三张中的主键是以前两张表的主键作为复合主键,并分别以两张表的主键作为外键。

    c.一对一的关系 人与身份证之间的关系

    java类对象:

    [java] Person int id; String name; IdCard ic; IdCard int id; String address;

    对应的数据库表为:

    [sql] create table person( id int primary key, name varchar(20) ); create table idcard( id int primary key, address varchar(40), constraint id_FK foreign key(id) references person(id) );

    注:对于一对一关系的两张表,分主表与从表,从表的存在必须依赖于主

    表,主表可以不依赖于从表。从表的设计上其主键字段同时也是外键字段。

    备注:有时在设计表时,会特意把两张表合在一张表中,虽然会造成

    数据冗余,但是却可以不因为联表查询而造成查询性能有所降低。这是用

    空间来换时间的做法。

    bitsCN.com

    本条技术文章来源于互联网,如果无意侵犯您的权益请点击此处反馈版权投诉

    本文系统来源:php中文网

    更多相关内容
  • MongoDB、Java与对象关系映射 MongoDB、Java与对象关系映射
  • Mybatis对象关系映射

    千次阅读 2022-02-24 21:55:40
    MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。 2、Mybaits的工作原理 Mybatis通过SqlSessionFactoryBuilder来读取...

    1、什么是Mybatis

    MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。

    2、Mybaits的工作原理

    Mybatis通过SqlSessionFactoryBuilder来读取mybatis-config.xml配置文件从而创建SqlSessionFactory工厂类,SqlSessionFactory通过openSession方法来获取sqlSession,然后sqlSession通过getMapper来获取接口中的所有执行sql语句的方法。

    image-20211220164159345

    3、Mybatis优缺点

    优点:

    • 简单、易上手
    • sql语句都写在xml文件里,便于统一管理
    • 提供xml标签,支持编写动态sql

    缺点:

    • 多张表进行查询的话,很考验程序员的sql能力
    • 对sql语句依赖程序很高,移植到其他数据库很麻烦
    • 拼接sql语句复杂,代码灵活性不高

    Mybatis多对一、一对多处理

    在数据库中可能会存在多对一的关系,比如说多个学生是一个班级、多个标签对一篇博客、多个学生对一个班主任等等。我们通常情况下创建的实体类中的属性是跟数据库里面的字段相对应,在一对多的环境下,实体类中的一个属性可以指向一个对象,然后通过Mybatis的ResultMap结果集映射,将相关联的表中的数据查找到后赋值给该属性,从而实现多对一的效果。

    搭建环境

    • 首先创建一个学生类和一个班级类,学生类里面有id、姓名、班级信息属性,班级类里面有班级id、班级名称、年级属性。

    ( 这里偷个懒,用lombok插件,添加依赖,通过注解添加构造器的方法 )

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Student {
        private int sid;
        private String name;
        private Class studentClass;
    }
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Class {
        private int cid;
        private String cname;
        private String grade;
    }
    
    • 接着我们创建一个db.properties配置文件来配置数据库连接信息 ( 数据库换成自己对应的数据库,密码不同也需要修改 )
    driver=com.mysql.cj.jdbc.Driver
    url=jdbc:mysql://localhost:3306/mybatis?useUnicode=true&&characterEncoding=UTF-8&&useSSL=false&&serverTimezone=UTC
    username=root
    password=12345678
    
    • 创建Mybatis-config.xml配置文件,添加我们需要的配置 ( 这边没有添加log4j的依赖,所以注释掉了 )
    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <!--核心配置文件-->
    <configuration>
        <!--
            properties:加载对应的配置文件
            settings:配置Mybatis的一些设置,如:log4j日志信息等
            typeAliases:扫描对应包下面的实体类,在xml文件中用小写表示就好
            environments:配置数据库环境,可以配置多个,最后生效的为default
            transactionManager:声明事物管理器
            mappers:扫描对应包下面的mapper.xml文件
        -->
        <properties resource="db.properties" />
    
    <!--    <settings>-->
    <!--        <setting name="logImpl" value="LOG4J"/>-->
    <!--        <setting name="cacheEnabled" value="true"/>-->
    <!--    </settings>-->
    
        <typeAliases>
            <package name="com.zhu.pojo" />
        </typeAliases>
    
        <!--环境-->
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC"/>
                <dataSource type="POOLED">
                    <property name="driver" value="${driver}"/>
                    <property name="url" value="${url}"/>
                    <property name="username" value="${username}"/>
                    <property name="password" value="${password}"/>
                </dataSource>
            </environment>
        </environments>
    
        <mappers>
            <package name="com.zhu.mapper" />
        </mappers>
    </configuration>
    
    • 创建MybatisUtils工具类,用于返回所需的SqlSession对象
    public class MybatisUtils {
    
        private static SqlSessionFactory sqlSessionFactory;
    
        static {
            try {
                String resources = "mybatis-config.xml";
                InputStream in = Resources.getResourceAsStream(resources);
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    
        public static SqlSession getSqlSession(){
            return sqlSessionFactory.openSession();
        }
    }
    
    • 创建StudentMapper和ClassMapper接口,因为Mybatis提供面向接口编程,所以我们可以通过方法将查询到的数据返回出来
    public interface StudentMapper {
    
        //查找所有学生信息
        List<Student> getStudent();
    }
    
    public interface ClassMapper {
    
        //查询所有班级信息
        List<Class> getStudentClass(@Param("cid") int cid);
    }
    

    实现Mybatis多对一

    • 创建StudentMapper.xml文件,用来实现接口的方法

    方法一: 按照查询嵌套处理

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--核心配置文件-->
    <!--映射到对应的接口上-->
    <mapper namespace="com.zhu.mapper.StudentMapper">
    
        <select id="getStudent" resultMap="getSClass">
            select * from student;
        </select>
    
        <select id="getStudentClass" resultType="class">
            select * from class where cid = #{cid}
        </select>
        
        <!--
        property指的是实体类里面的属性名
        column指的是要查询的字段
        javaType表示实体类中属性的类型
        select表示查询的方法
    	association:表示实体类对象,常用于多对一
        这句话的意思就是根据学生的cid来查询对应的班级信息
    	-->
        <resultMap id="getSClass" type="student">
            <association property="studentClass" column="cid" javaType="Class" select="getStudentClass" />
        </resultMap>
                
    </mapper>
    

    方法二: 按照结果嵌套处理

    <mapper namespace="com.zhu.mapper.StudentMapper">
    
        <select id="getStudent" resultMap="getSClass">
            select a.*,b.* from student a,class b where a.cid=b.cid
        </select>
    
        <resultMap id="getSClass" type="student">
            <result property="sid" column="sid" />
            <result property="name" column="name" />
            <association property="studentClass" javaType="class">
                <result property="cid" column="cid" />
                <result property="cname" column="cname" />
                <result property="grade" column="grade" />
            </association>
        </resultMap>
                
    </mapper>
    

    测试代码:

    public class TestMapper {
        public static void main(String[] args) {
            //通过工具类获取SqlSession
            SqlSession sqlSession = MybatisUtils.getSqlSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.getStudent();
            for (Student student:students){
                System.out.println(student);
            }
        }
    }
    

    测试结果:

    image-20211220201910000

    实现Mybatis一对多

    将刚刚的实体类反过来一下,意思是一个班级对应多个学生、一个博客对应多个标签,一个班主任对应多个学生等等,将学生看作是一个集合,每个老师都有对应学生集合,也是通过Mybatis的ResultMap结果集映射,从而实现一对多的效果。

    • 更改之前的学生类和班级类,学生类有id、姓名、班级id属性,班级类有班级id,班级名称、年级、学生列表属性
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Student {
        private int sid;
        private String name;
        private int cid;
    }
    
    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    @ToString
    public class Class {
        private int cid;
        private String cname;
        private String grade;
        private List<Student> students;
    }
    
    • 更改之前的Mapper接口文件中的方法,并且创建一个ClassMapper.xml配置文件,用来实现ClassMapper接口中的方法
    public interface StudentMapper {
    
        //查找所有学生信息
        List<Student> getStudent(@Param("cid") int cid);
    }
    
    public interface ClassMapper {
    
        //查询所有班级信息
        List<Class> getStudentClass();
    }
    

    方法一: 按照查询嵌套处理

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <!--核心配置文件-->
    <mapper namespace="com.zhu.mapper.ClassMapper">
    
            <select id="getStudent" resultType="student">
                select * from student where cid = #{cid}
            </select>
    
            <select id="getStudentClass" resultMap="StudentClass">
                select * from class
            </select>
    
            <!--
                collection:表示集合类对象,常用于一对多
                ofType:表示返回的集合里面的泛型
                这段sql语句的意思是通过查询出来的cid来查找对应班级的学生信息
            -->
            <resultMap id="StudentClass" type="class">
                <collection property="students" javaType="ArrayList" ofType="student" column="cid" select="getStudent" />
            </resultMap>
                
    </mapper>
    

    方法二: 按照结果嵌套查询

    <mapper namespace="com.zhu.mapper.ClassMapper">
    
        <select id="getStudentClass" resultMap="StudentClass">
            select a.*,b.* from student a,class b where a.cid=b.cid;
        </select>
    
        <resultMap id="StudentClass" type="class">
            <result property="cid" column="cid" />
            <result property="cname" column="cname" />
            <result property="grade" column="grade" />
            <collection property="students" ofType="student">
                <result property="sid" column="sid" />
                <result property="name" column="name" />
                <result property="cid" column="cid" />
            </collection>
        </resultMap>
                
    </mapper>
    

    将测试类里面的getMapper里面的参数变成ClassMapper.class,然后修改返回值,运行代码

    测试结果:

    image-20211220204604859

    多对多的处理其实也跟上面类似,可以看作是两个一对多,分别再两个实体类里面创建对应的集合或者实体类用于指向对方,然后分别再自己的Mapper.xml配置文件中实现两个一对多的处理即可,快结合上面的应用去实现一下吧!!!

    展开全文
  • 对象关系映射(ORM)介绍理解

    千次阅读 2021-06-16 20:19:40
    执行sql语句(sql中,如果有占位符,在执行sql语句前要替换,会使用很多字段来替换占位符(一般包装成一个对象,通过对象属性来操作)) 处理结果集(查询操作)----通过结果集对象.get类型(”结果集表头字段名“)...

    问题背景

    假设,让你设计一个框架,把jdbc封装一下??
    JDBC操作步骤:

    1. 获取数据库连接Connection
    2. 创建操作命令对象Statement
    3. 执行sql语句(sql中,如果有占位符,在执行sql语句前要替换,会使用很多字段来替换占位符(一般包装成一个对象,通过对象属性来操作))
    4. 处理结果集(查询操作)----通过结果集对象.get类型(”结果集表头字段名“),设置到一个对象属性之中
    5. 释放资源

    那么??使用JDBC操作是否方便呢?那么也就需要设计一个框架,来更好地操作数据库!!!

    ORM是什么?为何要有ORM?

    我们在使用Django框架开发web应用的过程中,不可避免地会涉及到数据的管理操作(增、删、改、查),而一旦谈到数据的管理操作,就需要用到数据库管理软件,例如mysql、oracle、Microsoft SQL Server等。

    在这里插入图片描述
    如果应用程序需要操作数据(比如将用户注册信息永久存放起来),那么我们需要在应用程序中编写原生sql语句,然后使用pymysql模块远程操作mysql数据库。

    在这里插入图片描述
    针对应用程序的数据操作,直接编写原生sql语句会存在两方面的问题,严重影响开发效率,如下:

    • sql语句的执行效率问题:应用开发程序员需要耗费一大部分精力去优化sql语句
    • 数据库迁移问题:针对mysql开发的sql语句无法直接应用到oracle数据库上,一旦需要迁移数据库,便需要考虑跨平台问题

    为了解决上述问题,django引入了ORM的概念,ORM全称Object Relational Mapping,即对象关系映射,是在pymysq之上又进行了一层封装,对于数据的操作,我们无需再去编写原生sql,取代代之的是基于面向对象的思想去编写类、对象、调用相应的方法等,ORM会将其转换/映射成原生SQL然后交给pymysql执行

    在这里插入图片描述
    基于图2所示,有了ORM框架,开发人员既不用再去考虑原生SQL的优化问题,也不用考虑数据库迁移的问题,ORM都帮我们做了优化且支持多种数据库,这极大地提升了我们的开发效率。

    简单说,ORM 就是通过实例对象的语法,完成关系型数据库的操作的技术,是"对象-关系映射"(Object/Relational Mapping) 的缩写。ORM 把数据库映射成对象。

    数据库的表(table) --> 类(class)
    记录(record,行数据)--> 对象(object)
    字段(field)--> 对象的属性(attribute)
    

    数据库设计表和字段时,也是同时设计java的实体类。
    在这里插入图片描述

    示例理解

    这是一行sql语句:

    select id, first_name, last_name, phone, birth_date, sex from persons where id = 10;
    

    程序直接运行sql,操作数据库的写法如下:

    res = db.execSql(sql);
    name = res[0]["first_name"];
    

    使用 ORM的写法:

    p = Person.get(10);
    name = p.first_name;
    

    一比较就可以发现,ORM 使用对象,封装了数据库操作,因此可以不碰 SQL 语言。开发者只使用面向对象编程,与数据对象直接交互,不用关心底层数据库。

    ORM 优点

    • 数据模型都在一个地方定义,更容易更新和维护,也利于重用代码。
    • ORM 有现成的工具,很多功能都可以自动完成,比如数据消毒、预处理、事务等等。
    • 它迫使你使用 MVC 架构,ORM 就是天然的 Model,最终使代码更清晰。
    • 基于 ORM 的业务代码比较简单,代码量少,语义性好,容易理解。
    • 你不必编写性能不佳的 SQL。

    ORM 缺点

    • ORM 库不是轻量级工具,需要花很多精力学习和设置。
    • 对于复杂的查询,ORM 要么是无法表达,要么是性能不如原生的 SQL。
    • ORM 抽象掉了数据库层,开发者无法了解底层的数据库操作,也无法定制一些特殊的 SQL。

    参考链接:
    ORM 实例教程

    ORM介绍

    展开全文
  • Hibernate实体关联关系映射

    千次阅读 2018-08-03 10:52:40
     简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射。  它将数据库中的表映射成对应的对象,以对象的形式展现,这样我们就可以通过映射的对象来对数据库中的数据...

    一、什么是Hibernate中的关联映射?

      简单来说Hibernate是ORM映射的持久层框架,全称是(Object Relational Mapping),即对象关系映射。

      它将数据库中的表映射成对应的对象,以对象的形式展现,这样我们就可以通过映射的对象来对数据库中的数据进行间接的操作。

      关联映射是将数据库中的表映射成与之相对应的对象,当你对这个对象进行操作的时候,Hibernate会对数据库中对应的表执行相应的操作,你对该实体的操作实际上就是在间接的操作数据库中与之相对应的表。

      Hibernate正是实现了这种思想,达到了方便开发人员以面向对象的思想来实现对数据库的操作。 

    二、Hibernate主要实现的映射关系:

            

     

    三、Hibernate映射的基本结构

        hibernate在实现ORM功能的时候主要用到的文件有:映射类(*.Java)、映射文件(*.hbm.xml)和数据库配置文件(*.properties/*.cfg.xml),它们各自的作用如下。

            映射类(*.java):它是描述数据库表的结构,表中的字段在类中被描述成属性,将来就可以实现把表中的记录映射成为该类的对象了。

            映射文件(*.hbm.xml):它是指定数据库表和映射类之间的关系,包括映射类和数据库表的对应关系、表字段和类属性类型的对应关系以及表字段和类属性名称的对应关系等。

            数据库配置文件(*.properties/*.cfg.xml):它是指定与数据库连接时需要的连接信息,比如连接哪种数据库、登录数据库的用户名、登录密码以及连接字符串等。当然还可以把映射类的地址映射信息放在这里。

     

    四、hibernate中的关联关系有四种:一对一、一对多、多对一、多对多。

     

    1、单向关联与双向关联

     单向关联:单向关联是指只有一方有另一方的关联信息而另一方没有关联信息                    

      

        A——>B  

        A对象中有B对象的关联信息

        B对象中没有A对象的关联信息

        我们可以通过A对象中B的关联信息查询或修改B对象的信息但无法通过B对象来查询修改A对象的信息

     双向关联:双向关联是指两方都有另一方的关联信息

      

        A<——>B

        A对象中有B对象的关联信息

        B对象中也有A对象的关联信息

        我们可以通过A对象中B的关联信息查询或修改B对象的信息也可以通过B对象来查询修改A对象的信息

     

    单向关联一般在一方配置多方不进行配置

      如:一对多 单向关联在“一”的一方配置文件里进行配置,"多"的一方不进行配置

    双向关联两方都要配置

      如:一对多 双向关联在“一”的一方配置文件里需要配置,“多”的一方也需要进行配置

     

    2、一对一关联映射

      一对一关联:一对一是指一个对象对应一个对象  如:一个人只有一个身份证。

      在两个数据表之间的一对一关系可以有两种实现方法,其中一种就是通过两个表的主键相关联,另一种是通过外键相关联

        如:一个人(Person)对应一个地址(Address)代码如下。

     (1)一对一主键单向关联: 

        Person——>Address

    public class Person {
        private int personid;
        private String name;
        private int age;
        //在Person对象中有Address对象的关联信息
        private Address address;
     
    public class Address{
        //Address对象中没有Person对象的关联信息
        private int addressid;
        private String addressdetail;

    这种单方面有另一个对象的关联信息的时候我们称为单向关联,再来看一下两个表中的映射hbm.xml文件:

    Person.hbm.xml

    <hibernate-mapping>
        <class name="com.entity.Person" table="PERSON">
            <id name="personid" column="presonid">
                <!--基于主键关联时,主键生成策略是foreign,表明根据关联类生成主键-->
                <generator class="foreign">
                    <!--关联持久化类的属性名-->
                    <param name="property">address</param>
                </generator>
            </id>
            <property name="name"/>
            <property name="age"/>
            <!--constrained设定为true,表示的主键必须与Person中对应资料的主键相同。-->
            <one-to-one name="address" constrained="true"/>
        </class>
    </hibernate-mapping>

    单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置

    Address.hbm.xml 

    因为是单方面关联所以只在Person.hbm.xml中配置了关联信息而Address.hbm.xml中不做任何配置

    所以我们省略Address.hbm.xml

      …………

     

    (2)一对一主键双向关联:

      Person<——>Address

    public class Person implements java.io.Serializable { 
    
      private Long id; 
      private String name; 
      //双向关联中Person对象中有Adderss对象的关联信息  
      private Address address;
     
    public class Address implements java.io.Serializable { 
      private Long id; 
      //Adderss对象中也有Person对象的关联信息  
      private Person person; 
      private String detail;

    这种两方面都有另一个对象的关联信息的时候我们称为双向关联,再来看一下两个表中的映射hbm.xml文件:

    Person.hbm.xml

    <hibernate-mapping> 
      <class name="entity.Person" table="person"> 
        <id name="id" type="java.lang.Long"> 
          <column name="id" /> 
          <generator class="identity" /> 
        </id> 
        <property name="name" type="java.lang.String"> 
          <column name="name" length="24" not-null="true"> 
            <comment>姓名</comment> 
          </column> 
        </property> 
        <one-to-one name="address"/> 
      </class> 
    </hibernate-mapping>

    单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置 

    Address.hbm.xml

    <hibernate-mapping> 
      <class name="entity.Address" table="address" catalog="mydb"> 
        <id name="id" type="java.lang.Long"> 
          <column name="id" /> 
          <!-- class="foreign": 一对一主键映射中,使用另外一个相关联的对象的标识符 --> 
          <generator class="foreign"> 
            <param name="property">person</param> 
          </generator> 
        </id> 
        <property name="detail" type="java.lang.String"> 
          <column name="detail" length="120" not-null="true"> 
            <comment>详细地址</comment> 
          </column> 
        </property> 
        <!-- 表示在address表存在一个外键约束,外键参考相关联的表person --> 
        <one-to-one name="person" constrained="true" /> 
      </class> 
    </hibernate-mapping>

     当我们操作Person对象时,可以对Address对象进行操作,也可以操作Address对象时对Person对象进行操作这样就形成了双向的关联

    双向关联还需要在hibernate.cfg.xml中进行配置

    <hibernate-configuration> 
    
      <session-factory> 
        <property name="connection.username">root</property> 
        <property name="connection.url"> 
          jdbc:mysql://localhost:3306/testdb 
        </property> 
        <property name="dialect"> 
          org.hibernate.dialect.MySQLDialect 
        </property> 
        <property name="connection.password">xiaohui</property> 
        <property name="connection.driver_class"> 
          com.mysql.jdbc.Driver 
        </property> 
        <property name="show_sql">true</property> 
        <property name="format_sql">true</property> 
    
       <!--在hibernate.cfg.xml中配置hbm.xml文件-->
        <mapping resource="com/entity/Person.hbm.xml" /> 
        <mapping resource="com/entity/Address.hbm.xml" /> 
    
      </session-factory> 
    
    </hibernate-configuration>

    (3)一对一外键单向关联:

      Person——>Address

    public class Person {
        private int personid;
        private String name;
        private int age;
        private Address address;
     
    public class Address{
        private int addressid;
        private String addressdetail;

    Address.hbm.xml

    
    <!--address中不做任何配置所以我们省略-->
    
      …………………………
    
    <!--单向关联和双向关联的区别在于单向关联只在一方配置双向关联两方都要配置-->
    Person.hbm.xml
    <hibernate-mapping> 
            <class name="com.entity.Person" table="PERSON"> 
                    <id name="personid"> 
                            <generator class="identity"/> 
                    </id> 
                    <property name="name"/> 
                    <property name="age"/> 
                    <!--用来映射关联PO column是Address在该表中的外键列名,增加unique变成唯一的--> 
                    <many-to-one name="address" unique="true"/> 
            </class> 
    </hibernate-mapping>

    关联和主键关联不同的地方是采用<many-to-one>标签来映射,一对一唯一外键关联映射其实是多对一的特例。<many-to-one>指定多的一端unique为true,这样就限制了多的一端的多重性为一,就是这样来映射的。

    (4)一对一外键双向关联:

      Person<——>Address

    public class Person implements java.io.Serializable { 
    
      private Long id; 
      private String name; 
      private Address address;
     
    public class Address implements java.io.Serializable { 
      private Long id; 
      private Person person; 
      private String detail;

    Person.hbm.xml 

    <hibernate-mapping> 
      <class name="com.entity.Person" table="person"> 
        <id name="personid" type="java.lang.Long"> 
          <column name="personid" /> 
          <generator class="identity" /> 
        </id> 
        <property name="name" type="java.lang.String"> 
          <column name="name" length="24" not-null="true"> 
            <comment>姓名</comment> 
          </column> 
        </property> 
      <!--双向关联配置-->
        <one-to-one name="address" /> 
      </class> 
    </hibernate-mapping>

    Address.hbm.xml

    <hibernate-mapping> 
      <class name="com.entity.Address" table="address" catalog="testdb"> 
        <id name="addressid" type="java.lang.Long"> 
          <column name="addressid" /> 
          <generator class="identity" /> 
        </id> 
        <property name="detail" type="java.lang.String"> 
          <column name="detail" length="120" not-null="true"> 
            <comment>详细地址</comment> 
          </column> 
        </property> 
        <many-to-one name="person" class="entity.Person" unique="true"> 
          <column name="personid"> 
            <comment>人的ID</comment> 
          </column> 
        </many-to-one> 
      </class> 
    </hibernate-mapping>

    单向关联和双向关联的区别主要在于单向只在一方配置而双向两方都要配置所以一对一双向关联比单向关联多了一个在Person.hbm.xml文件中配置<one-to-one name="address" /> 

     双向关联还需要在hibernate.cfg.xml中进行配置

    <hibernate-configuration> 
    
      <session-factory> 
        <property name="connection.username">root</property> 
        <property name="connection.url"> 
          jdbc:mysql://localhost:3306/testdb 
        </property> 
        <property name="dialect"> 
          org.hibernate.dialect.MySQLDialect 
        </property> 
        <property name="connection.password">xiaohui</property> 
        <property name="connection.driver_class"> 
          com.mysql.jdbc.Driver 
        </property> 
        <property name="show_sql">true</property> 
        <property name="format_sql">true</property> 
    
       <!--在hibernate.cfg.xml中配置hbm.xml文件-->
        <mapping resource="com/entity/Person.hbm.xml" /> 
        <mapping resource="com/entity/Address.hbm.xml" /> 
    
      </session-factory> 
    
    </hibernate-configuration>

     注意:因为一对一的主键关联映射扩展性不好,当我们的需要发生改变想要将其变为一对多的时候变无法操作了,所以我们遇到一对一关联的时候经常会采用唯一外键关联来解决问题,而很少使用一对一主键关联。

     

    3、一对多关联映射

      一对多关联:一对多是指一个对象对应多个对象 同样也分为单向关联和双向关联 如:一个教室可以有多个学生

    (1) 一对多单向关联:

       Classes——>Student

    public class Classes {  
        private int id;  
        private String name;     
        //Set支持延迟加载因为多个学生所以我们用Set集合关联  
        private Set students;  
    }  
    public class Student {  
        private int id;  
        private String name;      
    }  

    单向关联只需在一方配置hbm.xml文件Student不需要配置所以就省略了 

    Classes对象中使用了set属性,但是只是说明了延迟加载的属性,并没有为属性配置对应的对象,属性的对象是要在映射文件中来配置的,需要添加set标签,并在set标签中添加<one-to-many>标签,具体如下代码:

    Classes.hbm.xml

    <hibernate-mapping>  
        <class name="com.hibernate.Classes" table="t_classes">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
            <set name="students">  
                <key column="classesid"></key>  
                <one-to-many class="com.hibernate.Student"></one-to-many>  
            </set>  
        </class>  
    </hibernate-mapping>  

    因为Classes一方是一方对应的Student是多方 所以我们要用<set>来关联一方

    Student.hbm.xml不做任何改变

      省略………………

     

    (2)一对多双向关联:

        Classes<——>Student

    public class Classes {  
        private int id;  
        private String name;     
        //Set支持延迟加载  
        private Set<Student> students;  
    }  
    public class Student {  
        private int id;  
        private String name; 
        //添加class对象关联信息因为是一方所以我们用一个对象关联
        private Classes classes;     
    }  

    Classes.hbm.xml

      因为与单向一对多配置一样所以就省略了 可以参考上面单向一对多的代码

    Student.hbm.xml

    双向我们需要两方都要配置代码如下:

    <hibernate-mapping>  
        <class name="com.hibernate.Student" table="t_student">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
            <!-- 在多的一端Student中添加一行新的Classes列 ,并且列的名称要和Classes.hbm.xml的列明相同-->  
            <many-to-one name="classes" column="classesid"></many-to-one>  
        </class>  
    </hibernate-mapping>  

     因为Student一方是多方对应的Classes是一方 所以我们要用<many-to-one>来关联一方

    4、多对多关联映射

     多对多关联:多对多关联是指多个对象对应多个对象 如:老师可以有多个学生,学生也可以有多个老师

    (1)多对多单向关联:

       Teacher——>Student

    public class Teacher {
        private int id;
        private String name;
        private Set<Student> students = new HashSet<Student>();
    }
    
    public class Student {
        private int id;
        private String name;
        private String title;
    }

    Teacher.hbm.xml

    <hibernate-mapping>  
        <class name="com.hibernate.Teacher" table="t_teacher">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
         <!--生成一张新表存放两个关联对象的ID-->
            <set name="students" table="Teacher_Sutdent">  
           <!--将Teacher表的外键关联 注意不是对象的属性是表中的字段-->
                <key column="teacher_id"></key>  
           <!--将Student表的外键关联 注意不是对象的属性是表中的字段--> 
           <many-to-many class="com.hibernate.Student" column="student_id"></many-to-many> 
          </set> 
       </class> 
    </hibernate-mapping>

    文件中要使用<many-to-many>标签,并且在标签中添加上对应的列关系,因为你要让两个对象中都要清楚它们之间的映射是如何使用的,并且在生成的关系表中哪一列是对应的自己的外键,所以要在该标签中指明,另外在<set>标签中添加table属性会指明要生成新表,下面的示例中添加了t_user_role,所以会生成新的关联表。 

    Student.hbm.xml不做任何配置所以省略

      …………

    (2)多对多双向关联:

      Teacher<——>Student

    public class Teacher {
        private int id;
        private String name;
        private Set<Student> students = new HashSet<Student>();
    }
    
    public class Student {
        private int id;
        private String name;
        private String title;
        private Set<Teacher> teachers = new HashSet<Teacher>();
    }

    Teacher.hbm.xml同单向多对多一样故省略

      …………

    Student.hbm.xml

    <hibernate-mapping>  
        <class name="com.hibernate.Student" table="t_student">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
         <!--生成一张新表存放两个表的Id-->
            <set name="teachers" table="Teacher_Student">  
           <!--将Teacher表的外键关联 注意不是对象的属性是表中的字段-->
                <key column="student_id"></key>  
           <!--将Student表的外键关联 注意不是对象的属性是表中的字段--> 
           <many-to-many class="com.hibernate.Teacher" column="teacher_id"></many-to-many> 
          </set> 
       </class> 
    </hibernate-mapping>

     

    5、多对一关联

        对比一对一关联映射和多对一唯一外键关联映射,其实它们两个都是使用了<many-to-one>本质上都是外键约束,只不过一对一的是唯一映射,需要添加unique="true"的属性,其它的它们两个是相同的。

      多对一关联:多对一关联是指多个对象对应一个对象 如:多个员工对应一个部门

    (1)多对一单向关联:

    public class Department {  
        private int id;  
        private String name;  
    }  
    
    public class Employee {  
        private int id;  
        private String name;  
        private Department depart;//注意这里是以部门的对象来作为员工的属性的,这个思想很关键,是建立起部门和员工关联的关键  
          
    }  

    Department.hbm.xml不做任何配置故省略  

      …………    

    Employee.hbm.xml

    <hibernate-mapping package="com.suo.domain">  
          
        <class name="Employee">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
            <many-to-one name="depart"></many-to-one>  
            <!-- many-to-one指明了外键 ,会根据反射机制,找到要和Employee建立多对一关系的类,该列默认的是可以为空的-->  
        </class>  
          
    </hibernate-mapping>  

    (2)多对一双向关联:

    public class Department {  
        private int id;  
        private String name;
        private Set<Employee> emps;//用集合来存储员工     
    }  
    
    public class Employee {  
        private int id;  
        private String name;  
        private Department depart;//注意这里是以部门的对象来作为员工的属性的,这个思想很关键,是建立起部门和员工关联的关键  
          
    }  

    Departement .hbm.xml

    <hibernate-mapping package="com.suo.domain">  
          
        <class name="Department">  
            <id name="id">  
                <generator class="native"/>  
            </id>  
            <property name="name"/>  
              
            <set name="emps">  
                <key column="depart_id"/><!-- key指明了员工表中的外键-->  
                <one-to-many class="Employee"/><!-- one-to-many指明了和哪个类进行一对多的映射 -->  
            </set>  
            <!--   
                用set标签表示Department中的员工集合的属性,这个属性并没有映射到数据库中的部门表中,  
                即部门表中,并没有emps这样的一个列。  
             -->  
        </class>  
          
    </hibernate-mapping>  

    Employee.hbm.xml同单向关联配置相同故省略

      …………

     

    五、 级联操作 Cascade:

    1、简单的介绍

    cascade和inverse (Employee – Department)

    l  Casade用来说明当对主对象进行某种操作时是否对其关联的从对象也作类似的操作,常用的cascade:

             none,all,save-update,delete, lock,refresh,evict,replicate,persist,

             merge,delete-orphan(one-to-many)。

       一般对many-to-one,many-to-many不设置级联,

         在<one-to-one>和<one-to-many>中设置级联。

    l  inverse表“是否放弃维护关联关系”(在Java里两个对象产生关联时,对数据库表的影响),在one-to-many和many-to-many的集合定义中使用,inverse=”true”表示该对象不维护关联关系;

       该属性的值一般在使用有序集合时设置成false(注意hibernate的缺省值是false)。

             one-to-many维护关联关系就是更新外键。many-to-many维护关联关系就是在中间表增减记录。

             注: 配置成one-to-one的对象不维护关联关系

     

    2、属性的解析
    class元素的lazy属性设定为true,表示延迟加载,如果lazy设为false,则表示立即加载。以下对这二点进行说明。
         立即加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后, 会立即再从数据库取得数据组装此对象所关联的对象(如学生证1)。
         延迟加载:表示Hibernate在从数据库中取得数据组装好一个对象(如学生1)后,不会立即再从数据库中取得数据组装此对象所关联的对象(如学生1),而是等到需要时,才会从数据库取得数据组装此关联对象。

     

    <one-to-one>元素的cascade属性表明操作是否从父对象级联到被关联的对象,

    它的取得可以是以下几种:


         none:在保存,删除或修改当前对象时,不对其附属对象(关联对象)进行级联操作。它是默认值。
         save-update:在保存,更新当前对象时,级联保存,更新附属对象(临时对象,游离对象)。
         delete:在删除当前对象时,级联删除附属对象。
         all:所有情况下均进行级联操作,即包含save-update和delete操作。
         delete-orphan:删除和当前对象解除关系的附属对象。


    <one-to-one>元素的fetch属性的可选值是join和select,默认是select。当fetch属性设定为join时,表示连接抓取(Join fetching):Hibernate通过在Select语句中使用outer join(外连接)来获得对象的关联实例或者关联集合。

      当fetch属性设定为select时,表示查询抓取(Select fetching):需要另外发送一条Select语句抓取当前对象的关联实体或集合。

    3、代码练习

    <set name="emps" cascade="save-update">
     <key column="depart_id"/>
      <one-to-many class="Employee"/>
    </set>

    <set name="students" table="taacher_student" inverse="true"><!-- table是用来指定中间表的属性 -->
    <key column="teacher_id"></key><!-- 查找教师id时,链接中间表表的teacher_id -->
    <many-to-many class="Student" column="student_id"></many-to-many>
    </set>

    六、总结:

    1、单向关联

      (1)、一对一主键关联:单向关联时我们需要在有关联信息一方的配置文件里加入<one-to-one  constrained="true">并且将constrained属性设置为true 表示的主键必须与这个对象中对应资料的主键相同

      (2)、一对一外键关联:单向关联时我们需要在有关联信息一方的配置文件里加入<many-to-one unique="true">并且将unique属性设置为true 表示这个主键是唯一的

      (3)、一对多单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入<set>在<set>中加入<one-to-many/>

          <set>  

             <key column="关联的外键">

             <one-to-many/>

          </set>

      (4)、多对多单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入<set>在<set 中生成一张新表用来存放两个表的外键table="">中加入<key column="当前表的外键ID"><many-to-many clasee="关联对象路径" column="关联对象表的Id">

          <set table="">

              <key column=""/>

              <many-to-many class="" column="">

          </set>

      (5)、多对一单向关联:单向关联时我们需要在有关联信息一方的配置文件里加入<many-to-one>

     

    2、双向关联

      (2)、一对一主键关联:在从表的一方加入<one-to-oneconstrained="true">还需要在主表加入<one-to-one>

      (2)、一对一外键关联:除了在从表中加入<many-to-one unique="true">也需要在主表加入<one-to-one>

      (3)、一对多双向关联:除了在一方中加入<set><one-to-many></set>还需要在多放加入<many-to-one>

      (4)、多对多双向关联:需要在两方都加入<set><many-to-many></set>  注:<set>中的table="表名"   表明两方的配置要一样

           <set name="关联对象的属性名" table="生成一张新表">

             <key column="当前对象数据库表的外键"/>

             <many-to-many class="关联对象的类路径" column="关联对象数据库表的外键">

           </set>

         (5)、多对一双向关联:要在多方中加入<many-to-one>还要在一方中加入<set>

                <set>

                   <key column="关联外键"/>

                   <one-to-many>

                </set>

    展开全文
  • HarmonyOS 对象关系映射(Object Relational Mapping,ORM)数据库是一款基于 SQLite 的数据库框架,屏蔽了底层 SQLite 数据库的 SQL 操作,针对实体和关系提供了增删改查等一系列的面向对象接口。应用开发者不必再...
  • mybatisPlus 实体数据库表映射关系

    千次阅读 多人点赞 2020-10-29 16:49:41
    使用mybatisPlus时,会确定实体类和数据的映射关系 具体的映射方法有两种: 1、默认:采用驼峰映射规则,例如MyUserTable 对应的数据库表为 my_user_table ; TEMyUserTable 对应表名为t_e_my_user_table; 2、注解...
  • 在开发中可能会遇到MyBatis-Plus使用实体类属性进行SQL操作,但是不用存到数据库中去查找,这时候...在类名上方添加@TableName(“my_user_table”)在实体类的属性上面加上这个注解后,此字段就不会映射数据库了。......
  • 数据表简单Java类的基本映射关系: 数据实体表设计=类的定义; 表中的字段=类的成员属性; 表的外键关联=引用关联 表的一行记录=类的一个实例化对象; 表的多行记录=对象数组; 原创文章 7获赞 4访问量 242 ...
  • Python————对象关系映射

    千次阅读 2019-07-22 09:41:53
    ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的...
  • 1.在mybatis的映射中,如果我们没有定义指定的resultMap,就会因为字段和Java实体类的属性不同而导致映射失败。 2.数据库和java实体类的属性值名字相同,但是因为两者之间的数据类型不同,会导致在启动项目时报...
  • C#ORM(关系对象映射)的框架

    千次阅读 2020-09-17 08:02:19
    对象关系映射(Object Relationsl Mapping,简称ORM,或O/RM,或O/R mapping),是一种技术,用于实现面向对象编程语言里不同类型系统数据之间的转换。从效果上说,它其实是创建了一个可在编程语言里使用的“虚拟对象...
  • MySql (四) ER图与实体关系映射

    千次阅读 2021-03-13 15:43:24
    ERMaster初步掌握数据库设计的方法实体关系映射什么是数据库的设计?数据库设计(Database Design)是指对于一个给定的应用环境,构造最优的数据库模式,建立数据库及其应用系统,使之能够有效地存储数据,满足各种...
  • 在ABP框架中可以分别为数据传输对象DTO与实体Entity、实体Entity数据库表Table建立映射关系,既可以减少一定的编码工作量,也能降低数据传输对象实体与数据库表之间的耦合性。 一.对象映射–数据传输对象与实体...
  • 对象关系映射(Object Relational Mapping,简称ORM)模式是一种为了解决面向对象与关系数据库存在的互不匹配的现象的技术。 怎么理解上面的那句话呢?         在Java中...
  • JPA实体关系映射

    千次阅读 2015-08-27 18:09:54
    1、 实体关系映射 实体关系是指实体实体之间的关系,从方向上分为单向关联和双向关联,从实体数量上分为一对一、一对多、多对多等。对于任何两个实体,都要从这两个方面区分它们之间的关系。 单向关联是一个实体...
  • 数据库设计,讲解业务实体对象到数据库表的映射关系
  • 实现mybatis (和 mybatis-plus)一个字段在数据库中以字符串/json类型的形式存储,但是在实体类中需要以集合或对象的方式使用。
  • 对象关系映射(Object Relational Mapping,简称ORM)是通过使用描述对象和数据库之间映射的元数据,将面向对象语言程序中的对象自动持久化到关系数据库中。本质上就是将数据从一种形式转换到另外一种形式。 这也...
  • 实体关联关系映射

    千次阅读 2018-06-14 19:01:36
    关联是类(类的实例)之间的关系,表示有意义和值得关注的连接。1.多对一单向关联类product引用了类factory,但是类factory没有引用类product。映射文件的配置&lt;many-to-one name="factory" class=&...
  • 关于对象关系数据库的介绍,看另外一篇篇文章,litePal的使用以及关系数据库的介绍 1、添加远程依赖 // In your root build.gradle file: buildscript {  repositories {  jcenter()  mavenCentral()...
  • 实体映射

    千次阅读 2020-03-09 16:57:59
    1、实体映射配置 1.1、 @注解配置 所有的注解都是在javax.persistence.*; @Entity 实体注解 @Table指定对应的表 @Id 配置主键 @Column 配置普通属性 @OneToMany、@ManyToOne、@ManyToMany、@OneToOne 配置关系 ...
  • 一对一关联映射在实际生活中是比较常见的,如人身份证的关系,通过人这个对象可以找到身份证相关的信 息,也可以通过身份证这个对象找到人相关的信息。  有两种策略可以实现一对一的关联映射:  主键关联:即...
  • 数据库设计——实体表的映射

    千次阅读 2020-09-08 21:30:46
    E-R图 (Entity-Relationship),实体关系映射图 它的核心就是映射 (mapping): 1.实体名,映射成表名 2.属性,映射成列名 3.对象标示符,映射成主键约束 4.实体关系,映射成表之间的关系 (外键约束) 映射举例 实体类...
  • Hibernate之实体关系映射

    千次阅读 2015-03-06 09:27:40
    延迟加载即时加载 例如Person类和Email类是一对多关系,如果设为即时加载,当加载Person时,会自动加载Email,如果设置为延迟加载,当第一次调用person.getEmails()时才会执行SQL语句加载Email 注解配置时,@...
  • net数据设计应用.rar,Sawin软件研发之窗:_net数据设计应用.files,263731.gif,dotnetdb1.jpg,title.js,dotnetdb7.gif,dotnetdb6.gif,bottom.js,dotnetdb4.gif,dotnetdb10.gif,dontnetdb2.gif,dontnetdb9.gif,...
  • JPA实体中字段映射补充和嵌入对象

    千次阅读 2018-06-27 16:07:21
    实体中字段注解的说明* @Column注解用于列映射,name元素用于指定所映射到的列的名称* 实体字段的延迟提取: @Basic注解指定fatch元素,可以把基本映射的提取类型配置为延迟加载。但是在实际中延迟加载简单类型的字段...
  • Hibernate实体关系映射—Annotation

    千次阅读 2016-04-07 21:31:25
    Hibernate实体关系映射分为:  单边一对一,双边一对一;  单边一对多,单边多对一;  双边一对多,双边多对一;  单边多对多,双边多对多;  以及主键相同的单双边一对一。下面分别总结这几种关系映射的注解...
  • 问题描述 在开发中可能会遇到MyBatis-Plus使用实体类属性进行SQL操作,但是不用存到数据库中去查找,这时候我们的实体中有这个...忽略映射字段时可以在实体类属性上使用以下注解: @TableField(exist = false):表示

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 142,744
精华内容 57,097
热门标签
关键字:

对象关系与实体关系映射