Hibernate系列(三)一对多&多对一

一.Hibernate测试代码

直接上代码,具体解释见代码注释

必不可少之Hibernate主配置文件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.url">jdbc:mysql:///my?useUnicode=true&amp;characterEncoding=utf-8</property>
    <property name="hibernate.connection.username">root</property>
    <property name="hibernate.connection.password">password</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>
    <property name="hibernate.connection.isolation">4</property>
    <property name="hibernate.current_session_context_class">thread</property>
    <property name="dialect"></property>
    <mapping resource="cjx/OneAndManyTable/ContactPerson.hbm.xml" />
    <mapping resource="cjx/OneAndManyTable/Customerl.hbm.xml" />
</session-factory>
</hibernate-configuration>

自己写的工具类HibernateUtil.java(上面的代码结构图里没加上)

public class HibernateUtil {
//  用于测试的主函数
//  public static void main(String[] args) {
//      System.out.println(HibernateUtil.openSession());
//  }
    private static SessionFactory sf;
    static{
        //1.创建,调用空参构造
        Configuration conf = new Configuration().configure();
        //2.根据配置信息,创建 SessionFactory对象
         sf = conf.buildSessionFactory();
    }
    //获得session => 获得全新session
    public static Session openSession(){
                Session session = sf.openSession();
                return session;
    }
    //获得session => 获得与线程绑定的session
    public static Session getCurrentSession(){
        Session session = sf.getCurrentSession();
        return session;
    }
}

Customer.java

public class Customer {//客户实体
    private String id;
    private String name;
    //使用set集合表达一对多关系
    private Set<ContactPerson> contact=new HashSet<ContactPerson>();
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Set<ContactPerson> getContact() {
        return contact;
    }
    public void setContact(Set<ContactPerson> contact) {
        this.contact = contact;
    }
}

Customerl.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 package="cjx.OneAndManyTable">
<class table="customer" name="cjx.OneAndManyTable.Customer">
<id name="id">
<generator class="uuid"></generator>
</id>
<property name="name" />
<!-- 在配置文件中配置一对多,因为Customer实体类中用的set集合,这里就用set元素
name:集合属性名,Customer实体类中的一对多属性
column:外键列名,外键的列名
class:关联的实体类的完整类名
-->
<!-- 级联操作:cascade     作用:可以简化操作,减少代码量,但可能造成误操作
        save-update:级联保存更新
        delete:级联删除
        all:级联保存更新删除
        配置一对多时,操作一表时会自动关联多表
        例如:操作Customer时会自动关联操作ContactPerson
 -->
 <!-- inverse属性:用于配置关系是否维护
        true:不维护关系(inverse是反转的意思)
        false(默认值):维护关系
        inverse属性作用:性能优化,可以减少Hibernate生成的语句量
        原则:必须有一方维护关系。一对多关系中只能是一的一方放弃维护关系
  -->
<set name="contact"  cascade="save-update"  inverse="true" >
<key column="cpid"></key>
<one-to-many class="cjx.OneAndManyTable.ContactPerson" /><!--指定为一对多,并指定对应的实体类-->
</set>
<!-- 扩展:其他属性
lazy属性:决定是否延迟加载,懒加载
true(默认值):延迟加载
false:立即加载
extra:极其懒惰
fetch属性:决定加载策略,使用什么类型的SQL语句加载集合数据
select(默认值):单表查询加载
join:多表查询加载
subselect:子查询加载
batch-size:批量抓取
 -->
</class>
</hibernate-mapping>

ContactPerson.java

public class ContactPerson {//客户拥有的联系人实体
    //一个客户拥有多个联系人
    private String id;
    private String cpid;//外键
    private String name;
    private String age;
    private String sex;
    private String qq;
    private String email;
    private String address;
    private Customer customer;//表达多对一关系
    public String getId() {
        return id;
    }
    public void setId(String id) {
        this.id = id;
    }
    public String getCpid() {
        return cpid;
    }
    public void setCpid(String cpid) {
        this.cpid = cpid;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAge() {
        return age;
    }
    public void setAge(String age) {
        this.age = age;
    }
    public String getSex() {
        return sex;
    }
    public void setSex(String sex) {
        this.sex = sex;
    }
    public String getQq() {
        return qq;
    }
    public void setQq(String qq) {
        this.qq = qq;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public Customer getCustomer() {
        return customer;
    }
    public void setCustomer(Customer customer) {
        this.customer = customer;
    }
}

ContactPerson.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 package="cjx.OneAndManyTable">
<class table="contactperson" name="cjx.OneAndManyTable.ContactPerson">
<id name="id">
<generator class="uuid"></generator>
</id>
<property name="cpid" />
<property name="name" />
<property name="age" />
<property name="sex" />
<property name="qq" />
<property name="email" />
<property name="address" />

<!-- 多对一 ,在配置文件中配置 
name:引用属性名,ContactPerson实体类中多对一属性
column:外键列名,ContactPerson实体类中外键的列名
class:关联的实体类的完整类名
 -->
 <!-- 级联操作:cascade     作用:可以简化操作,减少代码量,但可能造成误操作
        save-update:级联保存更新
        delete:级联删除
        all:级联保存更新删除
        配置多对一时,操作多表时会自动关联一表
        例如:操作ContactPerson时会自动关联操作Customer
 -->
  <!-- inverse属性:在此处不能放弃维护关系,外键字段在多的一方,不能放弃-->
<many-to-one name="customer" column="cpid" cascade="save-update" 
class="cjx.OneAndManyTable.Customer" 
insert="false" update="false"></many-to-one>
</class>
</hibernate-mapping>

测试代码OneAndManyTable.java

public class OneAndManyTable {//一对多和多对一操作
    @Test
    //保存客户和联系人
    public void funone(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();
        //创建数据
        Customer c=new Customer();
        c.setName("客户A");

        ContactPerson cp1=new ContactPerson();
        cp1.setName("客户A的联系人A");
        cp1.setQq("123456");

        ContactPerson cp2=new ContactPerson();
        cp2.setName("客户A的联系人B");
        cp2.setAge("18");
        //表达一对多,客户下有多个联系人
//      c.getContact().add(cp1);//如果Customer放弃维护关系,则维护关系的代码可以不写
//      c.getContact().add(cp2);//如果Customer放弃维护关系,则维护关系的代码可以不写
        //表达多对一,联系人属于哪个客户
        cp1.setCustomer(c);
        cp2.setCustomer(c);
        //保存
        session.save(c);
        session.save(cp1);//配置级联操作后,此步可省
        session.save(cp2);//配置级联操作后,此步可省
        /*注意:如果Customer放弃维护关系,且维护关系的代码不写
         * 级联操作将不会起作用,ContactPerson不会被保存
         * 由此可知级联操作由维护关系的代码决定
         */
        tx.commit();
        session.close();
    }

    @Test
    //删除客户的联系人
    public void funtwo(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();
        Customer customer = session.get(Customer.class, "297eaf72634a258f01634a2596b40000");        
//      ContactPerson contactPerson = session.get(ContactPerson.class, "297eaf72634a258f01634a2596c30001");
//      customer.getContact().remove(contactPerson);
//      contactPerson.setCustomer(null);
        //配置了级联删除后,上面的三行代码替换为下面的一行代码
        session.delete(customer);
        tx.commit();
        session.close();
    }

    //删除客户,此处不用于测试
    public void funthree(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();
        Customer customer = session.get(Customer.class, "297eaf72634a258f01634a2596c30001");
        /*由于Customer与ContactPerson表相关联,所以可能不能直接删除
         * 方案一:解除外键
         * inverse="true" 外键会置为空
         * 方案二:级联删除
         * inverse="true"
         * cascade="delete" 
         */
        session.delete(customer);
        tx.commit();
        session.close();
    }

}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Struts2 是一个开源的 Java Web 框架,用于构建企业级应用程序。它提供了一组用于简化 Web 应用程序开发的工具和框架。 Hibernate 是一个开源的 Java 持久层框架,用于简化数据库操作。它提供了一组用于管理数据库实体对象的工具和框架。 struts2+hibernate项目是用struts2来构建前端界面,用hibernate来管理数据库交互的项目。 ### 回答2: Struts2和Hibernate都是常用的Java开发框架,可以通过结合使用来构建Web应用程序。 Struts2是一个基于MVC设计模式的框架,它将应用程序分成个部分:模型(Model)、视图(View)和控制器(Controller)。在Struts2中,模型表示数据,视图定义了如何呈现数据,控制器负责处理用户的请求并更新模型和视图。通过使用Struts2,可以将业务逻辑与视图分离,提高代码的可维护性和可重用性。 Hibernate是一个开源的对象关系映射(ORM)框架,它提供了一种将对象模型映射到关系数据库的机制,从而实现对数据库的访问和操作。使用Hibernate,开发人员可以通过简单的配置文件描述对象和数据库表之间的映射关系,Hibernate会自动执行SQL语句并将结果映射回Java对象。通过使用Hibernate,可以简化数据库访问的过程,提高开发效率。 在一个项目中同时使用Struts2和Hibernate可以发挥它们各自的优势。Struts2可以负责用户请求的处理和页面的呈现,而Hibernate可以负责数据的持久化和访问。使用Struts2和Hibernate,可以将应用程序分成多个模块,每个模块负责特定的功能,进一步提高代码的可维护性和可重用性。 总结而言,Struts2和Hibernate是两个功能强大的Java开发框架,可以互补使用来构建高效且易于维护的Web应用程序。 ### 回答3: Struts2和Hibernate是常用于开发Java Web应用的两个框架。它们分别负责解决Web层和持久层的问题。 Struts2是一个基于MVC(Model-View-Controller)架构的Web框架,用于处理Web层的业务逻辑。它通过将请求和响应分派给相应的Action类来处理用户的请求。Struts2提供了丰富的标签库和拦截器机制,使开发人员可以轻松地实现表单验证、权限控制、数据封装等公共功能。此外,Struts2采用了面向对象的设计思想,开发者可以通过自定义Action类和拦截器来实现更加灵活和可扩展的功能。 Hibernate是一个优秀的对象关系映射(ORM,Object-Relational Mapping)框架,用于解决持久层的问题。它将Java对象和数据库表之间的映射关系进行了封装,并提供了一系列API供开发人员操作数据库。使用Hibernate,开发者可以通过对象的方式操作数据库,而无需编写复杂的SQL语句。Hibernate还提供了缓存和事务管理等功能,用于提高数据访问的性能和可靠性。 结合使用Struts2和Hibernate可以将Web层和持久层完美地结合在一起。Struts2负责用户请求的处理和业务逻辑的控制,而Hibernate负责数据库的操作和数据的持久化。开发人员只需在Struts2的Action类中调用Hibernate的API,即可完成数据的读取、插入、更新和删除等操作。通过这种方式,开发人员可以专注于业务逻辑的实现,而无需关注底层的数据库细节。这种结合使用的方式可以极大地提高开发效率,并且使代码的维护更加方便。最重要的是,使用Struts2和Hibernate可以使应用的开发变得更加规范和模块化,提高了代码的可重用性和可测试性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值