创建位置一般在实体类所在的包中 名称一采用实体类名.hbm.xml 约束文件 “-//Hibernate/Hibernate Mapping DTD 3.0//EN” “http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd”>
<hibernate-mapping> <!-- 配置实体类和表的对应 --> <class name="com.hibernate.entry.User" table="user"> <!-- 配置实体类的id属性,对应于表的id,要求唯一才行 --> <id type="int" name="id" column="id"> <!-- 设置主键自动增长,有很多值 --> <generator class="native"></generator> </id> <!-- 其他属性的配置 --> <property name="userName" column="userName"></property> <property name="password" column="password"></property> </class> </hibernate-mapping>位置和名称固定:位置在src下,名字叫hibernate.cfg.xml 约束文件 “-//Hibernate/Hibernate Configuration DTD 3.0//EN” “http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd”>
<hibernate-configuration> <session-factory> <!-- 1.配置数据库信息,必须 --> <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property> <property name="hibernate.connection.url">jdbc:mysql:///hibernate</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password"></property> <!-- 2.配置hibernate信息,可选 --> <!-- 执行的时候输出底层的SQL语句 --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL语句 --> <property name="hibernate.format_sql">true</property> <!-- hibernate帮助自动创建表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置数据库的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 3.把映射文件都放到本核心配置文件中,因为hibernate只会加载核心配置文件 --> <mapping resource="com/hibernate/entry/User.hbm.xml"/> </session-factory> </hibernate-configuration>数据库表创建成功,数据插入成功,小问题是出现了中文问题
当在以上3中状态中调用session.saveOrUpdate();方法的时候, 瞬时态会执行save,持久态和托管态会执行update
一对多 : 在多的那张表里有一个字段作为外键,这个外键指向一的那张表的主键
多对多 : 生成第三张表,这个表至少包含其他两个表的主键
(1)建立实体类
代码类似,不再演示(2)让实体类中两方能够互相表示
在一的一方(客户),使用set集合保存多的一方,并建立get和set方法: private Set<LinkMan> setLinkMans=new HashSet<LinkMan>(); 在多的一方,使用一的实体对象来表示,并建立get和set方法: private Customer customer;(3)配置文件中做配置,并建立映射关系
在一的一方,配置如下: <!--name:就是实体类中set的名字--> <set name="setLinkMans"> <!-- 配置外键,外键是值就是外键的名称 --> <key column="clid"></key> <!-- 配置的是联系的那个实体类全路径 --> <one-to-many class="com.hibernate.entry.LinkMan"/> </set> 在多的一方,配置如下: <!-- 配置和customer实体类相联系 ,column是外键名称,两个配置文件中的外键名称一致--> <many-to-one name="customer" class="com.hibernate.entry.Customer" column="clid"></many-to-one> 多对多实现 实现步骤与上面相同,只是配置不同 <!--name指实体类中set集合名称, table指第三张表的名称 --> <set name="setRoles" table="user_role"> <!-- column指当前映射文件在第三张表中的外键名称 --> <key column="userid"></key> <!-- class对应另一个多的全路径,column指这个多在第三张表的外键名称 --> <many-to-many class="com.hibernate.many2many.Role" column="roleid"></many-to-many> </set> ------------------------------------------------------------------------------- <set name="setMUsers" table="user_role"> <key column="roleid"></key> <many-to-many class="com.hibernate.many2many.MUser" column="userid"></many-to-many> </set> </class>(1)级联保存
/* * 这是一种比较麻烦的方法, * 建立一的实体类,建立多的实体类,分别表示对方,最后分别保存 */ public static void save1() { SessionFactory sessionFactory=null; Session session=null; Transaction tx=null; try { sessionFactory =Util.getSessionFactory(); session =Util.getSession(); tx=session.beginTransaction(); Customer customer=new Customer(); customer.setCname("shen"); customer.setCpassword("123456"); LinkMan linkMan=new LinkMan(); linkMan.setLname("zhu"); linkMan.setLpassword("123456"); //互相表示对方 customer.getSetLinkMans().add(linkMan); linkMan.setCustomer(customer); //分别保存 session.save(customer); session.save(linkMan); tx.commit(); } catch (Exception e) { e.printStackTrace(); } finally{ // session.close(); sessionFactory.close(); } } /* * 这是一种比较简单的写法,需要配置,底层实现还是一样的思想 */ -------------------------------------------------------------- 配置:在一的一方的配置文件中加入级联(cascade="save-update"): <set name="setLinkMans" cascade="save-update"> -------------------------------------------------------------- Customer customer=new Customer(); customer.setCname("chao"); customer.setCpassword("123456"); LinkMan linkMan=new LinkMan(); linkMan.setLname("ping"); linkMan.setLpassword("123456"); //不用再互相保存对方了,只需要将linkman添加到set中去 customer.getSetLinkMans().add(linkMan); //不用分别保存了,只需要保存customer session.save(customer);(2)级联删除
/* * 配置了之后,进行级联删除 * 查询然后直接调用delete方法 */ ---------------------------------------------------------------- 配置在一的一方: <set name="setLinkMans" cascade="save-update,delete"> ---------------------------------------------------------------- 删除代码: Customer customer=session.get(Customer.class, 2); session.delete(customer);(3)级联修改
需求就是把某一个客户的联系人变成另一个客户的联系人
该修改方式有一个弊端,因为hibernate是对外键双向维护的,就造成2次数据库对多的一方的更新,解决的方式是:让一的一方放弃维护外键
<set name="setLinkMans" cascade="save-update,delete" inverse="true"> 不需要配置,思想如下: 1.获取目标客户实体对象, 2.获取目标联系人实体对象, 3.将联系人添加到客户,再将客户添加到联系人中 因为这2个实体对象都是持久态的数据,不需要调用session的方法,提交后就会更新数据库 多对多级联(1)多对多级联保存,类似于一对多操作
(2)多对多级联删除,类似于一对多操作
* 多对多维护第三张表 *
对于多对多的操作思想是:将两个多方分别操作,剩下的就是操作第三张表,就能完成功能.比如: User user=session.get(User.class,2); Role role=session.get(Role.class,3); //增加关系 user.getSetRoles().add(role); //删除关系 user.getSetRoles().remove(role);