web学习笔记25-Hibernate基本配置使用

来源:互联网 发布:ubuntu win7 系统时间 编辑:程序博客网 时间:2024/06/05 04:08

1、看看JDBC(Java Database Connector)的一些缺点:

缺点    1.编程的时候很繁琐,用的try和catch比较多(需要关闭ResultSet rs ,Statement stmt,Connection conn)。    2.jdbc没有做数据的缓存(如果我们要实现每10s查询1000万条数据,没有缓存会挂掉)。    3.没有做到面向对象编程(我们操作数据库,每次都要先拿到connect,在创建sql发送对象,执行sql,关闭对象,没有面向对象).    4.sql语句的跨平台性很差(如果我们用mysql,后面需要切换到oracle,因为sql语句都不一样,移植很麻烦)优点    效率比较高(封装度越高肯定会牺牲效率的,因为hibernate底层也是用到jdbc。所以对性能要求比较高可以直接使用jdbc)。

2、看看Hibernate的一些优缺点:

hibernate的优点    1.完全的面向对象编程(我们只要配置好xml,使用直接调用API就可以,不用写sql语句,hibernate会拼接)    2.hibernate的缓存很厉害(一级缓存,二级缓存,查询缓存 )    3.编程的时候就比较简单了    4.跨平台性很强(我们替换数据库,只需要改配置文件,hibernate会拼接对应数据库的sql语句)    5.使用场合就是企业内部的系统(因为hibernate操作数据库大于1000万条的时候会有问题,所以只适合企业内部使用,数据量不那么大)。hibernate的缺点    1.效率比较低    2.表中的数据如果在千万级别,则hibernate不适合    3.如果表与表之间的关系特别复杂,则hibernate也不适合

3、Hibernate使用步骤:

a.创建一个工程。    就创建一个java工程就OKb.导入jar包。

这里写图片描述
扩展知识
代理对象的三种创建方式:
1、jdkproxy(基于接口的,代理对象实现目标对象相同的接口)
2、cglib(第三方的,基于子类,代理对象是目标的子类)
3、javassist

c.hibernate.cfg.xml。    主要的用途:        告诉hibernate连接数据库的信息,用的什么样的数据库(方言)        根据持久化类和映射文件生成表的策略    /src/hibernate.cfg.xml
        <?xml version='1.0' encoding='utf-8'?>        <!DOCTYPE hibernate-configuration PUBLIC                "-//Hibernate/Hibernate Configuration DTD 3.0//EN"                "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">        <hibernate-configuration>            <!--                 一个sessionFactory代表数据库的一个连接            -->            <session-factory>                <!-- 链接数据库的用户名 -->                <property name="connection.username">root</property>                <!-- 链接数据库的密码 -->                <property name="connection.password">root</property>                <!-- 链接数据库的驱动 -->                <property name="connection.driver_class">                    com.mysql.jdbc.Driver                </property>                <!-- 链接数据库的url -->                <property name="connection.url">                    jdbc:mysql://localhost:3306/example_hibernate                </property>                <!--                     方言                    告诉hibernate使用什么样的数据库,hibernate就会在底层拼接什么样的sql语句                    这个路径可以查看Hibernate的帮助文档,直接把路径复制过来                -->                <property name="dialect">                    org.hibernate.dialect.MySQLDialect                </property>                <!--                     根据持久化类生成表的策略(一般使用update就可以)                    validate   通过映射文件检查持久化类与表的匹配                    update   每次hibernate启动的时候,检查表是否存在,如果不存在,则创建,如果存在,则什么都不做了                    create   每一次hibernate启动的时候,根据持久化类和映射文件生成表                    create-drop                -->                <property name="hbm2ddl.auto">update</property>                <!--                     这个可以在控制台显示执行的sql语句,可以不写,默认不显示                -->                <property name="show_sql">true</property>                <mapping                    resource="com/example/hibernate/domain/Person.hbm.xml" />            </session-factory>        </hibernate-configuration>
d.编写持久化类。    持久化类:说白了就是数据库中表的体现,字段和表中一一对应,并且有关联表的持久化类在里面。    com.example.hibernate.domain.Person
        /**         * 实现了Serializable的主要的作用是为了在网络上传输,实现了这个接口,jvm会把对象转化为二进制数据,便于传输。         */        public class Person implements Serializable{            //字段名称和数据库的表字段对应            private Long pid;            private String name;            private String description;            public Person(){}            public Long getPid() {                return pid;            }            public void setPid(Long pid) {                this.pid = pid;            }            public String getName() {                return name;            }            public void setName(String name) {                this.name = name;            }            public String getDescription() {                return description;            }            public void setDescription(String description) {                this.description = description;            }        }
e.编写映射文件。    com.example.hibernate.domain.Person.hbm.xml
        <?xml version="1.0" encoding="utf-8"?>        <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"        "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">        <hibernate-mapping>            <!--                 class用来描述一个类                name 类的全名                table 该持久化类对应的表名   可以不写,默认值为类名                catalog  数据库的名称             -->            <class name="com.example.hibernate.domain.Person" table="person">                <!--                     用来描述主键                    name 属性的名称                    column 属性的名称对应的表的字段   可以不写  默认值就是属性的名称                    length  属性的名称对应的表的字段的长度  如果不写,默认是最大的长度                 -->                <id name="pid" column="pid" length="5">                    <!--                         主键的产生器                     -->                    <generator class="increment"></generator>                </id>                <property name="name" length="20" type="string"></property>                <property name="description" length="50" type="java.lang.String"></property>            </class>        </hibernate-mapping>
f.生成表。
        com.example.hibernate.db.CreateTable        public class CreateTable {            @Test            public void testCreateTable(){                Configuration configuration = new Configuration();                configuration.configure();                configuration.buildSessionFactory();            }        }        这样就可以在数据中产生一个空的person表了
g.现在都配置好了,可以使用hibernate进行crud(create,retieve,update,delete)操作了。    com.example.hibernate.crud.PersonDao
        public class PersonDao {            /**             * 保存person             */            @Test            public void testSavePerson(){                //加载了hibernate的配置文件                Configuration configuration = new Configuration();                configuration.configure();                //configuration.configure("");//按照指定的路径加载指定的配置文件                SessionFactory sessionFactory = configuration.buildSessionFactory();                //产生session                Session session = sessionFactory.openSession();                //产生事务                Transaction transaction = session.beginTransaction();                //创建一个对象                Person person = new Person("aa");                person.setName("zhangsan");                person.setDescription("man");                //保存该对象                session.save(person);                //事务提交,session关闭                transaction.commit();                session.close();            }            @Test            public void testGetPersonById(){                Configuration configuration = new Configuration();                configuration.configure();                SessionFactory sessionFactory = configuration.buildSessionFactory();                Session session = sessionFactory.openSession();                /**                 * 第一个参数为持久化类的class形式                 * 第二个参数为主键的值                 */                Person person = (Person)session.get(Person.class, 1L);                System.out.println(person.getName());                session.close();            }            @Test            public void testUpdate(){                /**                 * 1、先根据ID把要修改的对象查询出来                 * 2、对对象进行修改                 */                Configuration configuration = new Configuration();                configuration.configure();                SessionFactory sessionFactory = configuration.buildSessionFactory();                Session session = sessionFactory.openSession();                Transaction transaction = session.beginTransaction();                /**                 * 先根据主键把其中的一行数据查询出来,查询出来的就是一个对象                 */                Person person = (Person)session.get(Person.class, 1L);                /**                 * 修改person对象                 */                person.setDescription("super man");                //执行修改操作                session.update(person);                transaction.commit();                session.close();            }            @Test            public void testDelete(){                /**                 * 1、根据id把对象查询出来                 * 2、删除该对象                 */                Configuration configuration = new Configuration();                configuration.configure();                SessionFactory sessionFactory = configuration.buildSessionFactory();                Session session = sessionFactory.openSession();                Transaction transaction = session.beginTransaction();                /**                 * 把pid为1的对象提取出来                 */                Person person = (Person)session.get(Person.class, 1L);                //删除一个对象                session.delete(person);                transaction.commit();                session.close();            }        }
注意:    1.配置文件可以随意放,查看源码可以看到configure也是调用了带参的 configuration.configure("");

4、sessionFactory对象介绍:

SessionFactory接口负责初始化Hibernate。它充当数据存储源的代理,并负责创建Session对象。读取hibernate.cfg.xml的时候就初始化好了。特点:    1.hibernate中的配置文件、映射文件、持久化类的信息都在sessionFactory中    2.sessionFactory中存放的信息都是共享的信息    3.sessionFactory本身就是线程安全的(如果在tomcat中,在启动的时候就已经加载好了,所以是线程安全的)    4.一个hibernate框架sessionFactory只有一个    5.sessionFactory是一个重量级别的类

5、session对象介绍:

提起来Session的话,首先想到的是http的session,在hibernate中的session并不是http中所说的session。一般把HttpSession对象称为用户会话,而hibernate中的Session是用来表示,应用程序和数据库的一次交互(会话)。通常将每个Session实例和一个数据库事务绑定,也就是每执行一个数据库事务,都应该先创建一个新的Session实例,在使用Session后,还需要关闭Session。特点:    1、得到了一个session,相当于打开了一次数据库的连接    2、在hibernate中,对数据的crud操作都是由session来完成的

6、transaction对象介绍:

hibernate中的事务默认不是自动提交的。只有产生了连接,才能进行事务的操作。所以只有有了session以后,才能有transaction
    Session session = sessionFactory.openSession();    Transaction transaction = session.beginTransaction();//看底层源码,设置了JDBC的connection的setAutoCommit为false    .    .    .    transaction.commit();    session.close();

7、hibernate插入数据内部的执行原理:
这里写图片描述

8、hibernate配置文件中的类型:

a.hibernate类型    这个效率比较低,因为内部还需要转化。b.java类型    该种类型的效率比较高    在hibernate内部,为了一张表,这张表中有如下的映射关系:    hibernate类型       java类型        数据库的字段的类型    string             java.lang.String    varchar例如:Person.hbm.xml
    <hibernate-mapping>        <class name="com.itheima12.hibernate.domain.Person" table="person">            <id name="pid" column="pid" length="5">                <generator class="increment"></generator>            </id>            <!-- 这个string就是Hibernate的类型 -->            <property name="name" length="20" type="string"></property>            <!-- 这个java.lang.String就是Java类型 -->            <property name="description" length="50" type="java.lang.String"></property>        </class>    </hibernate-mapping>
一般我们用java类型就好了。

9、hibernate中主键产生机制

在配置文件 Person.hbm.xml 中配置主键的类型,我们默认使用increment。下面介绍几种不同的类型之间的区别 先创建一个Utils的工具类 com.itheima12.hibernate.utils.HibernateUtils
     public class HibernateUtils {        public static SessionFactory sessionFactory;        static{            Configuration configuration = new Configuration();            configuration.configure();            sessionFactory = configuration.buildSessionFactory();        }    }
a.increment    <generator class="increment"></generator>
        /**         * select max(pid) from person         *    先找到主键的最大值,在最大值基础上加1         *    所以该主键必须是数字类型,对应的持久化类里面的字段需要是数字类型         */        @Test        public void testIncrement(){            Session session = HibernateUtils.sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = new Person();            person.setName("123");            session.save(person);            transaction.commit();            session.close();        }
b.assigned    <generator class="assigned"></generator>
        /**         * 在程序中手动的设置主键的值         */        @Test        public void testAssigned(){            Session session = HibernateUtils.sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = new Person();            person.setName("123");            person.setPid(2L);//如果不手动分配主键值,就会报错            session.save(person);            transaction.commit();            session.close();        }
c.identity    <generator class="identity"></generator>
        /**         * 表的自动增长机制         *   主键必须是数字类型         *   该效率比increment要高,但是id值不连续         */        @Test        public void testIdentity(){            Session session = HibernateUtils.sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = new Person();            person.setName("123");            session.save(person);            transaction.commit();            session.close();        }
d.uuid    <generator class="uuid"></generator>
        /**         * uuid的字符串是由hibernate内部生成的         *    要求主键必须是字符串类型         */        @Test        public void testUUID(){            Session session = HibernateUtils.sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = new Person();            person.setName("aaa");            session.save(person);            transaction.commit();            session.close();        }

10、hibernate对象的状态(3种状态)

a.临时状态:new出来的对象在内存中b.持久化状态:将对象加载进hibernate框架中c.脱管状态:session使用完了,对象重新回到内存,可被GC回收。各状态的简单示意图

这里写图片描述
现在看看session的各种方法,对象的状态是怎么转化的
持久化类,配置文件,Utils的代码同上。

a.save
        //该方法可以把一个对象从临时状态转换成持久化状态        @Test        public void testSave(){            SessionFactory sessionFactory = HibernateUtils.sessionFactory;            Session session = sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = new Person();            person.setName("123");            session.save(person);            transaction.commit();            session.close();        }
    b.get
        //从数据库中根据主键提取出一个对象,该对象就是一个持久化状态的对象        @Test        public void testGet(){            SessionFactory sessionFactory = HibernateUtils.sessionFactory;            Session session = sessionFactory.openSession();            Person person = (Person)session.get(Person.class, 1L);//持久化状态            session.close();        }
c.update
        //把一个对象变成持久化状态        @Test        public void testUpdate(){            SessionFactory sessionFactory = HibernateUtils.sessionFactory;            Session session = sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = (Person)session.get(Person.class, 1L);//持久化状态            person.setDescription("111");            //session.update(person);//update方法就是把一个对象的状态变成持久化状态,person对象已经是持久化状态了,所以这行代码不需要写            transaction.commit();            session.close();        }
d.evict
        //把一个对象从持久化状态转化为脱管状态        @Test        public void testEvict(){            SessionFactory sessionFactory = HibernateUtils.sessionFactory;            Session session = sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = (Person)session.get(Person.class, 1L);//持久化状态            person.setDescription("111");            session.evict(person);//该方法可以把一个持久化状态变成脱管状态            session.update(person);//由脱管状态的对象变成持久化状态            transaction.commit();            session.close();        }
 e.clear
        //把所有的hibernate中的持久化对象都转换成脱管状态的对象        @Test        public void testClear(){            SessionFactory sessionFactory = HibernateUtils.sessionFactory;            Session session = sessionFactory.openSession();            Transaction transaction = session.beginTransaction();            Person person = (Person)session.get(Person.class, 1L);//持久化状态            person.setDescription("111");            Person person2 = new Person();            person2.setName("88");            session.save(person2);//person2是一个持久化状态的对象            session.clear();//把hibernate里面的所有的对象都变成脱管状态的对象            transaction.commit();            session.close();        }

11、hibernate中的对象副本。

hibernate中只要是查询,就会创建对象的副本。副本中的数据和数据库里面的数据保持一致。Person person = (Person)session.get(Person.class, 1L);//持久化状态为什么要创建副本呢?    我们不希望频繁的和数据库交互,这样效率很低。比如我们查询了一个数据,我们没有修改或者修改的值和副本中的一样,    我们就没必要把数据再重新插入到数据库了,这样就减少了和数据库的交互,虽然会牺牲点内存。
原创粉丝点击