Hibernate基础

    技术2022-07-11  83

    hibernate基础

    配置文件

    配置文件的命名规范:类名.hbm.xml

    配置方式为xml文件

    引入约束文件

    约束文件位置

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-yeWCdj10-1593604408762)(F:\MarkDownOnte\学习笔记\dao层框架\assets\1591609475867.png)]

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Nm8xWkat-1593604408763)(F:\MarkDownOnte\学习笔记\dao层框架\assets\1591609484987.png)]

    根标签hibernate-mapping

    实体类映射文件标签

    class 标签:

    name属性 实体类的全限定名

    table属性 数据库的表名

    id标签 建立类中的属性与表中的主键映射关系

    name属性 实体类中对应主键名colum属性 表中的主键列generator 标签 class=“native”

    property标签 实体类中其他属性与数据库的字段映射关系

    name属性 实体类属性名colum属性 数据库列名

    实体类映射配置文件示例

    <?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.wx.dao.Customer" table="cst_customer"> <!-- 建立类中的属性与表中的主键对应 --> <id name="cust_id" column="cust_id" > <!--主键的生成策略--> <generator class="native"/> </id> <!-- 建立类中的普通的属性和表的字段的对应 --> <property name="cust_name" column="cust_name" length="32" /> <property name="cust_source" column="cust_source" length="32"/> <property name="cust_industry" column="cust_industry"/> <property name="cust_level" column="cust_level"/> <property name="cust_phone" column="cust_phone"/> <property name="cust_mobile" column="cust_mobile"/> </class> </hibernate-mapping>

    hibernate核心配置文件

    有两种配置方式xml方式与properties文件方式

    核心配置文件名 hibernaet.cfg.xml

    根标签session-factory

    子标签property 配置连接数据库相关的配置子标签property 配置数据库的方言,为了自动生成不同数据库的sql语句子标签mapping 配置映射

    hibernate的使用

    加载hibernate的核心配置文件 Configuration configuration= new Configuration().configure 创建SessionFactory的对象类似于连接池 configuration.bulidSessionFacory() 通过SessionFactory获取session对象 sessionFactory.openSessionFactory() 手动开启事务 session.beginTransaction() 编写代码 创建实体类session.save(实体类) 提交事务 session.commit 释放资源 session.close()

    hibernate的常见配置

    核心配置三类:

    1.必须配置 驱动类url路径用户名密码 2.可选配置 显示sql语句 hibernate.show.sql格式化sql hibernate.format.sql自动建表 hibernate.hbm2ddl.auto none 不会自动创建表create 如果数据库中有表就删除然后重新创建update 如果数据库中有表就使用没有就创建(更新表结构)validate 如果数据库中没有表就报错有就使用(校验用) 3.映射文件引入

    核心配置文件示例

    <?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.url">jdbc:mysql://localhost:3306/hibernate</property> <property name="hibernate.connection.username">root</property> <property name="hibernate.connection.password">root</property> <!-- 配置Hibernate的方言 --> <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <!-- 可选配置================ --> <!-- 打印SQL --> <property name="hibernate.show_sql">true</property> <!-- 格式化SQL --> <property name="hibernate.format_sql">true</property> <!-- 自动创建表 --> <property name="hibernate.hbm2ddl.auto">update</property> <!-- 配置C3P0连接池 --> <property name="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property> <!--在连接池中可用的数据库连接的最少数目 --> <property name="c3p0.min_size">5</property> <!--在连接池中所有数据库连接的最大数目 --> <property name="c3p0.max_size">20</property> <!--设定数据库连接的过期时间,以秒为单位, 如果连接池中的某个数据库连接处于空闲状态的时间超过了timeout时间,就会从连接池中清除 --> <property name="c3p0.timeout">120</property> <!--每3000秒检查所有连接池中的空闲连接 以秒为单位--> <property name="c3p0.idle_test_period">3000</property> <!--加载实体类映射文件--> <mapping resource="com/wx/dao/Customer.hbm.xml"/> </session-factory> </hibernate-configuration>

    hibernate的核心API

    Configuration:Hibernation的配置文件

    作用: 加载核心配置文件加载映射文件

    SessionFactory: session工厂

    作用1:初始化hibernate,作用2:维护了连接池与二级缓存线程安全的对象,一般一个项目创建一个对象

    Session:连接对象,非线程安全的,与数据库交互的桥梁

    相关的API:

    保存: Serializable save(Object obj); 返回保存记录的id查询: T get(Class c,Serializable id);T load(Class c,Serializable id);

    两者区别:

    load方式采用延迟加载,返回的是一个代理的对象,查询不到会抛出异常get采用一次性直接加载返回真是的对象,未查询到会返回一个null

    持久化类编写规则

    在java中与数据库表对应的实体类被称为持久化类持久化类=java类+映射文件持久化类编写规则: 由于地城是通过反射的方式建立的实体类对象,所以必须要有无参构造对应属性必须要有get/set方法对持久化类必须要提供一个唯一标识OID与数据库主键对应在属性中如果出现了基本数据类型尽量使用其对应的包装数据类型(避免出现歧义,因为基本数据类型默认为0,包装类型为null)持久化类不要使用final修饰,因为要使用代理对象

    主键生成策略

    主键分类: 自然主键:主键本省是表中的一个字段,比如创建一个人员表,其身份证就是唯一的使用身份证号作为主键就是自然主键代理主键:本省不是表中必须的一个字段,必须在表中我们另外创建一个id来标识一张表,这个主键就是代理主键尽量使用代理主键 主键的生成策略 在开发中主键多数不是由用户输入的数据设置的,一般使用程序自动生成,在Hibernate中为了减少程序的编写提供了多种主键的生成策略 increment: hibernate中的自动增长机制 适合在单线程中short int long 类型的主键,原理如下 首先发送一个sql语句 select max(id) from biao 然后让id+1作为下一条记录的主键 identity: 使用short int long 类型的主键,底层使用数据库的自增 ocacle没有自增不能使用sequence:使用short int long 类型的主键,采用序列的方式(oracle数据库)mysql不能使用uuid: 使用与字符串类型的主键,生成唯一uuid作为主键native:本地策略 ,hibernate依据数据库的不同使用对应的主键生成策略assigned: 由用户自己设置主键,hibernate不会生成主键foreign: 一对一表映射的情况下使用

    持久化类的三种状态

    瞬时态(transient):没有唯一标识oid,没有被session管理持久态(persistent):有唯一标识oid,被session管理 持久化类的处于持久化状态的对象可以自动更新数据库 托管态(detached):有唯一标识oid,没有被session管理 @org.junit.Test public void test2(){ // 对持久化类三种状态的测试 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); Customer customer = new Customer(); // 瞬时态 Serializable save = session.save(customer);// 有唯一oid被session管理持久态 customer.setCust_mobile("1107964521"); // 在这个期间对custom操作是处于持久化状态 transaction.commit(); session.close(); System.out.println(customer.getCust_id());// 现在处于托管态 }

    三种状态的相互转换

    转换方式 - 瞬时态获得: new瞬时->持久 save()方法瞬时->托管 直接设置oid custom.setCust-id(1) 持久态获得 获得:get(),load(),find()持久->瞬时 delete()持久->托管 clear() close()

    持久化类的持久态的特性

    持久态自动更新数据库

    Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); // 获得持久态对象 Customer customer = session.get(Customer.class, 2l); customer.setCust_level("17");// 设置属性 // session.update(customer); 不同调用更新方法直接就在数据库中更新了数据 transaction.commit(); session.close();

    hibernate的缓存

    一级缓存

    一级缓存是自带的不可卸载,只是作用与同一个session对象,其底层原理是session对象包含了一些列的java集合,在集合中存储了已经查询对象的oid再吃进行查询的时候如果在集合中查到了oid直接返回结果,如果在集合中没有查询到才到数据库中去查询,然后把查询结果存储到集合中并返回结果。

    一级缓存内部结构:

    一级缓存中存在的特殊区域:快照区(把查询的结果备份到快照区域)

    二级缓存一般不使用,因为会使用效率更高的redis代替

    Hibernate的事务管理

    为了保证连接对象是同一个连接对象(session)

    向下传递

    使用ThreadLocal 对象

    将这个连接绑定到当前线程中在dao的方法中,通过当前线程获得连接对象

    在hibernate中已经有绑定号的ThreadLocal对象但是默认不能使用需要设置开启

    在sessionFactory中提供了一个方法getCurrentSession()

    开启配置

    <property name="hibernate.current_session_context_class">thread</property>

    Hibernate中的其他的API

    Query

    query是一个接口用于接收HQL ,查询多个对象

    HQL:Hibernate Query Language 与sql相识的一种Hibernate的专属查询语言,面向对象的一种查询语言

    // 普通查询所有 String hql="from Customer"; Query query = session.createQuery(hql); List list = query.list(); list.forEach(s-> System.out.println(s)); //条件查询 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); // 条件查询 String hql="from Customer where cust_name like ? "; Query query = session.createQuery(hql); // 替换参数 query.setParameter(0,"%凌%"); // 执行查询 List list = query.list(); list.stream().forEach(s-> System.out.println(s)); // query分页查询 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); String hql="from Customer"; Query query = session.createQuery(hql); // 设置分页条件 query.setFirstResult(0); query.setMaxResults(5); //显示数据 List list = query.list(); list.stream().forEach(s-> System.out.println(s)); Ctiteria对象 criteria标准查询 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); List list = criteria.list(); criteriacriteria条件查询 // criteria Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); // 获得Criteria查询对象 Criteria criteria = session.createCriteria(Customer.class); criteria.add(Restrictions.like("cust_name","%赵%")); List list = criteria.list(); list.forEach(s-> System.out.println(s)); criteria分页查询 Session session = HibernateUtis.getSession(); Transaction transaction = session.beginTransaction(); // 获得Criteria查询对象 Criteria criteria = session.createCriteria(Customer.class); // 设置查询条件 criteria.add(Restrictions.like("cust_name","%逻%")); // 设置分页参数 criteria.setFirstResult(2); criteria.setMaxResults(6); List list = criteria.list(); list.forEach(s-> System.out.println(s));

    ion = session.beginTransaction(); // 获得Criteria查询对象 Criteria criteria = session.createCriteria(Customer.class); // 设置查询条件 criteria.add(Restrictions.like(“cust_name”,"%逻%")); // 设置分页参数 criteria.setFirstResult(2); criteria.setMaxResults(6); List list = criteria.list(); list.forEach(s-> System.out.println(s));

    Processed: 0.016, SQL: 9