Hibernate框架(初级) 📅 2026/7/28 15:37:33 Hibernate框架什么是Hibernate下载Hibernate的开发环境创建JAVAEE项目搭建Hibernate环境导入jar包创建项目总结映射的配置总结核心配置总结测试时需要的几个对象持久化类什么是持久化类持久化类的编写规则主键生成策略主键的分类自然主键代理主键实际开发Hibernate的主键生成策略持久化类的三种状态瞬时态持久态脱管态区分三种状态对象持久态的重要特点Hibernate的缓存什么是缓存Hibernate的一级缓存Query的简单使用CriteriaSQLQuery什么是HibernateHibernate是一个持久层的ORM对象关系映射框架。下载Hibernate的开发环境Hibernate5.0.7开发环境下载链接documentationHibernate开发文档libHibernate开发包requiredHibernate开发的必须依赖包optionalHibernate开发的可选jar包projectHibernate测试项目创建JAVAEE项目搭建Hibernate环境导入jar包数据库驱动包mysql-connector-java-6.0.6.jarHibernate开发必须的jar包引入日志记录包创建项目创建表创建实体类对应表格创建类与表的映射配置实体类名.hbm.xml建立类与表之间的映射主键对应和普通属性的对应?xml version1.0 encodingUTF-8 ?!DOCTYPE hibernate-mapping PUBLIC -//Hibernate/Hibernate Mapping DTD 3.0//EN http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtdhibernate-mapping!--建立类与表的映射--classnamecom.hibernate.pojo.Customertablecst_customer!--建立类中的属性与表中的主键对应--idnamecust_idcolumncust_idgeneratorclassnative//id!--建立类中普通的属性和表的字段的对应--propertynamecust_sourcecolumncust_source/propertypropertynamecust_industrycolumncust_industry/propertypropertynamecust_levelcolumncust_level/propertypropertynamecust_mobilecolumncust_mobile/propertypropertynamecust_namecolumncust_name/propertypropertynamecust_phonecolumncust_phone/property/class/hibernate-mapping映射约束从导入的jar包hibernate-core-5.0.7.Final.jar!\org\hibernate\hibernate-mapping-3.0.dtd中复制创建Hibernate的核心配置文件hibernate.cfg.xml配置数据库连接参数配置打印sql语句配置hibernate的方言配置映射文件?xml version1.0 encodingUTF-8 ?!DOCTYPE hibernate-configuration PUBLIC -//Hibernate/Hibernate Configuration DTD 3.0//EN http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtdhibernate-configurationsession-factory!--连接数据库的基本参数--propertynamehibernate.connection.driver_classcom.mysql.cj.jdbc.Driver/propertypropertynamehibernate.connection.urljdbc:mysql://localhost:3306/hibernate_day01?serverTimezoneAsia/Shanghaiamp;characterEncodingUTF-8/propertypropertynamehibernate.connection.usernameroot/propertypropertynamehibernate.connection.passwordcqrjxk39/property!--打印sql--propertynamehibernate.show_sqltrue/property!--格式化sql--propertynamehibernate.format_sqltrue/property!--配置hibernate的方言--propertynamehibernate.dialectorg.hibernate.dialect.MySQLDialect/propertymappingresourcecom/hibernate/pojo/Customer.hbm.xml/mapping/session-factory/hibernate-configuration测试加载Hibernate核心配置文件创建SessionFactory对象类似JDBC连接池通过SessionFactory获取session对象类似JDBC中的Connection开启事务编写代码事务提交资源释放publicvoidtest1(){//1. 加载Hibernate核心配置文件Configuration configurenewConfiguration().configure();//2. 创建SessionFactory对象类似于JDBC连接池SessionFactory sessionFactoryconfigure.buildSessionFactory();//3. 通过SessionFactory获取Session对象类似JDBC中的ConnectionSession sessionsessionFactory.openSession();//4. 开启事务Transaction transactionsession.beginTransaction();//5. 编写代码Customer customernewCustomer();customer.setCust_name(张三);session.save(customer);//6. 事务提交transaction.commit();//7. 资源释放session.close();}总结映射的配置class标签的配置标签用来建立类与表的映射关系属性name 类的全路径table 表名(类名与表名一致table可以省略)catalog 数据库名id标签的配置标签用来建立类中的属性与表中主键的对应关系属性name类中的属性名column表中的字段名(类中的属性名与表名一致colume可以省略)length长度property标签的配置标签用来建立类中的属性与表中普通字段的对应关系属性name类中的属性名column表中的字段名length长度not-null设置非空unique设置唯一注意Hibernate是可以根据映射关系自动创建表的只需要在Hibernate的核心配置文件hibernate.cfg.xml中配置如下语句即可propertynamehibernate.hbm2ddl.autoupdate/property总结核心配置必须配置连接数据库的基本参数驱动类ul路径用户名密码方言可选配置显示SQLhibernate.show_sql格式化SQLhibernate.format_sql自动建表hibernate.hbm2ddl.autonone不使用hibernate的自动建表create如果数据库中已经有表删除原有表重新建表(测试使用)create-drop如果数据库中已经有表删除原有表重新建表表格使用完后删除该表(测试使用)update如果数据库中有表使用原有表如果数据库中没有表则创建表可以更新表结构validate如果没有表不会创建表只会使用数据库中原有的表(会自动校验映射与表结构不匹配会报错)映射文件的引入通过mapping标签引入映射文件的位置总结测试时需要的几个对象Hibernate的核心配置文件既可以使用属性文件进行配置也可以使用xml文件进行配置但是属性文件配置时不能引入映射文件需要手动加载映射文件。Configuration作用加载核心配置文件hibernate.propertiesConfiguration cfg new Configuration();加载映射配置文件cfg.addResource(com/hibernate/pojo/Customer.hbm.xml);hibernate.cfg.xmlConfiguration cfg new Configuration().configure();SessionFactory作用维护了Hibernate的连接池线程安全的一个项目只需要创建一个即可所以一般将其抽取为Hibernate的工具类Hibernate的工具类importorg.hibernate.Session;importorg.hibernate.SessionFactory;importorg.hibernate.cfg.Configuration;publicclassHibernateUtil{privatestaticfinalConfiguration cfg;privatestaticfinalSessionFactory sf;static{cfgnewConfiguration().configure();sfcfg.buildSessionFactory();}publicstaticSessiongetSession(){returnsf.openSession();}}SessionHibernate与数据库的连接对象是Hibernate与数据库交互的桥梁线程不安全所以不能定义为全局变量只能定义为局部变量Session中常用的方法保存方法返回Serializable类型的主键Serializable save(Object obj)查询方法T get(Class clazz,Serializable id)T load(Class clazz,Serializable id)get和load的区别get采用的是立即加载当执行get方法时立即发送SQL语句load采用的是懒加载当执行load方法时不会发送SQL语句而是在使用其查询对象的时候才会发送SQLget方法返回的是真实对象本身load返回的是代理对象利用javassit.jar产生的代理get方法查询时数据库中找不到时会返回空load会抛出异常ObjectNotFoundException修改方法(推荐使用先查询再修改)void update(Object obj)删除方法(推荐使用先查询再删除)--级联删除void delete(Object obj)保存或更新(不常用)void saveOrUpdate(Object obj)查询所有Query query session.createQuery(from 类名);List类名 list query.list();SQLQuery query session.createSQLQuery(select * from 表名);List数组类型 list query.list();例如//根据id查询Customer customersession.get(Customer.class,1L);System.out.println(customer);Customer customer1session.load(Customer.class,1L);System.out.println(customer1);//修改Customer customersession.get(Customer.class,1L);session.update(customer);//删除Customer customersession.get(Customer.class,1L);session.delete(customer);//查询所有Query querysession.createQuery(from Customer);ListCustomerlistquery.list();SQLQuery sqlQuerysession.createSQLQuery(select * from cst_customer);ListObject[]list1sqlQuery.list();持久化类什么是持久化类持久化将内存中的一个对象持久化到数据库中的过程持久化类一个Java对象与数据库的表建立了映射关系那么这个类就称为持久化类持久化类的编写规则必须提供一个无参构造方法因为Hibernate底层需要使用反射生成实例属性需要私有并提供公有的get和set方法对持久化类提供一个唯一的标识OID与数据库的主键相对应持久类的属性尽量使用引用类型因为引用类型默认值是null持久化类尽量不要使用final修饰因为Hibernate有一个懒加载的优化手段返回的时代里对象代理对象是继承这个类进行代理的主键生成策略主键的分类自然主键自然主键指的是主键本身是表中的一个字段例如创建一个人员表人员都会有一个身份证号唯一不重复使用身份证号作为主键这种主键称为自然主键代理主键代理主键指的是主键本身不是表中必须要有的字段例如创建一个人员表给每一个人编一个号pno唯一不重复使用编号作为主键这种主键称为代理主键实际开发实际开发中尽量使用代理主键一旦主键参与到业务逻辑中去后期有可能要修改源代码好的程序应该满足ocp原则对程序扩展是open的对修改源代码是close的Hibernate的主键生成策略在实际开发中一般允许用户手动设置主键一般将主键交给数据库手动编写程序进行设置。在Hibernate中为了减少编程提供了多种主键生成策略。increment Hibernate中提供的增长机制适用于shortintlong类型的主键在单线程中使用identity适用于Intshortlong类型的主键使用的是数据库底层的自动增长机制适用于有自动增长机制的数据库MySQLoracle不支持sequence适用于shortintlong类型的主键采用的是序列的方式Oracle支持序列MySQL不支持uuid使用于字符串类型的主键使用Hibernate中的随机方式自动生成字符串主键native本地策略可以在identity和sequence之间自动切换assignedHibernate放弃主键管理需要自己手动编写程序例如idnamecust_idcolumncust_idgeneratorclassnative//id持久化类的三种状态瞬时态这种对象没有唯一的标识OID没有被session管理持久态这种对象有唯一标识OID被session管理脱管态这种对象有唯一标识OID没有被session管理区分三种状态对象例如publicvoidtest1(){Session sessionHibernateUtil.getSession();Transaction transactionsession.beginTransaction();Customer customernewCustomer();//瞬时态对象customer.setCust_name(李四);Serializable idsession.save(customer);Customer customer1session.get(Customer.class,id);//持久态transaction.commit();session.close();System.out.println(客户名称customer.getCust_name());//脱管态对象}瞬时态对象获得Customer cutomer new Customer();状态转换瞬时 → 持久save(Object obj);saveOrUpdate(Object obj);瞬时 → 脱管customer.setCust_id(1L);持久态对象获得get();load();find();iterate();状态转换持久 → 瞬时delete();持久 → 脱管close();clear();evict(Object obj);脱管态对象获得Customer customer() new Customer(); customer.setCust_id(1L);状态转换脱管 → 持久update();saveIrUpdate();脱管 → 瞬时customer.setCust_id(null);持久态的重要特点持久态可以自动更新数据库由Hibernate的一级缓存实现例如publicvoidtest1(){Session sessionHibernateUtil.getSession();Transaction transactionsession.beginTransaction();Customer customersession.get(Customer.class,6L);customer.setCust_name(王五);transaction.commit();session.close();}上面的程序并有使用update方法但是因为customer是持久态对象所以也会更新数据库的内容为王五Hibernate的缓存什么是缓存缓存是一种优化机制可以将数据存入内存中使用时直接从缓存中获取不用通过存储源Hibernate的一级缓存Hibernate的一级缓存又称session级别的缓存一级缓存的生命周期与session一致一级缓存是Hibernate自带的不可卸载的。特点当应用程序调用session接口的save()update()saveOrUpdate()时如果session缓存中没有相应的对象Hibernate会自动从数据库中查询相应的对象信息到一级缓存中当应用程序调用session接口的load()get()方法以及query接口的list()iterator()方法时会判断缓存中是否存在该对象有则返回没有就会查询数据库并将其添加到一级缓存中当应用程序调用session的close()方法时session缓存会被清空例如publicvoidtest1(){Session sessionHibernateUtil.getSession();Transaction transactionsession.beginTransaction();Customer customersession.get(Customer.class,6L);Customer customer1session.get(Customer.class,6L);System.out.println(customercustomer1);transaction.commit();session.close();}运行结果通过控制台打印的数据我们可以发现程序的两次查询只发送了一次sql语句并且查询得到的对象是一个对象证明Hibernate是有一级缓存的Query的简单使用query接口用于接收HQL查询多个对象查询所有String hqlfrom Customer;Query querysession.createQuery(hql);ListCustomerlistquery.list();for(Customer customer:list){System.out.println(customer);}查询某些带条件查询String hqlfrom Customer where cust_name like ?;Query querysession.createQuery(hql);//从0开始query.setParameter(0,王%);ListCustomerlistquery.list();for(Customer customer:list){System.out.println(customer);}分页查询String hqlfrom Customer;Query querysession.createQuery(hql);//设置起始页query.setFirstResult(0);//设置每页的记录数query.setMaxResults(3);ListCustomerlistquery.list();for(Customer customer:list){System.out.println(customer);}Criteria更加面向对象的查询完全看不到查询语句查询所有Criteria criteriasession.createCriteria(Customer.class);ListCustomerlistcriteria.list();for(Customer customer:list){System.out.println(customer);}查询某些Criteria criteriasession.createCriteria(Customer.class);criteria.add(Restrictions.like(cust_name,王%));ListCustomerlistcriteria.list();for(Customer customer:list){System.out.println(customer);}分页查询Criteria criteriasession.createCriteria(Customer.class);criteria.setFirstResult(0);criteria.setMaxResults(3);ListCustomerlistcriteria.list();for(Customer customer:list){System.out.println(customer);}SQLQuerySQLQuery用于接收sql语句特别复杂的请况下使用。