Hibernate Note

一、hibernate db中数据类型对照(xml方式)

1.ORACLE常用数据类型对照

         背景为灰色的表示常用,熟记。

                  

Hibernate 类型

Java类型

Oracle类型

type="java.lang.Long"

Java.lang.Long

NUMBER

java.lang.String

String

Varchar2

java.lang.Double

Double

NUMBER

java.sql.Timestamp

Java.util.Date

TIMESTAMP(6)

type="java.lang.String"

String

CHAR(1)

java.sql.Timestamp

Java.util.Date

TIMESTAMP(6)

        

        

<hibernate-mapping>

 <class  name="com.besttone.domain.OrderHead"  table="ORDER_HEAD">

   <id name="orderHeadId"  type="java.lang.Long">

    <!--     <generator  class="sequence">

                            <param  name="sequence">ORDER_HEAD_SEQ</param>

                   </generator>   -->

         <column  name="ORDER_HEAD_ID" precision="22"  scale="0"/>

     <generator class="sequence" />

   </id>

   <property name="userId"  type="java.lang.String">

    <column length="60" name="USER_ID"/>

   </property>

   <property name="productId"  type="java.lang.Long">

    <column name="PRODUCT_ID" precision="22"  scale="0"/>

   </property>

   <property name="payTotal"  type="java.lang.Double">

    <column name="PAY_TOTAL" precision="22"  scale="0" />

   </property>

   <property name="createdDate"  type="java.sql.Timestamp">

    <column length="11" name="CREATED_DATE"/>

   </property>

</class>

</hibernate-mapping>

 

2.MySql数据类型对照

背景为灰色的表示常用,熟记。

2.1 hibernate mysql 基本类型映射

Hibernate 映射类型

Java 类型

标准 SQL 类型

大小和范围

integer 或者 int

int 或者 java.lang.Integer

INTEGER

4 字节

long

long  Long

BIGINT

8 字节

short

short  Short

SMALLINT

2 字节

byte

byte  Byte

TINYINT

1 字节

float

float  Float

FLOAT

4 字节

double

double  Double

DOUBLE

8 字节

big_decimal

java.math.BigDecimal

NUMERIC

NUMERIC(8,2)8 位

string

char  Character  String

CHAR(1)

定长字符

string

String

VARCHAR

变长字符串

boolean

boolean  Boolean

BIT

布尔类型

2.2 Java 时间和日期类型的 Hibernate映射

映射类型

Java 类型

标准 SQL 类型

描述

date

util.Date 或者 sql.Date

DATE

YYYY-MM-DD

time

Date    Time

TIME

HH:MM:SS

timestamp

Date   Timestamp

TIMESTAMP

YYYYMMDDHHMMSS

calendar

calendar

TIMESTAMP

YYYYMMDDHHMMSS

二、Hibernate 关系配置

1.annotation基本类型配置

         配置、Jar包等:

a)      hibernateannotaion jar

b)      ejb3persistence jar

c)      hibernatecommon-annotations.jar

FAQ: @不给提示,配置eclipse属性信息contentassist-activation--加上@

 

通过 @Basic 可以声明属性的存取策略:

@Basic(fetch=FetchType.EAGER)  即时获取(默认的存取策略)

@Basic(fetch=FetchType.LAZY)   延迟获取

 

通过 @Temporal 定义映射到数据库的时间精度:

@Temporal(TemporalType=DATE)      日期

@Temporal(TemporalType=TIME)      时间

@Temporal(TemporalType=TIMESTAMP) 两者兼具

2. annotation 列属性映射

使用 @Column 映射到列

@Column(

name="columnName";   // 可选,列名(默认是属性名)

boolean unique() default false; //可选,是否在该列上设置唯一约束(默认 false

boolean nullable() default true; //可选,是否可以为空

boolean insertable() default true; //可选,该列是否作为生成insert语句中的一列

boolean updatable() default true; //可选,该列是否作为生成update语句中的一列

String columnDefinition() default ""; //可选,为这个特定列覆盖SQL DDL 片段(可能导致无法在不同数据库间移植)

String table() default ""; //可选,定义对应的表,默认为主表

int length() default 255;   //可选,列长度

int precision() default 0; //可选,列十进制精度(decimalprecision

int scale() default 0; // 可选,列十进制数范围(decimal scale

 

public class Person {

    @Column(name ="PERSONNAME", unique = true, nullable = false, updatable = true)

    private String name;

 

    @Column(name ="PHOTO", columnDefinition = "BLOB NOT NULL",secondaryTable="PER_PHOTO")

    private byte[] picture;

}

3.联合主键:

         必须实现 poSerializable接口

         <classname="Student" table="t_student">

                   <composite-idname="studentId" class="StudentId">

                            <key-propertyname="firstName" length="20"></key-property>

                            <key-propertyname="lastName"         length="20"></key-property>

                   </composite-id>

                   <propertyname="pwd" length="20"></property>

         </class>

4. 组合关系

         <class  name="User"  table="t_user"  >

                   <id  name="id">

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="name"></property>

                  <property name="phone"column="dianhua" length="30"></property>

                  

                   <componentname="address" class="Address"     >

                            <propertyname="city"></property>

                            <propertyname="street"></property>

                            <propertyname="zipcode"></property>

                   </component>

         </class>

5. 一对多,多对一

5.1  xml格式的:

        一方:

         <classname="Department" table="t_dept">

                   <idname="id" >

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="dname" length="20"></property>

                   <setname="employees" >

                            <key>

                                     <columnname="department_id"></column>

                            </key>

                            <one-to-many  class="Employee"/>

                   </set>

         </class>

        多方:

         <classname="Employee" table="t_emp">

                   <idname="id">

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="ename"></property>

                   <many-to-onename="department" class="Department"column="department_id">

                   </many-to-one>

         </class>

        

5.2  annotation方式的:

        多方:

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString mname;

         @ManyToOne

         privateStudent student;

        一方:

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString sname;

         privateString pwd;

         @OneToMany(mappedBy="student")

         privateSet<Money> moneys;

6. 一对一 外键关联

6.1  xml格式的:

         <classname="Address" table="t_address" >

                   <idname="id">

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="aname" length="20"></property>

                   <one-to-one name="company"class="Company"property-ref="address"></one-to-one>

         </class>

        

         <classname="Company" table="t_com" >外键生成

                   <idname="id">

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="cname" length="20"></property>

                   <many-to-one name="address"class="Address" cascade="save-update">

                           <column name="address_id"unique="true"></column>

                  </many-to-one>

         </class>

        

6.2  annotation格式的:

        

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString cname;

         @OneToOne(cascade=CascadeType.ALL)

         @JoinColumn(name="student_id",unique=true)

         privateStudent student;

        

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString sname;

         @OneToOne(mappedBy="student")

         privateCourse course;

        

6.3  一对一主键关联

         annotation格式的:

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString cname;

         privateInteger age;

         privateString des;

         @OneToOne(cascade=CascadeType.ALL)

         @PrimaryKeyJoinColumn

         privateStudent student;

        

         @Id

         @GenericGenerator(name="cc",strategy="foreign",parameters={@Parameter(name="property",value="course")})

         @GeneratedValue(generator="cc")

         privateInteger id;

         privateString sname;

         privateInteger age;

         privateString des;

         @OneToOne(mappedBy="student",cascade=CascadeType.ALL)

         privateCourse course;

7. 多对多

7.1  xml格式的:

xml格式的:

         <classname="Course" table="t_course">

                   <idname="id" >

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="cname" length="20"></property>

                   <setname="students" table="student_course">

                            <key>

                                     <columnname="course_id"></column>

                            </key>

                   <many-to-manyclass="Student" column="student_id"></many-to-many>

                   </set>

         </class>

        

         <classname="Student" table="t_student">

                   <idname="id" >

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="sname" length="20"></property>

                   <setname="courses" table="student_course">

                            <key>

                                     <columnname="student_id"></column>

                            </key>

                            <many-to-manyclass="Course" column="course_id"></many-to-many>

                  

                   </set>

         </class>

        

7.2  annotation格式的:

        

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString mname;

         @ManyToMany(mappedBy="moneys")

         privateSet<Student> students;

        

         @Id

         @GeneratedValue(strategy=GenerationType.AUTO)

         privateInteger id;

         privateString sname;

         privateString pwd;

         @ManyToMany

         privateSet<Course> moneys;

8. 其他

8.1不需要psersistence的字段

a)      Annotation@Transient

b)      xml不写

8.2映射日期与时间类型,指定时间精度

a)      Annotation@Temporal(参数)参数有3种只显示时间,只显示日期,时间日期都显示

              //@Temporal(TemporalType.DATE) 只显示日期

              //@Temporal(TemporalType.TIME) 只显示时间

              //@Temporal(TemporalType.TIMESTAMP) 显示日期与时间

b)      xml:指定 type

<class name="Teacher"table="Teacher" >

<id name="id"column="id"></id>

                   propertyname="name" type="time" />

              </class>

三、hibernate序列Sequence

    <id name="id" >

             <generatorclass="native"></generator>

    </id>

    其他常用的序列生成方式

1.      <generator class="sequence"/>

这是一个非常简单的接口;某些应用程序可以选择提供他们自己特定的实现。当然,Hibernate提供了很多内置的实现。下面是一些内置生成器的快捷名字:

2.      increment(递增)

用于为long, short或者int类型生成唯一标识。只有在没有其他进程往同一张表中插入数据时才能使用。 在集群下不要使用。(补充:主键按数值顺序递增,此方式的实现机制为在当前实例中维持一个变量,以保存着当前的最大值,之后每次需要生成主键的时候在此值上加1作为主键,可能产生的问题:如果当前有多个实例访问同一个数据库,那么由于各个实例都维持主键状态,不同实例可呢生成同样主键,从而造成主键重复异常,因此,如果同一个数据库有多个实例访问,此方式必须避免使用。)

3.      sequence(序列)

DB2,PostgreSQL,Oracle, SAP DB, McKoi中使用序列(sequence),而在Interbase中使用生成器(generator)。返回的标识符是long, short或者 int类型的。

4.      uuid.hex

用一个128-bitUUID算法生成字符串类型的标识符。在一个网络中唯一(使用了IP地址)。UUID被编码为一个3216进制数字的字符串。

5.      native(本地)

根据底层数据库的能力选择identity, sequence 或者hilo中的一个。(详解:由hibernate根据数据库适配器中的定义,自动采用identifyhilosequence的其中一种作为主键生成方式)

6.      idannotation方式

@GeneratedValue

a)      自定义ID

b)      AUTO(直接写 @GeneratedValue相当如native)

i.       默认:对 MySQL,使用auto_increment

ii.      Oracle使用hibernate_sequence(名称固定)

c)      IDENTITY(@GeneratedValue(strategy=GenerationType.IDENTITY))

d)      SEQUENCE(@GeneratedValue(strategy=GenerationType.SEQUENCE))

i.       @SequenceGenerator(可自定义在数据库生成指定的sequence)

                @Id

//@GeneratedValue中增加 generator="teacherSEQ"

@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="teacherSEQ")

//"teacherSEQ"@SequenceGenerator的标识名

//"teacherSEQ_DB"为指定到数据库生成的Sequence

@SequenceGenerator(name="teacherSEQ",sequenceName="teacherSEQ_DB")

public intgetId() {

                                     returnid;

}

四、hibernate 配置

1.日志配置

a)        slf4j与log4j的关系:slf4j像是一个大管家,可以管理许多的日志框架,log4j是其中之一

b)       加入slf4j-log4j.jar,加入 log4j 的 jar 包,去掉 slf4-nop.jar

c)        从hibernate/project/etc目录 copy log4j.properties

2. hibernate.cfg.xml配置文件

<!--显示输出sql-->

show_sql

     <!--格式化显示输出sql -->

       <propertyname="format_sql">true</property>

 

 

五、hibernate 联合主键

1.   xml方式: composite-id

        i.   将联合主键的属性提取出来,重新编写一个pojo类(原pojo类中的id,name要删除并新加入属性“StudentPK”)

       public class StudentPKimplements Serializable {

                   privateString id;

                   privateString name;

                   … …

       ii.   新建pojo类必须实现 java.io.Serializable序列化接

      iii.   新pojo类要重写equals和hashCode方法

@Override

public boolean equals(Object o) {

       if(o instanceofStudentPk) {

              StudentPk pk =(StudentPk)o;

              if(this.id ==pk.getId() && this.name.equals(pk.getName())) {

                return true;

              }

       }

       return false;

}

 

@Override

public int hashCode() {

       returnthis.name.hashCode();

}

       iv.   联合主键生成策略XML配置方法

     <hibernate-mapping>

                   <classname="com.bjsxt.pojo.Student" >

                            <composite-idname="studentPK" class="com.bjsxt.pojo.StudentPK">

                                      <key-propertyname="id"></key-property>

                                     <key-propertyname="name"></key-property>

                            </composite-id>

                            <propertyname="age" />

                            <propertyname="sex" />

                            <propertyname="good" type="yes_no"></property>

                   </class>

</hibernate-mapping>

2.   Annotation方式

        i.   前三步与Xml方式前三步一样 都要建立新pojo类 都要实现Serializable接口 重写equals和hashCode方法.

       ii.   方法1在新类前写@Embeddable,在原pojo类的新属性“TercherPK”的get方法前写@ld,如下

      @ Embeddable

public class TeacherPK implements Serializable {

                   privateString id;

                   privateString name;

                   … …

 

             @Entity

publicclass Teacher {

private TeacherPK teacherPK ;

@Id

public TeacherPK getTeacherPK(){

                            return teacherPK;

}

… …

      iii.   方法2:@EmbeddedlD(*) 新pojo类无需加注解,只需在原pojo类新属性“TercherPK”的get方法前写@EmbeddedlD即可

                    iv.       方法3:@ld  @IdClass(*)  新pojo类无需加注解,原pojo类的id,name属性保留不变,也无需新增“TercherPK”属性。 只在id,name的get方法前都加@Id,并在原pojo类前加@IdClass(TeacherPK).class),如下

@Entity

@IdClass(TeacherPK.class)

public class Teacher {

private String id;

private String name;

@Id

public String getId() {

              return id;

}

@Id

public String getName() {

              return name;

}

 

六、hibernate 核心开发

1.   Configuration

a)  AnnotationConfiguration

b)  进行配置信息的管理

c)  用来产生SessionFactory

d)  可以在configure方法中指定hibernate配置文件

e)  只气关注一个方法即:buildSessionFactory

2.    SessoinFactor

1)  用来产生和管理Session

2)  通常情况下每个应用只需要一个SessionFactory

3)  除非要访间多个数据库的情况

4)  关注两个方法即:openSession getCurrentsession

         i.   open session每次都是新的,需要close

       ii.   getCurrentsession从上下文找,如果有,用旧的,如果没有,建新的

1.  用途,界定事务边界

2.  事务提交自动close

3.  上下文配置可参见xml文件中

        <property name="current_session_context_classs">thread</property>

4.  current_session_context_class (jta、thread常用 managed、custom.Class少用)

          a) thread 使用connection 但数据库连接管理事务

          b)jta (全称java transaction api)-java分布式事务管理(多数据库访问)

            jta由中间件提供(jboss WebLogic等,tomcat不支持)

3.Session

a)   管理一个数据库的任务单元(简单说就是增 删 改 查

b)   方法(CRUD)

          i.   get与load的区别

1.            不存在对应记录时表现不一样

2.            load返回的是代理对象,等到真正用到对象的内容时才发出sql语句

3.            get直接从数据库加载,不会延迟

        ii.   updates

1.            用来更新detached对象,更新完成后转为persistent状态

2.            更新transient对象会报错

3.            更新自己设定id的transient对象可以(数据库有对应记录)

4.            persistent状态的对象只要设定(如:t.setName…)不同字段就会发生更新

5.            更新部分更改的字段

a)xml 设定property 标签的 update 属性,annotation 设定@Column 的 updatable

   属性,不过这种方式很少用,因为不灵活

b)使用xml中的dynamic-update,JPA1.0 Annotation 没有对应的属性,hibernate 扩

   展?

i. 同一个session可以,跨session不行,不过可以用merge()(不重要

c)使用 HQL(EjBQL)(建议)

       iii.   clear方法

1.无论是load还是get,都会首先査找缓存(一级缓存),如果没有,才会去数据库査找

clear()方法可以强制清除session缓存

        iv.   flush()方法

1.            当session的事务提交后,会强制将内存(session缓存)与数据库同步.默认情况下是session的事务提交(commit)时才同步!

2.            session的FlushMode设置,可以设定在什么时候同步缓存与数据库(很少用)

例如: session.setFlushMode(FlushMode.AUTO)

七、hibernate 对象的三种状态

1.    三种状态的区分关键在于

i.       有没有ID

ii.      ID在数据库中有没有

iii.     在内存中有没有(session缓存)

        

2      三种状态:

a)      transient:内存中一个对象,没ID,缓存中也没有

b)      persistent:内存中有,缓存中有,数据库有(ID)

c)      detached:内存有,缓存没有,数据库有,ID

八、hibernate id特殊配置

       1. 组合关系

         <class  name="User"  table="t_user"  >

                   <id  name="id">

                            <generatorclass="native"></generator>

                   </id>

                   <propertyname="name"></property>

                   <propertyname="phone" column="dianhua"  length="30"></property>

                  

                   <componentname="address" class="Address"     >

                            <propertyname="city"></property>

                            <propertyname="street"></property>

                            <propertyname="zipcode"></property>

                   </component>

         </class>

       2.

九、hibernate 注意事项

1.    Hibernate中,POJO类要重写hashcode()方法和equals()方法。

1)     重点是equals,重写hashCode只是技术要求(为了提高效率)

2)     为什么要重写equals呢,因为在java的集合框架中,是通过equals来判断两个对象是否相等的.如果没有用到比较这些的,也可以不重写equals.

3)     hibernate中,经常使用set集合来保存相关对象,而set集合是不允许重复的,但是下面的程序,判断一下运行结果:Set user = newHashSet();

user.add(newAddress("http://hi.baidu.com/yangwen_yw"));

user.add(newAddress("http://hi.baidu.com/yangwen_yw"));

System.out.println(user.size());

上面程序的运行结果取决于Address类是否重写了equals方法。

如果没有重写,默认equals是比较地址,那么这两个address对象不一样,输出2,意味着hibernate会认为这是两个对象,再接下来的持久化过程中可能会出错。

如果重写了equals,比如按照主键(address空间地址)比较,那么这两个对象是一样的,输出1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值