hibernate学习笔记

    技术2022-06-27  51

    1.hibernate 的配置文件可以是.cfg.xml(可读性强)类型的 也可以是 .propertes 类型的。2.mysql 的hibernate 配置文件,配置数据库连接时URL 中localhost:3306 可以用///代表。3.当我们有实体类 ,还有映射文件也配置好了以后就是差数据库里面没有对应的表时:我们可以告诉配置文件让它自己在数据库里面创建对应的表,但需要在hibernate.cfg.xml中加上属性节点<property name="hbm2ddl.auto">create</property>//create表示他每次运行都重新创建并删除原来的(测试是可以用,平时不要用)//create-drop表示他每次运行都创建并结束后就删除(看不出效果)//update 会自动更新原有的表的结构来符合将需要的表在现实中上面三种值 不利用到程序的运行上的,不实在。//validate  表示没有对应的表时就发生异常4. transient (瞬时) 就是与session 无关的,并且 数据库也没有该对象信息的   detached(脱管)session 已经关闭,但是数据库里面有该对象的信息   persistent(持久) 与session 有关(session 没有关闭),数据库里面也有该对象信息5.多对一<many-to-one name="user" column="uid"/> name="’多‘的一方的属性(是一个对象)名" column="多的一方(本类)的数据库表的外键uid"hibernage 读到这里的信息,自己会知道根据user对象 找到它的映射文件 默认是user 对象的主键id 对应数据库表的uid ,所以我们平时用就不必要配置她的信息,当我们数据库的uid 不是对应 user对象的主键时就必须告诉hibernate 如下:<many-to-one name="user" column="uid" property-ref="name"/>这样 它 就知道数据库表uid 对应user对象的name 属性。当我们不指定column 时,他会默认字段名跟数据库表列名一致,一般我们是指定的 6.当得到 某一对象时 ,而此对象的属性也包含对象,我要得到子对象的其他信息直接   对象.属性.getname(); 会报错,在得到父对象时还没有提交之前取就行,如果想取到了父对象后 ,再取父对象的属性(也是一个对象),也根据get方法取到子对像的其他属性值 要在去父对象时初始化 : HIbernate.initialize(父对象.get属性);//get属性(属性是存对象的) 就如我们所愿 了,7.一对多 ,一(depart)的一方有属性 private Set emps;//每个部门有多个员工部门表的映射文件 有:<set name="emps">     <key column="depart_id"/>     <one-to-many  class="Employee" /></set>//这样hibernate 会知道 根据depart_id 在Employee表中查询depart部门的员工8. 一对一(人跟身份证) 人的实体中有 身份证的类对象 的属性 身份证的实体中有人的类对象 的属性8.1. 身份证映射文件;<id name="id">  <generator class="foreign">      <param name="property">person</param>  //身份证的id 不用自己产生,是通过自己的属性person 取到的  </generator></id ">/...<one-to-one name="person" constrained="true"/>//身份证的id 是主键 也是外键//constrained="true" 表示加上约束8.2下面是身份证表,跟上面不同的是主键是自动产生,身份证号是外键这样映射文件要更改一下<id name="d">  <generator class="native" /></id ">/...<many-to-one name="person" column="person_id"  unique="true"/> //这样成了多对一,加上唯一约束才能保证身份证号唯一,同时怕person 映射文件也要注意修改为:<class name="Person"><id name="id" > <generator class="native"/></id> <property name="name"/> <one-to-one name="idCard" property-ref="person"/></class>//表明人根据自己的属性idCard 找IdCard类中person 属性 根据跟自己一致才知道这个身份证是自己的默认是映射到IdCard表的主键,现在我们需要的不是主键,所以要 property-ref="person" 告诉我们要的是person9. 多对多  中间关联表teacher-studer  有Student_id,Teacher_id 两个字段。

    Teacher 类int  idstring teacherNameSet<Student> students;映射文件:<class name="Teacher" table="teacher">    <id name="id">         <generator class="native"/>   </id>   <set name="students"  table="teacher-student">     <key column="Teacher_id"/>     <one-many  class="Student"  column="Student_id" />  </set></class>Student 类int  idstring studentNameSet<Teacher> teachers;映射文件:<class name="student" table="student">    <id name="id">         <generator class="native"/>   </id>   <set name=" teachers"  table="teacher-student">     <key column="Student_id"/>     <one-many  class="Teacher"  column="Teacher_id" />  </set></class>多对对时:不能都告诉对方要么:告诉学生有什么老师要么:告诉老师有什么学生如果两个都告诉 就会报错 ,因为中间表teacher-student 他的主键是有两个外键(Teacher_id,Student_id)组成两个都告诉的话,他会重复插入中间表数据,主键就重复了,所以只告诉两方其中一方就行了。 9. 两个对象同时放在一个数据库表中时:数据库Tuser表  字段:id , first_name,last_name,birthday;User 类:  属性: int id  ,   Name name ,  Date birthdayName 类:  属性: String firstName,String lastNameUser的映射表如下:<class name="User" table="Tuser">    <id name="id">         <generator class="native"/>   </id>  <componet name=" name" >     <property name="firstName" column="first_name"/>     <property name="lastName" column="last_name"/></componet>10.使用的集合    set 是我们常用的   list 用法也一样 只是它会自动拍下,这样数据库里面要有一个排序的列  映射文件跟set一样,但多一个元素 <list-index column="要排序的列名"/><class name="student" table="student">    <id name="id">         <generator class="native"/>   </id>   <set name=" teachers"  table="teacher-student">     <key column="Student_id"/>    <list-index column="要排序的列名"/>     <one-many  class="Teacher"  column="Teacher_id" />  </set></class>  list集合 的配置文件也可以这样写<class name="student" table="student">    <id name="id">         <generator class="native"/>   </id>   <bug name=" teachers"  table="teacher-student">     <key column="Student_id"/>     <one-many  class="Teacher"  column="Teacher_id" />  </bug></class>这样写它就不再排序了。还有map 做法跟set 如下一样:<class name="student" table="student">    <id name="id">         <generator class="native"/>   </id>   <map name=" teachers"  table="teacher-student">     <key column="Student_id"/>   <map-key type="string"  column="name"/>     <one-to-many  class="Teacher"  column="Teacher_id" />  </map></class>也是多了一列:  <map-key type="string"  column="name"/>

    还有一个集合就是 数组: 跟上面类似

    总结:实体类中那些集合属性 的类型必须是接口,不是类,比如:set 是接口,List是接口 Map是接口,如果换为HasHmap时就会出错,因为他是接口的实现类,是一个类。在Hibernate 运行的时候它都会把那些接口都转换为persistenSet 接口,这个接口是JDk里面的接口。11.级联配置cascade="all"其中可以取到的值有:all,delete,save-update,lock,refresh,evict,replicate,persist,none,merge,delete-orphan(one-to-many 的时候),一般多对一,对多对不设置级联。12. inverse="true"  这个属性不能在有序的集合里面用而且inverse 只有在集合里面有这个属性,hebernate 只允许一的一方放弃维护 不允许多的一方放弃13.cascade="all" 在删除多的一方是如果不成功的话,去掉就行了(经验)。影响cascade的原因是lazy="false" 延迟加载有个写死的方法:就是把这个lazy="false" 去掉,接着我在 在PetInfo pet= (PetInfo)session.get(petInfo.class,id) 把取到的对象写死取到(PetInfo) 再跟多这一句   pet.getSets();  之后再 tx.commit 然后才session.close();其他方法也可以...cascade="delete" 不要all 就搞定14 .类的继承比如普通类Employer员工表 里面有子类 销售类ssales和skill技术类则Employer映射文件下比平时添加多的元素

    <class name="Employer" table="employer" discriminator-value="0" >    <id name="id">         <generator class="native"/>   </id>  <property name="name" column="name"/><discriminator column="type(数据库类型列)" type="int"/><!--鉴别器是给Hibernate用的--><subclass name="skill" discriminator-value="1">       <property name="子类的属性"/></subclass><subclass name="sales" discriminator-value="2">       <property name="子类的属性"/></subclass></class>用的时候跟平时一样,实例化子类,用父类接收。discriminator-value="2" 意思是普通员工type=0 技术type=1 销售type=2而实体类不用有type 段 因为这是给Bibernate用 他根据你保存的类型然后找到对应的类型帮你自动插入, 然后取对象的时候,取出来就是相对应的类(子类或者父类)还有一个<joined-subclass  /> 两个子类一直表的用法


    最新回复(0)