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/ManyAndManyTable/Indent.hbm.xml" />
    <mapping resource="cjx/ManyAndManyTable/Product.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;
    }
}

Product.java

/*订单管理数据库
 * 单个订单中可以包含多个产品。
 * 一个产品可能出现在多个订单中。
 * 对于“订单”表中的每条记录,都可能与“产品”表中的多条记录对应。
 * 对于“产品”表中的每条记录,都可以与“订单”表中的多条记录对应。
 * 此时,使用中间表,至少两列,都是外键列,分别引用产品表和订单表的主键
 */
public class Product {//产品表
    private long id;
    private String name;
    private String price;
    private Date produceDate;
    private Set<Indent> indents =new HashSet<Indent>();//表达多对多
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPrice() {
        return price;
    }
    public void setPrice(String price) {
        this.price = price;
    }
    public Date getProduceDate() {
        return produceDate;
    }
    public void setProduceDate(Date produceDate) {
        this.produceDate = produceDate;
    }
    public Set<Indent> getIndents() {
        return indents;
    }
    public void setIndents(Set<Indent> indents) {
        this.indents = indents;
    }
}

Product.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.ManyAndManyTable">
<class table="product" name="Product">
<id name="id">
<generator class="native"></generator>
</id>
<property name="name" />
<property name="price" />
<property name="produceDate" />
<!-- 多对多关系表达 -->
<!-- 
name:集合属性名
table:中间表名
key column “我”的外键列名
class 多对多关系的类
column “别人”的外键名
 -->
<set name="indents" table="middletable">
    <key column="productid"></key>
    <many-to-many class="Indent" column="indentid"></many-to-many>
</set>

</class>
</hibernate-mapping>

Indent.java

/*订单管理数据库
 * 单个订单中可以包含多个产品。
 * 一个产品可能出现在多个订单中。
 * 对于“订单”表中的每条记录,都可能与“产品”表中的多条记录对应。
 * 对于“产品”表中的每条记录,都可以与“订单”表中的多条记录对应。
 * 此时,使用中间表,至少两列,都是外键列,分别引用产品表和订单表的主键
 */
public class Indent {//订单表
    private long id;
    private String customername;
    private String number;
    private String allprice;
    private Date createDate;
    private Set<Product> products =new HashSet<Product>();//表达多对多
    public long getId() {
        return id;
    }
    public void setId(long id) {
        this.id = id;
    }
    public String getCustomername() {
        return customername;
    }
    public void setCustomername(String customername) {
        this.customername = customername;
    }
    public String getNumber() {
        return number;
    }
    public void setNumber(String number) {
        this.number = number;
    }
    public String getAllprice() {
        return allprice;
    }
    public void setAllprice(String allprice) {
        this.allprice = allprice;
    }
    public Date getCreateDate() {
        return createDate;
    }
    public void setCreateDate(Date createDate) {
        this.createDate = createDate;
    }
    public Set<Product> getProducts() {
        return products;
    }
    public void setProducts(Set<Product> products) {
        this.products = products;
    }
}

Indent.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.ManyAndManyTable">
<class table="indent" name="Indent">
<id name="id">
<generator class="native"></generator>
</id>
<property name="customername" />
<property name="number" />
<property name="allprice" />
<property name="createDate" />

<!-- 多对多关系表达 -->
<!-- 
name:集合属性名
table:中间表名
key column “我”的外键列名
class 多对多关系的类
column “别人”的外键名
 -->
<set name="products" table="middletable">
    <key column="indentid"></key>
    <many-to-many class="Product" column="productid"></many-to-many>
</set>

</class>
</hibernate-mapping>

测试代码 ManyAndManyTable.java

public class ManyAndManyTable {//多对多操作

    @Test
    //保存产品和订单
    public void funone(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();
        //创建一个日期对象
        Date date = new Date(System.currentTimeMillis());
//      DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//      String str = df.format(date);
//      System.out.println(str);
        //1.创建2个Product
        Product p1=new Product();
        p1.setName("手机");
        p1.setProduceDate(date);
        Product p2=new Product();
        p2.setName("电脑");
        p2.setProduceDate(date);
        //2.创建2个Indent
        Indent i1=new Indent();
        i1.setCustomername("abc");
        i1.setCreateDate(date);
        Indent i2=new Indent();
        i2.setCustomername("abc");
        i2.setCreateDate(date);
        //3.产品表达关系
        p1.getIndents().add(i1);
        p1.getIndents().add(i2);
        p2.getIndents().add(i1);
        p2.getIndents().add(i2);
        /*注意:多对多与多对一不同,在都不配置维护关系的前提下
         * 多对一通过修改外键维护关系,多对多通过中间表维护关系
         * 所以在多对多中,如果两个表都维护关系,两个表都会对中间表进行修改
         * 如果下面的  4.订单表达关系  代码不去掉,会发生插入两次相同数据的情况
         *关系维护重复 ,不符合数据库的约束原则,会发生错误
         * 如果不改变代码,必须要有一方放弃维护关系(建议使用)
         * 在当前实例下,订单应该放弃维护关系
         */
//      //4.订单表达关系
//      i1.getProducts().add(p1);
//      i1.getProducts().add(p2);
//      i2.getProducts().add(p1);
//      i2.getProducts().add(p2);
        //5.保存
        session.save(p1);
        session.save(p2);
        session.save(i1);
        session.save(i2);
        tx.commit();
        session.close();
    }
    @Test
    //向订单中加入一个产品
    public void funtwo(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();
        Date date = new Date(System.currentTimeMillis());
        //1.获得订单
        Indent indent = session.get(Indent.class,3l);//因为是long型,所以要加l
        //2.创建产品
        Product p=new Product();
        p.setName("衣服");
        p.setProduceDate(date);
        //3.向订单中加入一个产品
        indent.getProducts().add(p);
        //4.保存
        session.save(p);//如果配置级联保存,此行可以省略

        tx.commit();
        session.close();
    }
    @Test
    //向订单中删除一个产品
    public void funthree(){
        Session session = HibernateUtil.openSession();
        Transaction tx = session.beginTransaction();

        //1.获得订单
        Indent indent = session.get(Indent.class,3l);
        //2.获得要删除的产品
        Product product = session.get(Product.class, 7l);
        //3.向订单中删除一个产品
        indent.getProducts().remove(product);   
        tx.commit();
        session.close();
    }
}

猜你喜欢

转载自blog.csdn.net/bestmy/article/details/81067175