Hibernate 技术(一)

Hibernate

简介

Hibernate是一个开源的对象关系映射(ORM)框架。对JDBC进行了非常轻量级的对象封装。 

将对象和数据库表建立映射关系,Hibernate框架使用在数据持久化层(dao)。 

ORM:对象关系映射(英语:Object Relational Mapping)

采用映射元数据(配置文件)来描述对象-关系的映射细节。ORM框架通过配置文件将实体对象和数据库表对应起来。

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

第一个Hibernate小例子

        前提准备:导入jar包
        需要的jar包 hibernate路径下下lib/required的所有jar包和jpa目录下的jar包
        mysql驱动jar包


            第一步:创建实体类

            Hibernate要求实体类必须提供一个不带参数的默认构造方法。因为程序运行时,Hibernate会运用java的反射机制,创建实体类的实例。 

            public class User {
                private int id;   
                private String name;
                private String password;
                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 String getPassword() {
                    return password;
                }
                public void setPassword(String password) {
                    this.password = password;
                }

            }

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
        第二步:创建对应的数据库表 

            CREATE DATABASE hibernate;
            USE hibernate;
            CREATE TABLE USER(
                id INT PRIMARY KEY AUTO_INCREMENT,
                name VARCHAR(50),
                password VARCHAR(50) 
            );
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
        第三步:创建Hibernate的配置文件,放在src目录下,文件名为hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>//指定数据库的驱动程序
    <property name="hibernate.connection.username">root</property>//数据库的用户名
    <property name="hibernate.connection.password">123456</property>//数据库的密码
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>//连接数据库的url

    <property name="show_sql">true</property>//为true时会在控制台输出sql语句,有利于跟踪hibernate的状态
    <property name="format_sql">true</property>//会格式化输出sql语句
    <property name="hbm2ddl.auto">update</property>
    <property name="hibernate.connection.autocommit">true</property>//自动提交事务

    <mapping resource="com/cad/domain/User.hbm.xml"/>//引入映射文件

</session-factory>
</hibernate-configuration> 
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
        第四步:创建对象-关系映射文件
            该文件应该和实体类在同一目录下。命名规则为 实体类名.hbm.xml 例如User.hbm.xml 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping> //根元素
<class name="com.cad.domain.User" table="user"> //指定实体类和对应的数据表
    <id name="id" column="id">                 //<id>元素设定类中的id和表的主键id的映射
        <generator class="native"></generator> //<gender>元素指定对象标识符生成器,负责生成唯一id。以后会详细讲
    </id>
    <property name="name" column="name"></property> //name是实体类属性的名字,column是数据表中列的名字
    <property name="password" column="password"></property>
</class>
</hibernate-mapping>    

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
        第五步:调用HibernateAPI操作数据库
            public class Demo {
                @Test
                public void test() {
                    //读取配置文件
                    Configuration conf=new Configuration().configure();
                    //根据配置创建factory
                    SessionFactory sessionfactory=conf.buildSessionFactory();
                    //获得操作数据库的session对象
                    Session session=sessionfactory.openSession(); 
                    //创建对象
                    User u=new User();
                    u.setName("张三");
                    u.setPassword("123456");
                    //将对象保存到数据库
                    session.save(u);
                    //关闭资源
                    session.close();
                    sessionfactory.close();
                }

            }
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

通过上面的小例子,我们大致了解了使用Hibernate的流程,接下来让我们详解Hibernate。

详解Hibernate配置文件

    Hibernate从其配置文件中读取和数据库连接有关的信息。Hibernate配置文件有两种形式,XML格式或者java属性文件(properties)格式。

    
    
  • 1
  • 2
    (一)java属性文件的格式创建hibernate的配置文件,默认文件名为hibernate.properties,为键值对的形式,放在src目录下:例如

                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                hibernate.connection.driver_class=com.mysql.jdbc.Driver
                hibernate.connection.url=jdbv:mysql://localhost:3306/hibernate
                hibernate.connection.username=root
                hibernate.connection.password=123456
                hibernate.show_sql=true


                hibernate.dialect:指定数据库使用的sql方言。可以根据数据库的不同生成不同的方言,底层是通过调用一个一个类实现的。
                hibernate.connection.driver_class:指定数据库的驱动程序
                hibernate.connection.url:指定连接数据库的url
                hibernate.connection.username:指定连接数据库的用户名
                hibernate.connection.password:指定连接数据库的密码
                hibernate.show_sql:如果为true,可以在控制台打印sql语句 

                hbm2ddl.auto:生成表结构的策略配置,配置这个可以通过映射文件和实体类自动生成表结构
                有四个值:
                    update(最常用的取值):如果当前数据库不存在对应的数据表,那么自动创建数据表
                    如果存在对应的数据表,并且表结构和实体类属性一致,那么不做任何修改
                    如果存在对应的数据表,但是表结构和实体类属性不一致,那么会新创建与实体类属性对应的列,其他列不变 

                    create(很少使用):无论是否存在对应的数据表,每次启动Hibernate都会重新创建对应的数据表,以前的数据会丢失

                    create-drop(极少使用):无论是否存在对应的数据表,每次启动Hibernate都会重新创建对应的数据表,每次运行结束删除数据表

                    validate(很少使用):只校验表结构是否和我们的实体类属性相同,不同就抛异常 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
(二)使用xml格式的配置文件,默认文件名为hibernate.cfg.xml 
                <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE hibernate-configuration PUBLIC
                    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

                <hibernate-configuration>

                    <session-factory>
                        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
                        <property name="hibernate.connection.username">root</property>
                        <property name="hibernate.connection.password">123456</property>
                        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>

                        <property name="show_sql">true</property>
                        <property name="format_sql">true</property>
                        <property name="hbm2ddl.auto">update</property>
                        <property name="hibernate.connection.autocommit">true</property> 

                        //引入映射文件
                        <mapping resource="com/cad/domain/User.hbm.xml"/>

                    </session-factory>
                </hibernate-configuration>
    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

两种方式的区别

            如果Hibernate的配置文件为java属性文件,那么必须通过代码来声明需要加载的映射文件
            通过Configuration的addClass(实体类名.class)来加载。

            配置文件为xml文件时,可以通过<mapping>元素来指定需要加载的映射文件。

            当通过Configuration的默认构造方法创建实例时,会默认查找hibernate.properties文件,如果找到就将配置信息加载到内存中。
            默认情况下,hibernate不会加载hibernate.cfg.xml文件,必须通过Configuration的configure()方法来显式加载hibernate.cfg.xml文件 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Hibernate中持久化类编写规范

    -必须提供无参数的默认构造方法。因为程序运行时,Hibernate会运用java的反射机制,创建实体类的实例。 

    -所有属性必须提供public访问控制符的set get方法 

    -属性应尽量使用基本数据类型的包装类型(如Integer            基本数据类型无法表达null值,所有基本数据类型的默认值都不是null,这样就有很大的缺陷。
            例如有一个score属性,表示学生分数,如果为0,那么是表示该学生未参加考试还是说该学生成绩为0呢?
            这时候如果用包装类型,就可以使用null来表示空值,学生未参加考试等等。

    -不要用final修饰实体(将无法生成代理对象进行优化)

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

对象标识符

在关系数据库中,通过主键来识别记录并保证记录的唯一性。
            主键的要求:不允许为null,不能重复,不能改变

            自然主键:在业务中,某个属性符合主键的三个要求,那么该属性可以作为主键。比如人的身份证就可以当作主键
            代理主键:增加一个不具备任何意义的字段,通常为ID,来作为主键

在java中,按照内存地址不同区分不同的对象。

在Hibernate中通过对象标识符(OID)来维持java对象和数据库表中对应的记录。
与表的代理主键对应,OID也是整数类型,为了保证OID的唯一性和不可变性,通常由Hibernate或者底层数据库库给OID赋值。

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

详解对象-关系映射文件

Hiernate采用XML格式的文件来指定对象和关系数据之间的映射。Hibernate通过这个文件来生成各种sql语句。
命名规则为 实体类名.hbm.xml  应该和实体类放在同一目录下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 <!--根元素,有一常用属性为package,当指定了package时,后面的类名字就可以简短,例如 package="com.cad.domain",后面class标签的name只用写User即可--> 
 <hibernate-mapping>

    <!--class标签指定类和表的对应关系,name为类名,table为表名
        class标签的属性 dynamic-insert属性,默认是false,当我们执行插入语句时,会动态生成sql语句,如果我们只为某个字段赋值,其他字段为null,但是生成的sql语句还是包含其他字段,例如user有两个属性,我们只为name赋值,生成的sql语句还是 insert into user(name,password)values (?,?),而当我们将该值设置为true时,生成的sql语句会仅包含不为null的字段,生成的sql语句就是insert into user(name) values (?) 

        class标签的属性 dynamic-update属性,默认是false,当我们执行更新语句时,会动态生成sql语句,如果我们只为某个字段更新,其他字段不变,生成的sql语句还是包含其他字段。而当我们将该值设置为true时,生成的sql语句仅包含需要更新的字段
        使用上面的两个属性可以提高运行性能,但是Hibernate动态生成sql语句需要的性能很小,所以可以省略-->
    <class name="com.cad.domain.User" table="user"> 

        <!--id标签用来设定持久化类中的OID和表的主键的映射,name为持久化类中的属性,column是数据表中的主键列名
            id标签的属性:length 指定列的数据长度
            id标签的属性:unsaved-value 指定当主键为某个值时,当做null来处理
            id标签的属性:access 也可用在<property>标签上 默认值为property,即通过相应的get set方法来访问持久化类的属性,当值为field时,表明使用反射机制直接访问类的属性,不推荐使用,破坏封装性-->
        <id name="id" column="id">
            <!--
                generator标签用来设定主键生成策略,hibernate内置的几种主键生成策略
                1.increment 适用于代理主键。由Hibernate自动以递增的方式生成主键,每次增量为1 ,会执行两个sql语句,先从表中查找出最大的id,然后加一,插入当前数据
                2.identity  适用于代理主键。由底层数据库生成主键,依赖数据库的主键自增功能
                3.sequence  适用于代理主键。由底层数据库的序列来生成主键,前提是数据库支持序列。(mysql不支持,oracle支持)
                4.hilo      适用于代理主键。Hibernate根据hilo算法来自己生成主键。
                5.native    适用于代理主键。根据底层数据库对自动生成主键的支持能力选择 identity|sequence|hilo
                6.uuid      适用于代理主键。采用UUID算法生成主键。
                7.assigned  适用于自然主键。由我们自己指定主键值。例如指定身份证号为主键值

            -->
            <generator class="native"></generator>
        </id>

        <!--
            property标签属性 name指定持久化类的属性名称
            column 与类属性映射的字段名,如果没有设置,默认用类属性名作为字段名
            not-null  指定属性的约束是否为非空,默认false
            unique   指定属性的约束是否唯一
            type     指定Hibernate映射类型。例如java类型为string,数据库类型为text,那么应该把Hibernate类型设置为Text。有一张对应的表可以查看。如果没有指定映射类型,Hibernate会使用反射机制识别属性的java类型,然后自动使用与之对应的Hibernate映射类型
        -->
        <property name="name" column="name"></property>
        <property name="password" column="password"></property>
    </class>
 </hibernate-mapping>   

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

Hibernate API详解

Configuration类

Configuration类:用来加载默认文件路径下的配置文件(hibernate.properties)。
                 调用configure()方法会加载默认文件路径下的xml格式的配置文件(hibernate.cfg.xml)推荐使用。

                 如果配置文件在不默认文件路径下或者配置文件名不符合默认规则
                     可以使用 
                     new Configuration().configure(file)  加载指定文件
                     new Configuration().configure(path)  加载指定路径下的文件 

                如果使用properties格式的配置文件,可以使用addClass(实体类名.class)方法可以加载映射文件。           

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

SessionFactory对象

SessionFactory对象: 
                SessionFactory代表数据库存储源。根据Hibernate配置文件创建对应的数据库存储源。
                SessionFactory对象创建后,和Configuration对象再无关联。修改Configuration包含的配置文件信息,不会对SessionFactory有任何影响。   

                  获取SessionFactory对象:new Configuration().configure().buildSessionFactory();
                对象的缓存很大,就称为重量级对象。SessionFactory存放了Hibernate配置信息,映射元数据信息等。是重量级对象。 

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Session对象

Session对象:   
                代表程序和数据库的会话。Session提供了操作数据库的各种方法。是轻量级对象。 

                   获取Session对象 
                   factory.openSession(): 获取新的Session实例。
                   factory.getCurrentSession():采用该方法创建的Session会取出当前线程中的Session,底层使用ThreadLocal进行存取 

                    save()方法:把Java对象保存到数据库中。
                                    Transaction ts=session.beginTransaction();
                                    User u=new User();
                                    u.setName("赵六");
                                    u.setPassword("123456");
                                    //将对象保存到数据库
                                    session.save(u); 
                                    ts.commit();

                    update()方法:更新数据库的方法 
                                    Transaction ts=session.beginTransaction();
                                    //先查出要修改的对象,根据主键值   
                                    User user=session.get(User.class, 1);
                                    user.setName("jery");
                                    //将对象更新到数据库,根据OID
                                    session.update(user); 
                                    ts.commit();

                    delete()方法:删除方法
                                    底层根据OID进行删除。有两种方式
                                    (1Transaction ts=session.beginTransaction();
                                        User user=session.get(User.class, 1); 
                                        //删除指定对象
                                        session.delete(user);   
                                        ts.commit();
                                    (2)
                                        Transaction ts=session.beginTransaction();
                                        User user=new User();
                                        user.setId(2);
                                        session.delete(user);
                                        ts.commit();     

                    load()或get()方法:从数据库查找指定对象 

                                  session.get(实体类名.class,OID);或session.load(实体类名.class,OID);

                    load()和get()的区别
                                  我们使用get查询时发现控制台会立马打出查询语句。
                                  使用load查询时控制台不会打印查询语句。
                                  get方法被调用时立刻发送sql语句到数据库进行查询。
                                  load方法被调用时并没有查询数据库,当我们需要使用查询的对象时,才去查询,所以当我们打印对象时,才会在控制台打印sql语句。

                      get()的原理 
                                程序调用get方法,Hibernate发送sql语句到数据库
                                数据库返回结果,Hibernate将结果封装成对象,返回对象到程序。

                      load()的原理
                                程序调用load方法,Hibernate使用代理技术,创建一个代理对象,属性只有ID值。
                                然后返回代理对象给程序,我们使用对象时,代理对象调用Hibernate查询数据库,初始化其他属性。 

            load方法,返回一个代理对象,获取其属性时,会查询数据库,每次访问属性都会查询数据库么?
            答:不是。代理对象中有一个标识是否被初始化的boolean类型变量,记录是否被初始化。

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

查询所有对象的方法

            使用HQL语言(后面会详细介绍),HQL语言是面向对象的
            Query query=session.createQuery("from User");


            第二种方式
            Criteria c=session.createCriteria(User.class);
            List<User> l=c.list();

            第三种方式,使用原生sql语句进行查询
            SQLQuery query=session.createSQLQuery("select * from user");
            List l=query.list();

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Transaction对象

        封装了事务的操作。我们做增删改查等操作时,必须开启事务.
            因为session是线程不安全的,这样主要是为了线程安全。保证数据的正确性。
            开启事务: Transaction ts=session.beginTransaction();
            提交事务:ts.commit();
            回滚事务:ts.rollback();
            当通过getCurrentSession获取当前线程绑定的Session时,事务关闭时,会自动把Session关闭并删除。

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Query对象

        封装HQL语句的对象。

        返回一个对象的方法 query.uniqueResult();

        分页相关
        query.setFirstResult(index):从第几个取
        query.setMaxResults(count):指定取几行记录

    
    
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

Hibernate

简介

Hibernate是一个开源的对象关系映射(ORM)框架。对JDBC进行了非常轻量级的对象封装。 

将对象和数据库表建立映射关系,Hibernate框架使用在数据持久化层(dao)。 

ORM:对象关系映射(英语:Object Relational Mapping)

采用映射元数据(配置文件)来描述对象-关系的映射细节。ORM框架通过配置文件将实体对象和数据库表对应起来。

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

第一个Hibernate小例子

        前提准备:导入jar包
        需要的jar包 hibernate路径下下lib/required的所有jar包和jpa目录下的jar包
        mysql驱动jar包


            第一步:创建实体类

            Hibernate要求实体类必须提供一个不带参数的默认构造方法。因为程序运行时,Hibernate会运用java的反射机制,创建实体类的实例。 

            public class User {
                private int id;   
                private String name;
                private String password;
                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 String getPassword() {
                    return password;
                }
                public void setPassword(String password) {
                    this.password = password;
                }

            }

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
        第二步:创建对应的数据库表 

            CREATE DATABASE hibernate;
            USE hibernate;
            CREATE TABLE USER(
                id INT PRIMARY KEY AUTO_INCREMENT,
                name VARCHAR(50),
                password VARCHAR(50) 
            );
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
        第三步:创建Hibernate的配置文件,放在src目录下,文件名为hibernate.cfg.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
<session-factory>
    <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>//指定数据库的驱动程序
    <property name="hibernate.connection.username">root</property>//数据库的用户名
    <property name="hibernate.connection.password">123456</property>//数据库的密码
    <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>//连接数据库的url

    <property name="show_sql">true</property>//为true时会在控制台输出sql语句,有利于跟踪hibernate的状态
    <property name="format_sql">true</property>//会格式化输出sql语句
    <property name="hbm2ddl.auto">update</property>
    <property name="hibernate.connection.autocommit">true</property>//自动提交事务

    <mapping resource="com/cad/domain/User.hbm.xml"/>//引入映射文件

</session-factory>
</hibernate-configuration> 
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
        第四步:创建对象-关系映射文件
            该文件应该和实体类在同一目录下。命名规则为 实体类名.hbm.xml 例如User.hbm.xml 

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping> //根元素
<class name="com.cad.domain.User" table="user"> //指定实体类和对应的数据表
    <id name="id" column="id">                 //<id>元素设定类中的id和表的主键id的映射
        <generator class="native"></generator> //<gender>元素指定对象标识符生成器,负责生成唯一id。以后会详细讲
    </id>
    <property name="name" column="name"></property> //name是实体类属性的名字,column是数据表中列的名字
    <property name="password" column="password"></property>
</class>
</hibernate-mapping>    

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
        第五步:调用HibernateAPI操作数据库
            public class Demo {
                @Test
                public void test() {
                    //读取配置文件
                    Configuration conf=new Configuration().configure();
                    //根据配置创建factory
                    SessionFactory sessionfactory=conf.buildSessionFactory();
                    //获得操作数据库的session对象
                    Session session=sessionfactory.openSession(); 
                    //创建对象
                    User u=new User();
                    u.setName("张三");
                    u.setPassword("123456");
                    //将对象保存到数据库
                    session.save(u);
                    //关闭资源
                    session.close();
                    sessionfactory.close();
                }

            }
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

通过上面的小例子,我们大致了解了使用Hibernate的流程,接下来让我们详解Hibernate。

详解Hibernate配置文件

    Hibernate从其配置文件中读取和数据库连接有关的信息。Hibernate配置文件有两种形式,XML格式或者java属性文件(properties)格式。

  
  
  • 1
  • 2
    (一)java属性文件的格式创建hibernate的配置文件,默认文件名为hibernate.properties,为键值对的形式,放在src目录下:例如

                hibernate.dialect=org.hibernate.dialect.MySQLDialect
                hibernate.connection.driver_class=com.mysql.jdbc.Driver
                hibernate.connection.url=jdbv:mysql://localhost:3306/hibernate
                hibernate.connection.username=root
                hibernate.connection.password=123456
                hibernate.show_sql=true


                hibernate.dialect:指定数据库使用的sql方言。可以根据数据库的不同生成不同的方言,底层是通过调用一个一个类实现的。
                hibernate.connection.driver_class:指定数据库的驱动程序
                hibernate.connection.url:指定连接数据库的url
                hibernate.connection.username:指定连接数据库的用户名
                hibernate.connection.password:指定连接数据库的密码
                hibernate.show_sql:如果为true,可以在控制台打印sql语句 

                hbm2ddl.auto:生成表结构的策略配置,配置这个可以通过映射文件和实体类自动生成表结构
                有四个值:
                    update(最常用的取值):如果当前数据库不存在对应的数据表,那么自动创建数据表
                    如果存在对应的数据表,并且表结构和实体类属性一致,那么不做任何修改
                    如果存在对应的数据表,但是表结构和实体类属性不一致,那么会新创建与实体类属性对应的列,其他列不变 

                    create(很少使用):无论是否存在对应的数据表,每次启动Hibernate都会重新创建对应的数据表,以前的数据会丢失

                    create-drop(极少使用):无论是否存在对应的数据表,每次启动Hibernate都会重新创建对应的数据表,每次运行结束删除数据表

                    validate(很少使用):只校验表结构是否和我们的实体类属性相同,不同就抛异常 

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
(二)使用xml格式的配置文件,默认文件名为hibernate.cfg.xml 
                <?xml version="1.0" encoding="UTF-8"?>
                <!DOCTYPE hibernate-configuration PUBLIC
                    "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
                    "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">

                <hibernate-configuration>

                    <session-factory>
                        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
                        <property name="hibernate.connection.username">root</property>
                        <property name="hibernate.connection.password">123456</property>
                        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernate</property>

                        <property name="show_sql">true</property>
                        <property name="format_sql">true</property>
                        <property name="hbm2ddl.auto">update</property>
                        <property name="hibernate.connection.autocommit">true</property> 

                        //引入映射文件
                        <mapping resource="com/cad/domain/User.hbm.xml"/>

                    </session-factory>
                </hibernate-configuration>
  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

两种方式的区别

            如果Hibernate的配置文件为java属性文件,那么必须通过代码来声明需要加载的映射文件
            通过Configuration的addClass(实体类名.class)来加载。

            配置文件为xml文件时,可以通过<mapping>元素来指定需要加载的映射文件。

            当通过Configuration的默认构造方法创建实例时,会默认查找hibernate.properties文件,如果找到就将配置信息加载到内存中。
            默认情况下,hibernate不会加载hibernate.cfg.xml文件,必须通过Configuration的configure()方法来显式加载hibernate.cfg.xml文件 

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

Hibernate中持久化类编写规范

    -必须提供无参数的默认构造方法。因为程序运行时,Hibernate会运用java的反射机制,创建实体类的实例。 

    -所有属性必须提供public访问控制符的set get方法 

    -属性应尽量使用基本数据类型的包装类型(如Integer            基本数据类型无法表达null值,所有基本数据类型的默认值都不是null,这样就有很大的缺陷。
            例如有一个score属性,表示学生分数,如果为0,那么是表示该学生未参加考试还是说该学生成绩为0呢?
            这时候如果用包装类型,就可以使用null来表示空值,学生未参加考试等等。

    -不要用final修饰实体(将无法生成代理对象进行优化)

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

对象标识符

在关系数据库中,通过主键来识别记录并保证记录的唯一性。
            主键的要求:不允许为null,不能重复,不能改变

            自然主键:在业务中,某个属性符合主键的三个要求,那么该属性可以作为主键。比如人的身份证就可以当作主键
            代理主键:增加一个不具备任何意义的字段,通常为ID,来作为主键

在java中,按照内存地址不同区分不同的对象。

在Hibernate中通过对象标识符(OID)来维持java对象和数据库表中对应的记录。
与表的代理主键对应,OID也是整数类型,为了保证OID的唯一性和不可变性,通常由Hibernate或者底层数据库库给OID赋值。

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

详解对象-关系映射文件

Hiernate采用XML格式的文件来指定对象和关系数据之间的映射。Hibernate通过这个文件来生成各种sql语句。
命名规则为 实体类名.hbm.xml  应该和实体类放在同一目录下。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

 <!--根元素,有一常用属性为package,当指定了package时,后面的类名字就可以简短,例如 package="com.cad.domain",后面class标签的name只用写User即可--> 
 <hibernate-mapping>

    <!--class标签指定类和表的对应关系,name为类名,table为表名
        class标签的属性 dynamic-insert属性,默认是false,当我们执行插入语句时,会动态生成sql语句,如果我们只为某个字段赋值,其他字段为null,但是生成的sql语句还是包含其他字段,例如user有两个属性,我们只为name赋值,生成的sql语句还是 insert into user(name,password)values (?,?),而当我们将该值设置为true时,生成的sql语句会仅包含不为null的字段,生成的sql语句就是insert into user(name) values (?) 

        class标签的属性 dynamic-update属性,默认是false,当我们执行更新语句时,会动态生成sql语句,如果我们只为某个字段更新,其他字段不变,生成的sql语句还是包含其他字段。而当我们将该值设置为true时,生成的sql语句仅包含需要更新的字段
        使用上面的两个属性可以提高运行性能,但是Hibernate动态生成sql语句需要的性能很小,所以可以省略-->
    <class name="com.cad.domain.User" table="user"> 

        <!--id标签用来设定持久化类中的OID和表的主键的映射,name为持久化类中的属性,column是数据表中的主键列名
            id标签的属性:length 指定列的数据长度
            id标签的属性:unsaved-value 指定当主键为某个值时,当做null来处理
            id标签的属性:access 也可用在<property>标签上 默认值为property,即通过相应的get set方法来访问持久化类的属性,当值为field时,表明使用反射机制直接访问类的属性,不推荐使用,破坏封装性-->
        <id name="id" column="id">
            <!--
                generator标签用来设定主键生成策略,hibernate内置的几种主键生成策略
                1.increment 适用于代理主键。由Hibernate自动以递增的方式生成主键,每次增量为1 ,会执行两个sql语句,先从表中查找出最大的id,然后加一,插入当前数据
                2.identity  适用于代理主键。由底层数据库生成主键,依赖数据库的主键自增功能
                3.sequence  适用于代理主键。由底层数据库的序列来生成主键,前提是数据库支持序列。(mysql不支持,oracle支持)
                4.hilo      适用于代理主键。Hibernate根据hilo算法来自己生成主键。
                5.native    适用于代理主键。根据底层数据库对自动生成主键的支持能力选择 identity|sequence|hilo
                6.uuid      适用于代理主键。采用UUID算法生成主键。
                7.assigned  适用于自然主键。由我们自己指定主键值。例如指定身份证号为主键值

            -->
            <generator class="native"></generator>
        </id>

        <!--
            property标签属性 name指定持久化类的属性名称
            column 与类属性映射的字段名,如果没有设置,默认用类属性名作为字段名
            not-null  指定属性的约束是否为非空,默认false
            unique   指定属性的约束是否唯一
            type     指定Hibernate映射类型。例如java类型为string,数据库类型为text,那么应该把Hibernate类型设置为Text。有一张对应的表可以查看。如果没有指定映射类型,Hibernate会使用反射机制识别属性的java类型,然后自动使用与之对应的Hibernate映射类型
        -->
        <property name="name" column="name"></property>
        <property name="password" column="password"></property>
    </class>
 </hibernate-mapping>   

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49

Hibernate API详解

Configuration类

Configuration类:用来加载默认文件路径下的配置文件(hibernate.properties)。
                 调用configure()方法会加载默认文件路径下的xml格式的配置文件(hibernate.cfg.xml)推荐使用。

                 如果配置文件在不默认文件路径下或者配置文件名不符合默认规则
                     可以使用 
                     new Configuration().configure(file)  加载指定文件
                     new Configuration().configure(path)  加载指定路径下的文件 

                如果使用properties格式的配置文件,可以使用addClass(实体类名.class)方法可以加载映射文件。           

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

SessionFactory对象

SessionFactory对象: 
                SessionFactory代表数据库存储源。根据Hibernate配置文件创建对应的数据库存储源。
                SessionFactory对象创建后,和Configuration对象再无关联。修改Configuration包含的配置文件信息,不会对SessionFactory有任何影响。   

                  获取SessionFactory对象:new Configuration().configure().buildSessionFactory();
                对象的缓存很大,就称为重量级对象。SessionFactory存放了Hibernate配置信息,映射元数据信息等。是重量级对象。 

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Session对象

Session对象:   
                代表程序和数据库的会话。Session提供了操作数据库的各种方法。是轻量级对象。 

                   获取Session对象 
                   factory.openSession(): 获取新的Session实例。
                   factory.getCurrentSession():采用该方法创建的Session会取出当前线程中的Session,底层使用ThreadLocal进行存取 

                    save()方法:把Java对象保存到数据库中。
                                    Transaction ts=session.beginTransaction();
                                    User u=new User();
                                    u.setName("赵六");
                                    u.setPassword("123456");
                                    //将对象保存到数据库
                                    session.save(u); 
                                    ts.commit();

                    update()方法:更新数据库的方法 
                                    Transaction ts=session.beginTransaction();
                                    //先查出要修改的对象,根据主键值   
                                    User user=session.get(User.class, 1);
                                    user.setName("jery");
                                    //将对象更新到数据库,根据OID
                                    session.update(user); 
                                    ts.commit();

                    delete()方法:删除方法
                                    底层根据OID进行删除。有两种方式
                                    (1Transaction ts=session.beginTransaction();
                                        User user=session.get(User.class, 1); 
                                        //删除指定对象
                                        session.delete(user);   
                                        ts.commit();
                                    (2)
                                        Transaction ts=session.beginTransaction();
                                        User user=new User();
                                        user.setId(2);
                                        session.delete(user);
                                        ts.commit();     

                    load()或get()方法:从数据库查找指定对象 

                                  session.get(实体类名.class,OID);或session.load(实体类名.class,OID);

                    load()和get()的区别
                                  我们使用get查询时发现控制台会立马打出查询语句。
                                  使用load查询时控制台不会打印查询语句。
                                  get方法被调用时立刻发送sql语句到数据库进行查询。
                                  load方法被调用时并没有查询数据库,当我们需要使用查询的对象时,才去查询,所以当我们打印对象时,才会在控制台打印sql语句。

                      get()的原理 
                                程序调用get方法,Hibernate发送sql语句到数据库
                                数据库返回结果,Hibernate将结果封装成对象,返回对象到程序。

                      load()的原理
                                程序调用load方法,Hibernate使用代理技术,创建一个代理对象,属性只有ID值。
                                然后返回代理对象给程序,我们使用对象时,代理对象调用Hibernate查询数据库,初始化其他属性。 

            load方法,返回一个代理对象,获取其属性时,会查询数据库,每次访问属性都会查询数据库么?
            答:不是。代理对象中有一个标识是否被初始化的boolean类型变量,记录是否被初始化。

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61

查询所有对象的方法

            使用HQL语言(后面会详细介绍),HQL语言是面向对象的
            Query query=session.createQuery("from User");


            第二种方式
            Criteria c=session.createCriteria(User.class);
            List<User> l=c.list();

            第三种方式,使用原生sql语句进行查询
            SQLQuery query=session.createSQLQuery("select * from user");
            List l=query.list();

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

Transaction对象

        封装了事务的操作。我们做增删改查等操作时,必须开启事务.
            因为session是线程不安全的,这样主要是为了线程安全。保证数据的正确性。
            开启事务: Transaction ts=session.beginTransaction();
            提交事务:ts.commit();
            回滚事务:ts.rollback();
            当通过getCurrentSession获取当前线程绑定的Session时,事务关闭时,会自动把Session关闭并删除。

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

Query对象

        封装HQL语句的对象。

        返回一个对象的方法 query.uniqueResult();

        分页相关
        query.setFirstResult(index):从第几个取
        query.setMaxResults(count):指定取几行记录

  
  
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
        <link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/markdown_views-ea0013b516.css">
            </div>

猜你喜欢

转载自blog.csdn.net/clf3211147/article/details/81048752