Hibernate基于主键的单项,双向多对多映射关系

今天我们来一起谈论下hibernate的基于主键的单项,双向多对多映射关系
首先多对多都是基于主键的,没有基于外键的说法
1.基于主键的单项多对多
这里写图片描述
在这里就是说中间stuobject是一张关系表,将两张表的主键进行关联,形成了多对多的关系
代码如下:

public class StuObject {
    private int stuobjectid;
    private String objectname;
    private StuObject(){}
    public StuObject(String objectname){
        this.objectname=objectname;
    }
    public int getStuobjectid() {
        return stuobjectid;
    }
    public void setStuobjectid(int stuobjectid) {
        this.stuobjectid = stuobjectid;
    }
    public String getObjectname() {
        return objectname;
    }
    public void setObjectname(String objectname) {
        this.objectname = objectname;
    }
}


public class YoungStu {
    private int stuid;
    private String youngname;
    private Set<StuObject> stuobject;
    public YoungStu(){

    }
    public YoungStu(String youngname){
        this.youngname=youngname;
    }
    public int getStuid() {
        return stuid;
    }
    public void setStuid(int stuid) {
        this.stuid = stuid;
    }
    public String getYoungname() {
        return youngname;
    }
    public void setYoungname(String youngname) {
        this.youngname = youngname;
    }
    public Set<StuObject> getStuobject() {
        return stuobject;
    }
    public void setStuobject(Set<StuObject> stuobject) {
        this.stuobject = stuobject;
    }
}


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:工厂

        其他概念:
            struts2中的session是指当前用户与服务器之间的一个连接
     -->
    <session-factory>
    <!-- 配置数据库连接信息 -->
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property><!-- 数据库驱动 -->
        <property name="connection.url">jdbc:mysql://localhost:3306/hibernate4</property><!--数据库地址  -->
        <property name="connection.username">**</property><!-- 用户名 -->
        <property name="connection.password">****</property><!-- 密码 -->
        <!--  
            dialect数据库方言:指明用什么数据库
            driver_class指定的是引用的驱动
            两者不是一码事
        -->
        <!--  
            dialect:指连接什么数据库
            connection.driver_class:连接数据库所需要的驱动
        -->
        <property name="dialect">
            org.hibernate.dialect.MySQL5Dialect
        </property>
        <!-- 是否打印sql -->
        <property name="show_sql">true</property>
        <!-- 格式化sql语句 -->
        <property name="format_sql">true</property>
        <mapping resource="hibernatedemo1/pojo/stuobject.hbm.xml"></mapping> 
        <mapping resource="hibernatedemo1/pojo/Youngstu.hbm.xml"></mapping>
    </session-factory>
</hibernate-configuration>

youngstu.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="hibernatedemo1.pojo.YoungStu" table="youngstu">
        <!-- 
            id标签必须有
            id:主键只是hibernate在操作数据库表的时候的一个概念,并不要求此列也为数据库规范意义上的主键
         -->
         <!--  id标签对应的是实体类的属性,表中可以没有主键-->
        <id name="stuid">
            <!-- 
                generator:主键生成策略
                    native:自增长(映射文件生成策略为native,且表中相应的列设为自增)
                    assigned:自定义(如果此列在数据库中是主键的话,那么程序在save时,必须保证此列对应的对象属性有值)
                    increment:由hibernate从数据库中取出主键的最大值(每个session只取一次),以该值为基础,每次增量为1,在内存 中生成主键
                    不依赖于底层的数据库,因此可以跨数据库
                    sequence:采用数据库提供的sequence机制生成主键,需要数据库支持sequence
                    所以:native和sequence都有各自的数据库选型的局限性
             -->
            <generator class="increment"></generator>
        </id>   
        <!--这里的name必须和映射类里的字段名一致-->
        <property name="youngname"/>
        <!--这里的name是你映射类里的set的别名  后面是重新建立一个关系表-->
        <set name="stuobject" table="stuobject">
        <!--**表示当前类映射到关系表stuobject中的列,这个column是table所指引的列名,不一定要和映射类里的id名称一样**-->
            <key column="stuid"></key>
        <!--所对应的另一个表(与yongstu产生关系的一方) column是table所指引的列名,不一定要和映射类里的id名称一样-->
            <many-to-many class="hibernatedemo1.pojo.StuObject" column="stuobjectid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>


stuobject.hbm.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
    <class name="hibernatedemo1.pojo.StuObject" table="object">
        <!-- 
            id标签必须有
            id:主键只是hibernate在操作数据库表的时候的一个概念,并不要求此列也为数据库规范意义上的主键
         -->
         <!--  id标签对应的是实体类的属性,表中可以没有主键-->
        <id name="stuobjectid">
            <!-- 
                generator:主键生成策略
                    native:自增长(映射文件生成策略为native,且表中相应的列设为自增)
                    assigned:自定义(如果此列在数据库中是主键的话,那么程序在save时,必须保证此列对应的对象属性有值)
                    increment:由hibernate从数据库中取出主键的最大值(每个session只取一次),以该值为基础,每次增量为1,在内存 中生成主键
                    不依赖于底层的数据库,因此可以跨数据库
                    sequence:采用数据库提供的sequence机制生成主键,需要数据库支持sequence
                    所以:native和sequence都有各自的数据库选型的局限性
             -->
            <generator class="increment"></generator>
        </id>   
        <property name="objectname"/>
    </class>
</hibernate-mapping>

测试代码
HibernateUtil.java

public class HibernateUtil {
    private static final Configuration cfg;
    private static final SessionFactory sessionFactory;
    static{
        cfg = new Configuration().configure();
        ServiceRegistry registry = new StandardServiceRegistryBuilder()
        .applySettings(cfg.getProperties()).build();
        sessionFactory=cfg.buildSessionFactory(registry);
    }

    public static Session openSession(){
        return sessionFactory.openSession();
    }
}
Demo.java
//基于主键的单项多对多映射
    @Test
    public void fkmanytomanyTest(){
        Session session=HibernateUtil.openSession();
        Transaction tx=session.beginTransaction();
        YoungStu youngstu=new YoungStu("Align");
        session.saveOrUpdate(youngstu);
        youngstu.setStuobject(new HashSet());
        for(int i=0;i<5;i++){
            StuObject stuobject=new StuObject("高数"+i);
            youngstu.getStuobject().add(stuobject);
            session.saveOrUpdate(stuobject);
        }
        tx.commit();
        session.close();
    }

2.双向多对多映射关系
这里写图片描述
Role.java

public class Role {
    private int id;
    private String name;
    private Set<Function> function;
    public Role(){}
    public Role(String name){
        this.name=name;
    }
    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<Function> getFunction() {
        return function;
    }
    public void setFunction(Set<Function> function) {
        this.function = function;
    }
}

Function.java

public class Function {
    private int funid;
    private String code;
    private String url;
    private Set<Role> role;
    public Function(){}
    public Function(String code,String url){
        this.code=code;
        this.url=url;
    }
    public int getFunid() {
        return funid;
    }
    public void setFunid(int funid) {
        this.funid = funid;
    }
    public String getCode() {
        return code;
    }
    public void setCode(String code) {
        this.code = code;
    }
    public String getUrl() {
        return url;
    }
    public void setUrl(String url) {
        this.url = url;
    }
    public Set<Role> getRole() {
        return role;
    }
    public void setRole(Set<Role> role) {
        this.role = role;
    }

}

role.hbm.xml

<hibernate-mapping>
    <class name="hibernatedemo1.pojo.Role" table="role">
        <id name="id">
            <generator class="increment"></generator>
        </id>   
        <property name="name"/>
        <set name="function" table="rolefunction">
            <key column="roleid"></key>
            <many-to-many class="hibernatedemo1.pojo.Function" column="funid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

function.hbm.xml

<hibernate-mapping>
    <class name="hibernatedemo1.pojo.Function" table="function">    
        <id name="funid">
            <generator class="increment"></generator>
        </id>   
        <property name="code"/>
        <property name="url"></property>
        <set name="role" table="rolefunction">
            <key column="funid"></key>
            <many-to-many class="hibernatedemo1.pojo.Role" column="roleid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

这两个hbm.xml里面要注意

<set name="function" table="rolefunction">
            <key column="roleid"></key>
            <many-to-many class="hibernatedemo1.pojo.Function" column="funid"></many-to-many>
        </set>


<!--这两个里面的column一定要一一对应,不能随便-->


<set name="role" table="rolefunction">
            <key column="funid"></key>
            <many-to-many class="hibernatedemo1.pojo.Role" column="roleid"></many-to-many>
        </set>
python+opencv简谱识别音频生系统源码含GUI界面+详细运行教程+数据 一、项目简介 提取简谱中的音乐信息,依据识别到的信息生midi文件。 Extract music information from musical scores and generate a midi file according to it. 二、项目运行环境 python=3.11.1 第三方库依赖 opencv-python=4.7.0.68 numpy=1.24.1 可以使用命令 pip install -r requirements.txt 来安装所需的第三方库。 三、项目运行步骤 3.1 命令行运行 运行main.py。 输入简谱路径:支持图片或文件夹,相对路径或绝对路径都可以。 输入简谱主音:它通常在第一页的左上角“1=”之后。 输入简谱速度:即每分钟拍数,同在左上角。 选择是否输出程序中间提示信息:请输入Y或N(不区分大小写,下同)。 选择匹配精度:请输入L或M或H,对应低/中/高精度,一般而言输入L即可。 选择使用的线程数:一般与CPU核数相同即可。虽然python的线程不是真正的多线程,但仍能起到加速作用。 估算字符上下间距:这与简谱中符号的密集程度有关,一般来说纵向符号越稀疏,这个值需要设置得越大,范围通常在1.0-2.5。 二值化算法:使用全局阈值则跳过该选项即可,或者也可输入OTSU、采用大津二值化算法。 设置全局阈值:如果上面选择全局阈值则需要手动设置全局阈值,对于.\test.txt中所提样例,使用全局阈值并在后面设置为160即可。 手动调整中间结果:若输入Y/y,则在识别简谱后会暂停代码,并生一份txt文件,在其中展示识别结果,此时用户可以通过修改这份txt文件来更正识别结果。 如果选择文件夹的话,还可以选择所选文件夹中不需要识别的文件以排除干扰
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值