Hibernate 学习笔记02 --基础配置

1、知识点

1、  对应包:hibernate.0

2、  hibernate.cfg.xml:hbm2ddl.auto

3、  搭建日志环境并配置显示DQL语句

4、  搭建JUnit环境

a)        需要注意JUuit的Bug

5、  hibernate.cfg.xml:show_sql

6、  hibernate.cfg.xml:format_sql

7、  表名和类名不同,对表名进行配置

a)        Annotation:@Table

b)       xml:自己查询

8、  字段名和属性名相同

a)        默认为@Basic

b)       xml中不用写column

9、  字段名和属性名不同

a)        Annotation:@Column

b)       xml自己查询

10、  不需要persistence的字段

a)        Annotation:@Transient

b)       xml:不写

 

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

a)        Annotation:@Temporal

b)       xnl:指定type

12、  映射枚举类型

a)        @Enumerated

b)       xml:麻烦(不推荐)

13、  字段映射的位置(field或者get方法)

a)        Best Practice:保持filed和get set方法的一致

14、  @Lob

15、  课外:CLOB和BLOB类型的数据存取

16、  课外:Hibernate自定义数据类型

17、  Hibernate

 

2、hibernate.cfg.xml中的一些配置

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

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

        <propertyname="hbm2ddl.auto">create</property>

       关于hbm2ddl.auto的说明如下:

hibernate.hbm2ddl.auto

Automatically validates or exports schema DDL to the database when the SessionFactory is created. Withcreate-drop, the database schema will be dropped when theSessionFactory is closed explicitly.

e.g. validate | update | create | create-drop

3、使用JUnit测试程序

         我们知道,可以创建Hibernate文档建议的辅助类来获取会话工厂,这样一来方便,二来通过单例设计模式规定了只实例化一次会话工厂。除了创建这个辅助类,还可以使用@BeforeClass和@AfterClass来完成此要求。

package com.bjsxt.hibernate;

 

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.AnnotationConfiguration;

import org.junit.AfterClass;

import org.junit.BeforeClass;

import org.junit.Test;

 

public class StudentTest {

         private static SessionFactory sessionFactory;

         @BeforeClass

         public static void beforeClass() {

                            sessionFactory = new AnnotationConfiguration().configure().buildSessionFactory();

         }

         @AfterClass

         public static void afterClass() {

                   sessionFactory.close();

         }

        

         @Test

         public void testStudentSave() {

                   Student s = new Student();

                   s.setId(1);

                   s.setName("zhangsan");

                   s.setAge(8);

                  

                  

                   Session session = sessionFactory.getCurrentSession();

                   session.beginTransaction();

                   session.save(s);

                   session.getTransaction().commit();

         }

        

         public static void main(String[] args) {

                   beforeClass();  //检测BUG的方法,如果出现的话

         }

        

         @Test

         public void testStudentDelete() {

                  

         }

}

4、综合使用基础配置

4.1、使用Annotation形式来设置上面提到的基础配置

         首先建立Hibernate 4建议的工厂取得方法,写一个辅助类HibernateUtil:

package org.hibernate.tutorial.util;

 

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

 

public class HibernateUtil {

 

    private static final SessionFactory sessionFactory = buildSessionFactory();

 

    private static SessionFactory buildSessionFactory() {

        Configuration cfg = new Configuration();

        cfg.configure();

        ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(

                cfg.getProperties()).buildServiceRegistry();

        SessionFactory sessionFactory = cfg.buildSessionFactory(sr);

        try {

            // Create the SessionFactory from hibernate.cfg.xml

            // the following is deprecated:

            // return new Configuration().configure().buildSessionFactory();

            return sessionFactory;

        } catch (Throwable ex) {

            // Make sure you log the exception, as it might be swallowed

            System.err.println("Initial SessionFactory creation failed." + ex);

            throw new ExceptionInInitializerError(ex);

        }

    }

 

    public static SessionFactory getSessionFactory() {

        returnsessionFactory;

    }

}

         修改教师类teacher:

package com.wolex.hibernate.model;

 

//注意导入的包

import java.util.Date;

import javax.persistence.Column;

import javax.persistence.Entity;

import javax.persistence.EnumType;

import javax.persistence.Enumerated;

import javax.persistence.Id;

import javax.persistence.Table;

import javax.persistence.Temporal;

import javax.persistence.TemporalType;

import javax.persistence.Transient;

 

@Entity

// 指定数据表名为"teachers":

@Table(name = "teachers")

public class Teacher {

    private int id;

    private Stringname;

    private Stringtitle;

    private StringspouseName;

    private Datebirthday;

    private Sexsex;

 

    @Id

    @Column(length = 15)

    // 奇怪的是:如果一个映射类没有@Id,会报错;而且@Id属性的长度无法指定

    public int getId() {

        returnid;

    }

 

    @Column(name = "tname", length = 20)

    public String getName() {

        returnname;

    }

 

    // 不持久化的属性

    @Transient

    public String getSpouse() {

        returnspouseName;

    }

 

    @Column(length = 10)

    public String getTitle() {

        returntitle;

    }

 

    // 但只有一个值的时候,value可写可不写: @Temporal(value = TemporalType.TIME)

    // 枚举类TemporalType中的其他常量:DATETIMESTAMP

    @Temporal(TemporalType.TIME)

    public Date getBirthday() {

        returnbirthday;

    }

 

    // EnumType.ORDINAL表示采用枚举的序数(12。。。)

    @Enumerated(EnumType.STRING)

    @Column(length = 10)

    public Sex getSex() {

        returnsex;

    }

 

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

 

    public void setId(int id) {

        this.id = id;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public void setSpouse(String spouse) {

        this.spouseName = spouse;

    }

 

    public void setTitle(String title) {

        this.title = title;

    }

 

    public void setSex(Sex sex) {

        this.sex = sex;

    }

 

}

         注意,Hibernate中是可以配置没有主键的类映射表,但是在实际中表都存在主键(即使没有,也可以人为添加一个id列),对于@Id指定的属性没有指定长度,请参考ID生产策略。

         编写测试类TeacherTest:

package com.wolex.hibernate.model;

 

import java.util.Date;

import org.hibernate.Session;

import org.hibernate.tutorial.util.HibernateUtil;

import com.wolex.hibernate.model.Teacher;

 

public class TeacherTest {

    public static void main(String[] args) {

        Teacher tea = new Teacher();

        tea.setId(1);

        tea.setName("Theresa");

        tea.setTitle("中级");

        tea.setBirthday(new Date());

        tea.setSex(Sex.FEMALE);

        Session session = HibernateUtil.getSessionFactory().openSession();

        session.beginTransaction();

        session.save(tea);

        session.getTransaction().commit();

        session.close();

        HibernateUtil.getSessionFactory().close();

    }

}

Hibernate:

drop table teachers cascade constraints

Hibernate:

    create table teachers (

        id number(10,0) not null,

        birthday date,

        tname varchar2(20),

        sex varchar2(10),

        title varchar2(10),

        primary key (id)

)

Hibernate:

    insert

    into

        teachers

        (birthday, tname, sex, title, id)

    values

        (?, ?, ?, ?, ?)

         因为我们上面hbm2ddl.auto配置的是“create”,所以每次hibernate都会把先drop掉原来的表再生成。下面我们查询一下该表:

SQL> DESCRIBE teachers

 Name                                     Null?    Type

 ------------------------------------------------- ----------------------------

 ID                                        NOTNULL NUMBER(10)

 BIRTHDAY                                           DATE

 TNAME                                             VARCHAR2(20)

 SEX                                               VARCHAR2(10)

 TITLE                                             VARCHAR2(10)

SQL> SELECT * FROM teachers;

        ID BIRTHDAY        TNAME           SEX             TITLE

---------- --------------- --------------- ------------------------------

         1 04-JUN-13       Theresa         FEMALE          中级

         在Oracle 9i以前时间的数据类型就只有DATE一种,所以如果dialect设置为Oracle(anyversion),则上面TemporalType无论是TIME、DATE、TIMESTAMP都只会在数据库中映射为DATE类型。但是9i引入了两个新的、相关联的数据类型:INTERVAL和TIMESTAMP。

SQL Dialect设置为Oracle(anyversion):

<property name="dialect">org.hibernate.dialect.OracleDialect</property>

         SQL Dialect设置为Oracle 10g:

<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>

         那么如果SQL Dialect设置为10g后,Temporal.DATE和Temporal.time都会在数据库中映射为DATE数据类型,如果是Temporal.TIMESTAMP的话,则映射为TIMESTAMP数据类型。至于怎样映射为INTERVAL类型,未知?!

4.2、使用XML完成配置

package com.wolex.hibernate.model;

import java.util.Date;

 

public class Student {

    private int id;

    private Stringname;

    private long password;

    private Datebirthday;

    private DateregistrationDate;

 

    public int getId() {

        returnid;

    }

 

    public void setId(int id) {

        this.id = id;

    }

 

    public String getName() {

        returnname;

    }

 

    public void setName(String name) {

        this.name = name;

    }

 

    public Date getRegistrationDate() {

        returnregistrationDate;

    }

 

    public void setRegistrationDate(Date registrationDate) {

        this.registrationDate = registrationDate;

    }

 

    public long getPassword() {

        returnpassword;

    }

 

    public void setPassword(long password) {

        this.password = password;

    }

 

    public Date getBirthday() {

        returnbirthday;

    }

 

    public void setBirthday(Date birthday) {

        this.birthday = birthday;

    }

}

         Student类建立好了,下面配置其映射文件Student.hbm.xml:

<?xmlversion="1.0"?>

<!DOCTYPEhibernate-mapping PUBLIC

        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 

<hibernate-mappingpackage="com.wolex.hibernate.model">

    <classname="Student"table="students">

        <idname="id"column="stu_id"length="20"></id>

        <!-- 记得length="",不要忘了加双引号 -->

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

        <!-- <property name="password" type="java.math.BigDecimal" length="11"

            precision="2" scale="3"></property> -->

    <!-- 上面纠结了很久都改变不了最终生成表的number类型的长度与精度 -->

        <propertyname="password"></property>

        <propertyname="birthday"type="java.util.Date"></property>

        <propertyname="registrationDate"type="time"></property>

    </class>

 

</hibernate-mapping>

         这里使用到了length只有在类中field的类型是String的时候才有效,如果是int、long等都无效,原因未知!??注意birthdayregistrationDate分别设置为不同的类型。

         在hibernate.cfg.xml中添加:

<mapping resource="com/wolex/hibernate/model/Student.hbm.xml"/>

         编写测试类,此次不使用hibernateUtil辅助类:

package com.wolex.hibernate.model;

import java.util.Date;

import org.hibernate.HibernateException;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.cfg.Configuration;

import org.hibernate.service.ServiceRegistry;

import org.hibernate.service.ServiceRegistryBuilder;

import com.wolex.hibernate.model.Student;

 

public class StudentTest {

    public static void main(String[] args) {

        Student stu = new Student();

        stu.setId(1);

        stu.setName("Cyndi");

        stu.setPassword(219341);

        stu.setBirthday(new Date());

        stu.setRegistrationDate(new Date());

 

        Configuration cfg = new Configuration();

        cfg.configure();

        SessionFactory sf;

        try {// 主要为了观察错误原因

            ServiceRegistry sr = new ServiceRegistryBuilder().applySettings(

                    cfg.getProperties()).buildServiceRegistry();

            sf = cfg.buildSessionFactory(sr);

            Session session = sf.openSession();

            session.beginTransaction();

            session.save(stu);

            session.getTransaction().commit();

            session.close();

            sf.close();

        } catch (HibernateException e) {

            e.printStackTrace();

        }

    }

}

         查询students表,观察结果:

SQL> DESCRIBE students;

 Name                                     Null?    Type

 ------------------------------------------------- ----------------------------

 STU_ID                                    NOT NULLNUMBER(10)

 SNAME                                              VARCHAR2(20CHAR)

 PASSWORD                                          NUMBER(19)

 BIRTHDAY                                          TIMESTAMP(6)

 REGISTRATIONDATE                                  DATE

SQL> SELECT * FROM students;

    STU_ID SNAME        PASSWORD BIRTHDAY                       REGISTRAT

---------- ---------- ---------- ---------------------------------------

         1 SoYeon         219341 04-JUN-13 07.21.00.329000PM   04-JUN-13

         可见birthday字段的类型是TIMESTAMP,如果java类中属性类型为java.util.Date,那么Student.hbm.xml文件中的type不设置,则默认设置为java.util.Date。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值