Hibernate框架基本使用
阅读原文时间:2023年07月12日阅读:2

时间:2017-1-16 00:36

——什么是Hibernate

    Hibernate是一个开放源代码的关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以使用对象编程思维来操作数据库。

    Hibernate可以应用在任何使用JDBC的场景,既可以在Java的客户端程序使用,也可以在Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE框架中取代CMP,完成数据持久化的重任。

    Hibernate是轻量级JavaEE应用的持久层解决方案,是一个关系数据库ORM框架:
        *   ORM(Object Relation Mapping),对象关系映射,就是通过将Java对象映射到数据库表,通过操作Java对象,就可以完成对数据表的操作。

    Hiernate提供了对关系型数据库的增删改查操作。

    流行数据库框架:
        *   JPA(Java Persistence API),JPA通过JDK5.0注解或XML描述对象 - 关系表的映射关系(只有接口规范)
        *   Hibernate最流行ORM框架,通过对象 - 关系映射配置,可以完全脱离底层SQL。
        *   MyBatis是Apache的一个开源项目iBatis,支持普通SQL查询,存储过程和高级映射的优秀持久层框架。
        *   Apache DBUtils、SpringMVC、JDBCTemplate

——为什么学习Hibernate

1、Hibernate对JDBC访问数据库的代码做了封装,大大简化了数据访问层繁琐的重复性代码

2、Hibernate是一个基于jdbc的主流持久化框架,是一个优秀的orm实现,它很大程度的简化了dao层编码工作

3、Hibernate使用java的反射机制,而不是字节码增强程序类实现透明性

4、Hibernate的性能非常好,因为它是一个轻量级框架。映射的灵活性很出色。它支持很多关系型数据库,从一对一到多对多的各种复杂关系

——Hibernate常用版本

Hibernate3.x版本和Hibernate4.x

Hibernate并没有提供日志的实现,所有可以下载slf4j 和 log4j 开发包,整合Hibernate的日志系统到log4j 

——Hibernate的日志记录

    日志:程序开发中的一些信息。

    通常用System.out.println();打印输出。

    但是这种方式不好:
        *   如果输出内容比较多,并且项目已经开发完毕,不想使用输出,那么需要修改源代码。

    Hibernate中使用slf4j技术。
    slf4j并不是记录日志的工具,而是用于服务其它日志的系统。

    在企业中最常用的日志记录工具:log4j
    log4j才是一个具体的日志记录工具。

    Log4J的日志级别:

        *   fatal(致命的)
        *   error(普通错误)
        *   warn(警告)
        *   info(信息)
        *   debug(调试)
        *   trace(堆栈信息).
 

    Log4J的三个组件:

        记录器(Loggers)

            *   格式:记录器 = 级别, 输出源1 , 输出源2

            *   log4j.rootLogger=info, stdout

        输出源(Appenders)

            *   log4j.appender.stdout=org.apache.log4j.ConsoleAppender:控制台进行输出.

            *   log4j.appender.file=org.apache.log4j.FileAppender:向文件进行输出.

        布局(Layouts) 

            log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

            log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

    log4j配置文件:

        ### direct log messages to stdout ###

        log4j.appender.stdout=org.apache.log4j.ConsoleAppender

        log4j.appender.stdout.Target=System.err

        log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

        log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

        ### direct messages to file mylog.log ###

        log4j.appender.file=org.apache.log4j.FileAppender

        log4j.appender.file.File=c\:mylog.log

        log4j.appender.file.layout=org.apache.log4j.PatternLayout

        log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n

        ### set log levels - for more verbose logging change 'info' to 'debug' ###

        log4j.rootLogger=info, stdout, file

    示例代码:
         public class Log4jDemo {

            private Logger logger = Logger.getLogger(this.getClass());

            @Test

            public void fun() {

                logger.fatal("致命错误");

                logger.error("普通错误");

                logger.warn("警告");

                logger.info("普通信息");

                logger.debug("调试信息");

                logger.trace("堆栈信息");

            }

        }

——Hibernate快速入门

1、下载Hibernate的开发工具
    下载地址:http://sourceforge.net/projects/hibernate/files/hibernate3/

2、Hibernate框架目录结构
    *   documentation
        存放Hibernate文档
    *   lib
        存放Hibernate开发jar包
        >   bytecode
            操作字节码的jar包
        >   jpa
            Hibernate的实现JPA规范
        >   optional
            开发Hibernate的可选jar包
        >   required
            开发Hibernate必须jar包
    *   project
        提供的测试示例工程

3、创建一个工程(Java工程)
    1)导入jar包
        *   核心jar包
            解压根目录下:hibernate3.jar
        *   解压目录下:
            lib/required/*.jar
        *   引入JPA规范
            解压目录下:lib/jpa/hibernate-jpa-2.0-api-1.0.1.Final.jar
        *   导入日志记录包:
            log4j.jar
            slf4j.jar
        *   导入数据库驱动

        antlr-2.7.6.jar:
            一个语言转换工具,Hibernate利用它实现HQL到SQL的转换。
        commons-collections-3.1.jar:
            collections Apache 的工具集,用来增强Java对集合的处理能力

        dom4j-1.6.1.jar:
            dom4j XML 解析器

        hibernate-jpa-2.0-api-1.0.1.Final.jar:
            JPA 接口开发包

        javassist-3.12.0.GA.jar:
            代码生成工具, Hibernate用它在运行时扩展 Java类

        jta-1.1.jar:
            标准的 JAVA 事务(跨数据库)处理接口

        slf4j-api-1.6.1.jar:
            hibernate使用的一个日志系统

4、创建表(关系型数据库)
    create database hibernate3_day01;

    use hibernate3_day01;

    create table customer(

        id int primary key auto_increment,

        name varchar(20),

        age int

    );

5、创建实体类(面向对象)

    /**

     * 实体类对象

     * 

     * @author WYC

     * 

     */

    public class Customer {

        private int id;

        private String name;

        private int age;

        public int getId() {

            return id;

        }

        public void setId(int id) {

            this.id = id;

        }

        public String getName() {

            return name;

        }

        public void setName(String name) {

            this.name = name;

        }

        public int getAge() {

            return age;

        }

        public void setAge(int age) {

            this.age = age;

        }

}

6、创建ORM的映射

映射文件只要是XML格式文件就可以,名字可以任意。
    通常情况下映射文件与实体类在同包下。
    名称规范:
        实体类名称.hbm.xml

    在XML文件中引入约束:
        在hibernate3.jar/org.hibernate.hibernate-mapping-3.0.dtd

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

示例代码:
----------------------------------------------------------------------------------------------------------------------------
       

        

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

        

            

            

            

                

                

                

                

                

                <!-- 

                    type的三种写法

                      *  Java类型:java.lang.String

                      *  Hibernate类型:string

                      *  SQL类型:不能直接使用type属性,需要使用子标签

                           >  

                    通常使用Hibernate类型。

                    可以不写type,Hibernate会自动完成类型转换

                -->

                

                

            

        

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

7、创建Hibernate的核心配置文件
    配置Hibernate连接的数据库等信息。

    在src下创建一个配置文件:
        hibernate.cfg.xml

    在XML文件中引入约束:
        Hibernate核心包下:/org/hibernate/hibernate-configuration-3.0.dtd

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

示例代码:

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

       

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

        

            

            

                

                

                com.mysql.jdbc.Driver

                jdbc:mysql:///hibernate3_day01

                root

                Admin123
 

                

                

                org.hibernate.dialect.MySQLDialect
 

                

                

                true
 

                

                true

               
                false 
 

                

                update
 

                

                

                
 

            

        

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

8、编写测试
    向数据库中插入一条记录。

    session.save(Object obj);

示例代码:
 

import java.util.List;

import org.hibernate.Criteria;

import org.hibernate.Query;

import org.hibernate.SQLQuery;

import org.hibernate.Session;

import org.hibernate.SessionFactory;

import org.hibernate.Transaction;

import org.hibernate.cfg.Configuration;

import org.hibernate.criterion.Restrictions;

import org.junit.Test;

/**

 * Hibernate入门案例测试

 * @author WYC

 *

 */

public class HibernateDemo1 {

    @Test

    public void fun(){

        /*

         * 1、使用Hibernate框架加载核心配置文件,获取连接信息。

         */

        Configuration config = new Configuration().configure();

        /*

         * 2、创建连接池SessionFactory,可以获得Session(相当于Connection)

         */

        SessionFactory factory = config.buildSessionFactory();

        /*

         * 3、获得Session对象

         */

        Session session = factory.openSession();

        /*

         * 4、默认情况下事务是不会自动提交的

         */

        // 开启事务

        Transaction tx = session.beginTransaction();

        /*

         * 5、业务逻辑操作

         */

        // 向数据库中插入一条记录

        Customer customer = new Customer();

        customer.setName("张三");

        customer.setAge(20);

        session.save(customer);

        /*

         * 7、提交事务

         */

        tx.commit();

        /*

         * 8、释放资源

         */

        session.close();

        factory.close();

    }

}

9、Java - Hibernate - SQL类型对应关系

    

——Hibernate的CRUD操作

1、插入数据
    session.save(customer);

2、根据主键进行查询:
    Customer customer = (Customer)session.get(Customer.class, 1);

    Customer customer = (Customer)session.load(Customer.class, 1);

    示例代码:

        public void fun2(){

            /*

             * 1、加载Hibernate配置文件

             * 2、创建SessionFactory

             * 3、通过工厂创建Session对象

             * 4、开启事务

             * 5、逻辑操作

             * 6、提交事务

             * 7、释放资源

             */

            Configuration config = new Configuration().configure();

            SessionFactory factory = config.buildSessionFactory();

            Session session = factory.openSession();

            Transaction tx = session.beginTransaction();

            /*

             * 根据id进行查询

             */

            // get()方法

            Customer customer = (Customer)session.get(Customer.class, 1);
 

            // load()方法

            // Customer customer = (Customer)session.load(Customer.class, 1);

            // System.out.println(customer);

            tx.commit();

            session.close();

            factory.close();

        }

get()方法和load()方法的区别:
        1)发送SQL的时间不同
            *   load()方法采用了一个延时加载的技术(懒加载),load()方法在调用时并没有发送SQL语句,而是在使用对象属性时才会发送一条SQL语句。
            *   get()方法采用的是立即检索,当执行session.get()方法的时候立即发送SQL语句。
            *   load()更优化

        2)返回的对象不同
            *   load()方法返回的是一个代理对象(javassist包生成),可以通过断点查看。
            *   get()方法返回的是真实对象本身。

        3)当查询数据不存在时
            *   load()方法会抛出ObjectNotFoundException异常。
            *   get()方法会返回null,如果调用方法会出现空指针异常。

3、修改操作

session.update(Object obj)

修改有两种方式:
    *   手动创建对象修改
    *   先查询再修改

// 修改记录

public void fun3(){

    /*

     * 1、加载核心配置文件

     * 2、创建Session工厂

     * 3、通过工厂创建Session对象

     * 4、开启事务

     * 5、逻辑操作

     * 6、提交事务

     * 7、释放资源

     */

    Configuration config = new Configuration().configure();

    SessionFactory factory = config.buildSessionFactory();

    Session session = factory.openSession();

    Transaction tx = session.beginTransaction();

    /*

     * 有两种方式可以进行修改

     *  * 手动创建对象的方式

     *  * 先查询再修改的方式

     */

//   Customer customer = new Customer();

// customer.setId(2);

// customer.setName("李四");

    /*

     * 当被修改对象不设置age等属性时,则会采用默认值的形式:0

     * 所以在定义属性时不要使用基本数据类型,因为基本数据类型的默认值是0

     * 而是使用包装类,因为包装类的默认值是null

     */

// session.update(customer);
 

    /*

     * 先查询再修改的方式

     */

    Customer customer = (Customer)session.get(Customer.class, 2);

    customer.setName("王五");

    session.update(customer);

    tx.commit();

    session.close();

    factory.close();

}

4、删除记录

    session.delete(Object obj)

删除有两种方式:
    *   手动创建对象删除
    *   先查询再删除

如果想要进行级联删除,则必须先查询再删除。

// 删除操作

public void fun4(){

    Configuration config = new Configuration().configure();

    SessionFactory factory = config.buildSessionFactory();

    Session session = factory.openSession();

    Transaction tx = session.beginTransaction();

    /*

     * 有两种删除方式:

     *  * 手动创建对象的方式

     *  * 先查询再删除的方式

     */

// Customer customer = new Customer();

// customer.setId(3);

//

// session.delete(customer);

    Customer customer = (Customer)session.get(Customer.class, 6);

    session.delete(customer);

    tx.commit();

    session.close();

    factory.close();

}

——查询操作

1、HQL查询
    Hibernate Query Language。
    Hibernate的查询语言,只能用于面向对象的查询。

    // HQL查询操作

    public void fun5(){

        Configuration config = new Configuration().configure();

        SessionFactory factory = config.buildSessionFactory();

        Session session = factory.openSession();

        Transaction tx = session.beginTransaction();

        // 查询所有客户

        // Customer表示一个类,可以不写表名,因为在配置文件中已经完成了映射

//     Query query = session.createQuery("from com.wyc.hibernate3.demo1.Customer");

//     List list = query.list();

         // 根据姓名查询客户

//     Query query = session.createQuery("from Customer where name = ?");

         // setParameter()方法可以不设置值的类型

//     query.setParameter(0, "张三");

//       List list = query.list();
 

        // 为参数起别名

        Query query = session.createQuery("from Customer where name = :name");

        query.setParameter("name", "张三");

        List list = query.list();

        for(Customer c : list){

            System.out.println(c);

        }

        tx.commit();

        session.close();

        factory.close();

    }

2、QBC查询
    Query By Criteria,条件查询。

示例代码:

    public void fun6(){

        Configuration config = new Configuration().configure();

        SessionFactory factory = config.buildSessionFactory();

        Session session = factory.openSession();

        Transaction tx = session.beginTransaction();

        /*

         * 使用QBC查询

         */

//     Criteria criteria = session.createCriteria(Customer.class);

//     List list = criteria.list();

        /*

         * 使用QBC进行条件查询

         */

        Criteria criteria = session.createCriteria(Customer.class);

        criteria.add(Restrictions.eq("name", "张三"));

        List list = criteria.list();

        for(Customer c : list){

            System.out.println(c);

        }
 

        tx.commit();

        session.close();

        factory.close();

    }

3、SQL查询

    public void fun7(){

        Configuration config = new Configuration().configure();

        SessionFactory factory = config.buildSessionFactory();

        Session session = factory.openSession();

        Transaction tx = session.beginTransaction();

        /*

         * 使用SQL进行查询

         */

        // 查询所有记录

//       SQLQuery query = session.createSQLQuery("select * from customer");

//     // 一个数组表示一条记录

//     List list = query.list();

//

//     for(Object[] o : list){

//         System.out.println(Arrays.toString(o));

//     }

        SQLQuery query = session.createSQLQuery("select * from customer");

        // 指定封装对象

        query.addEntity(Customer.class);

        List list = query.list();

        for(Customer c : list){

            System.out.println(c);

        }

        tx.commit();

        session.close();

        factory.close();

    }

——Hibernate常用配置

1、核心配置
    有两种方式进行配置
    1)属性文件的配置
        hibernate.properties
        格式:
            key=value
            hibernate.connection.driver_class=com.mysql.jdbc.Driver

        注意:在属性配置文件中无法完成加载映射文件,只能通过手动编码的方式进行加载。
    2)XML格式文件配置
        hibernate.cfg.xml

2、配置属性
    1)必须属性:
        连接数据库的4个基本参数
            *   hibernate.connection.driver_class:数据库驱动程序
            *   hibernate.connection.url:数据库URL
            *   hibernate.connection.username:数据库用户名
            *   hibernate.connection.password:数据库密码

        Hibernate方言:
            *   hibernate.dialect:操作数据库方言

    2)可选属性:
        hibernate.show_sql:true,会在控制台上输出SQL语句
        hibernate.format_sql:true,格式化控制台输出的SQL语句
        hibernate.connection.autocommit:true,事务是否自动提交
        hibernate.hbm2ddl.auto:
            *   create:每次执行时,都会创建一个新的表(如果这个表已经存在,那么将删除该表然后重新创建),一般用于测试。
            *   create-drop:每次执行时,都会创建一个新的表,程序执行结束后会将该表删除,一般用于测试,当SessionFactory close()之后才会执行drop操作。
            *   update:如果数据库中没有表,则会创建一个新的表,如果该表已存在,会直接使用这个表,当指定字段不存在时,会更新表结构,新添加字段的值默认为null
            *   validate:使用原有的表,并且完成校验,校验映射文件中与表配置的字段是否一致,如果不一致,则会报错。

    3)映射文件配置
        *   在核心配置文件中配置映射文件:
           
        *   需要使用手动编码的方式加载

2、映射文件的配置
    主要配置的是ORM,对象和关系表的映射。
    1)配置类与表的映射
         
        *   name:类的完整路径
        *   table:表名(可以省略,默认使用类名,不区分大小写,但是类名不能与数据库关键字冲突)

    2)配置普通属性与字段的映射
        *  
        *   如果不写length,默认255。
        *   type的三个值:
            >   Java类型:java.lang.String
            >   Hibernate类型:string
            >   SQL类型:不能直接使用type属性,需要使用子标签
               

    3)配置唯一标识与主键映射
        *   一个表中只有一个主键
           
            >   生成策略

        *   复合主键
            必须实现序列化接口
           

    4)关联关系

    5)命名SQL
        使用的是HQL:
                            from Customer             

        使用SQL:
                            select * from Customer            

 
——Hibernate核心API

1、Configuration
    1)负责管理Hibernate的配置信息,包括如下内容:
        *   加载hibernate.properties和hibernate.cfg.xml
        *   持久化类与数据表的映射关系(*.hbm.xml)

    2)创建Configuration的两种方式:
        *   属性文件(hibernate.properties)
            Configuration config = new Configration();    // 手动加载hbm

        *   XML文件(hibernate.cfg.xml)
            ConfigURation config = new Configration().configure();
            configure()方法源代码:configure("/hibernate.cfg.xml");
            可以手动指定要加载的XML文件:configure(XML文件名称);

    3)加载映射文件
        *   第一种写法:
            configuration.addResource("com/wyc/hibernate3/demo1/Customer.hbm.xml");
        *   第二种写法(要求:映射文件名称要规范,类与映射文件要在同一个包下)
            configuration.addClass(Customer.class);

        通常会将映射文件配置在核心配置文件中,如果要使用properties配置文件,则必须使用这种方法。

2、SessionFactory工厂类
    Configuration对象根据当前的配置信息生成SessionFactory对象。
    SessionFactory对象中保存了当前数据库配置信息和所有映射关系以及预定义的SQL语句。
    SessionFactory对象是线程安全的。
    SessionFactory还负责维护Hibernate的二级缓存(Session是一级缓存)。
    SessionFactory对象根据数据库信息,维护连接池,创建Session(相当于Connection)对象。

    构造SessionFactory很耗费资源,一般情况下一个应用只初始化一个SessionFactory对象。

    练习:抽取一个HibernateUtils工具类来提供Session对象。

    示例代码:

/**

 * Hibernate工具类

 * @author WYC

 *

 */

public class HibernateUtils {

    private static Configuration config;

    private static SessionFactory factory;

    static {

        config = new Configuration().configure();

        factory = config.buildSessionFactory();

    }

    public static Session openSession(){

        return factory.openSession();

    }

}

    当openSession()方法调用时,就会通过实体类来创建映射的表,前提是在核心配置文件中进行了配置。

3、Session接口
    1)相当于JDBC的Connection
    2)Session是应用程序与数据库之间交互操作的一个单线程对象,是Hibernate的运作中心。
    3)Session是线程不安全的。
    4)所有持久化对象必须在Session的管理下才可以进行持久化操作。
    5)Session对象有一个一级缓存,显示执行flush之前,所有的持久化操作的数据都换存在Session对象中。
    6)持久化类与Session关联起来后就具有了持久化的能力。
    7)常用方法:
        *   save()、persist():增加
            >   persist()方法是JPA提供的方法
        *   update():修改对象
        *   saveOrUpdate():添加或修改对象
            >   当对象存在时执行修改操作,对象不存在时执行添加操作
        *   delete():删除对象
        *   get()、load():根据主键查询对象。
        *   createQuery():创建一个Query接口,编写HQL语句
        *   createSQLQuery():创建一个SQLQuery接口,编写SQL语句
        *   createCriteria():条件查询,会返回一个Criteria接口。

4、Transaction接口
    1)代表数据库操作的事务对象
        Transaction transaction = session.beginTransaction();
    2)提供事务管理的方法
        *   commit():提交相关联的Session实例
        *   rollback():撤销事务操作
        *   wasCommitted():检察事务是否提交

    如果没有开启事务,那么每个Session的操作都相当于一个独立的事务。

5、Query接口
    1)Query代表面向对象的一个Hibernate查询操作。
    2)session.createQuery()接收的是一个HQL语句。
    3)HQL是Hibernate Query Language的缩写,语法很像SQL语法,但是完全面向对象的。
    4)使用Query对象步骤:
        *   获得Hibernate Session对象
        *   编写HQL语句
        *   调用session.createQuery()方法创建查询对象
        *   如果HQL语句包含查询条件参数,则调用Query对象的setXxx()方法设置参数
        *   调用Query对象的list()方法,或uniqueResult()方法执行查询
    5)Query还包含两个方法,用于控制返回结果
        *   setFirstResult(int firstResult):设置返回结果从第几条开始
        *   setMaxResults(int maxResults):设置本次返回结果记录数
        *   可以使用这两个方法进行分页查询。

    HQL入门举例:
        *   以from开头的HQL语句:
            调用list()方法返回List,from Customer表示查询Customer表的所有数据。
        *   使用Select关键字:(查询部分对象属性)
            >   select name from Customer,返回List
            >   select name, age from Customer,返回List
            >   select c.name from Customer as c,为Customer实例起别名
        *   使用Where添加条件:
            >   from Customer as c where c.age > :age:其中:age是参数
            >   from Customer as c where c.age > ?:其中?是参数

6、Criteria接口
    1)Criteria接口是Hibernate提供的用于条件查询接口
    2)Criteria criteria = session.createCriteria(Customer.class);
    3)使用Criteria对象步骤:
        *   获得Hibernate的Session对象
        *   通过Session获得Criteria对象
        *   使用Restrictions的静态方法创建Criteria条件对象
        *   向Criteria对象中添加Criteria查询条件
        *   执行Criteria的list()或uniqueResult()获得结果

——在Hibernate中使用C3P0连接池

1、导入C3P0的jar包

2、在核心配置文件中添加一段配置:
    

    

    org.hibernate.connection.C3P0ConnectionProvider
    

    5

    

    20

    <!--设定数据库连接的过期时间,以秒为单位,

    如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 -->

    120

    

    3000

——Hibernate持久化对象的配置和操作

1、Hibernate采用普通、传统的Java对象(POJO类),作为持久化类,与数据表进行映射。
2、编写规则:
    *   提供一个public的无参构造方法。
    *   提供一个标识属性,映射数据表主键字段。
    *   所有属性提供public访问控制符的set()/get()方法。
    *   标识属性应尽量使用基本数据类型的包装类。
    *   不要用final修饰(不能被继承,无法生成代理对象进行优化)
        当无法生成代理对象时,load()方法不会延时加载,会即时打印SQL语句。
3、持久化对象的唯一标识:OID
    *   Java根据地址区分同一个类的不同对象。
    *   关系数据库根据主键区分是否同一条记录
    *   Hibernate使用OID来建立内存中的对象和数据库记录的对应关系。
    *   对象的OID和数据库的表的主键对应,为保证OID的唯一性,应该让Hibernate来为OID赋值。

4、自然主键和代理主键
    1)自然主键
        创建一个用户表,用户表中某条记录想要被唯一确定,可以使用身份证号作为主键,身份证号本身就是一个用户的属性,这就叫自然主键。
    2)代理主键
        创建一个用户表,用户表中某条记录想要被唯一确定,但没有使用身份证号作为主键,使用一个与用户的任何信息都不相关,只具备标识的作用,这就是代理主键。

    尽量使用代理主键。

5、尽量让Hibernate自己维护主键
    涉及到主键的生成策略。

——主键的生成策略

1、increment
    自动增长,适用于数值类型,而不能使用字符串。
    不是使用数据库的自动增长机制,而是使用Hibernate框架提供的自动增长方式。

    *   首先会检查主键的最大值:select max(id) from table
    *   然后在最大值的基础上+1
    容易出现多线程的问题,不能在集群下使用。

2、identity
    自动增长,适用于数值类型,而不能使用字符串。
    采用数据库的自动增长的机制。
    不适用于Oracle数据库,因为Oracle数据库没有自动增长。

3、sequence
    序列,适用于数值类型,而不能使用字符串。
    可以应用在Oracle中,MySQL中不能使用。

4、uuid
    使用与字符串类型的主键。
    使用随机字符串作为主键。

5、native
    本地策略。
    根据底层数据库自动选择使用identity还是sequence。

6、assigned
    Hihernate框架不维护主键,由程序自动生成。

7、foreign
    主键来自外表主键。
    应用在一对一的关系表中。

——练习

    1、搭建Hibernate环境
        >   核心配置文件
        >   映射文件
    2、抽取Hibernate工具类
    3、CRUD操作

——总结

1、Hibernate框架概述
    *   是一个持久层的ORM框架
    *   ORM:Object Relational Mapping
        >   对象关系映射,将Java中实体对象与关系型数据库中的表建立一种关系,Hibernate中可以通过操作对象的方式,从而操作数据库中的表。
    *   常见持久层框架
        >   Hibernate
        >   MyBatis
        >   JPA

2、Hibernate入门
    1)下载Hibernate开发包
    2)Hibernate开发包目录结构
        *   文档
        *   开发包
            >   操作字节码
            >   必须包
            >   可选包
            >   JPA
    3)创建一个Java项目,导入相应jar包
    4)创建数据库表
    5)创建一个实体类
    6)映射配置文件
    7)核心配置文件
    8)测试程序

3、Hibernate的CRUD
    1)save()
    2)update()
    3)delete()
    4)get() / load()
        *   区别:
            >   get:采用立即检索,马上发送SQL语句。返回的是真实对象。当检索不到数据时会抛出NullPointerException
            >   load:采用延迟加载的技术,当真正使用对象的时候,才会发送SQL语句。返回的是代理对象。抛出ObjectNotFoundException

4、Hibernate的配置
    *   核心配置
        >   属性文件(properties)
            在src下创建一个hibernate.properties文件
            必须手动加载
        >   XML文件
            在src下创建一个hibernate.cfg.xml文件

        必须的配置:
            数据库连接信息
            Hibernate方言

        可选配置:
            显示SQL
            格式化SQL
            hbm2ddl.auto
                create/create-drop/update/validate

        映射文件:
            

    *   映射配置
        >   建立类与表的映射
            name:类的全路径
            table:表名称
        >   id
        >   property
            name
            column
            type
            length

5、Hibernate核心API
    *   Configuration
        >   属性文件:
            直接创建
        >   XML文件
            new Configuration().configure();

    *   SessionFactory
        >   维护二级缓存,线程安全的对象
        >   抽取工具类

    *   Session
        >   维护一级缓存,线程不安全的对象

    *   Transaction
        >   控制事务
        >   在Hibernate中默认事务不自动提交,每个Session都是一个独立的事务

    *   Query
    *   Criteria

6、Hibernate的持久化类的编写
    *   无参构造
    *   属性提供set() / get()方法
    *   属性尽量使用包装类
    *   类不要使用final
    *   提供唯一标识OID

7、自然主键和代理主键

8、Hibernate主键的生成策略
    *   increment:线程不安全,不能用于集群
    *   identity:使用数据库自动增长机制
    *   sequence:支持序列的数据库,比如Oracle
    *   uuid
    *   native:本地策略,根据本地数据库自动选择主键生成策略