@Beeder
2017-12-22T02:41:04.000000Z
字数 11935
阅读 649
javaWeb
Hibernate核心内容是ORM(关系对象模型)。可以将对象自动的生成数据库中的信息,使得开发更加的面向对象。这样作为程序员就可以使用面向对象的思想来操作数据库,而不用关心繁琐的JDBC。所以,Hibernate处于三层架构中的D层(持久层)

Configuration接口:负责配置并启动Hibernate
Configuration作用:
1. 读取 hibernate.cfg.xml
2. 管理对象关系映射文件
3. 加载 hibernate 驱动 url 以及用户名,密码....
4. 管理 hibernate 配置信息(mapping resource)
SessionFactory作用:
1. 可以缓存sql语句和数据,称为sessionFactory级的缓存(二级缓存)
2. 它是一个重量级的类,因此我们需要保证一个数据库只有一个sessionfactory
SessionFactory接口:负责初始化Hibernate
SessionFactory factory = new Configuration().configure().buildSessionFactory();//openSession();//---是获取一个新的 SessionSession session = factory.openSession();//getCurrentSession();//---获取和当前线程绑定的session,就是在同一个线程中,获取的session是同一个session,这样可以利于事务的控制Session session = factory.getCurrentSession();/*getCurrentSession须先配置才能用:需要在hibernate.cfg.xml的配置文件中提供配置<property name="hibernate.current_session_context_class">thread</property>*/
| 方法 | 使用方式 | 关闭方式 | 线程安全 |
|---|---|---|---|
| openSession() | 同一个线程中,每次都使用不同session | 手动关闭 | 不安全 |
| getCurrentSession() | 同一个线程中,保证使用同一个session | 自动关闭 | 安全 |
Session接口:负责持久化对象的CRUD操作
在创建session这个一级缓存对象的时候,session分为2块区域,一个是缓存区域。一个是快照区域
当到了查询语句, 所获得的数据,缓存区域保存一份,快照区域也保存一份。
到后面的set的时候,会修改缓存区域的参数。
当提交事务的时候,会对比2块区域的内容,一致就没问题。不一致就修改数据库。
session.close() //一级缓存消失Session.clear(); //清空缓存Session.evict(Object entity); //清除指定的对象在一级缓存中的引用Session.flisb(); //使用数据库中的数据覆盖缓存中的数据
// 1.查询所有记录Query query = session.createQuery("from Customer");List<Customer> list = query.list();System.out.println(list);
// 1.条件查询:Query query = session.createQuery("from Customer where name = ?");query.setString(0, "李健");List<Customer> list = query.list();System.out.println(list);// 2.条件查询:Query query = session.createQuery("from Customer where name = :aaa and age = :bbb");query.setString("aaa", "李健");query.setInteger("bbb", 38);List<Customer> list = query.list();System.out.println(list);
//排序查询和SQL语句中的排序的语法是一样的升序session.createQuery("from Customer order by cust_id").list();//降序session.createQuery("from Customer order by cust_id desc").list();
Hibernate框架提供了分页的方法,咱们可以调用方法来完成分页
//两个方法如下:setFirstResult(a) //-- 从哪条记录开始,如果查询是从第一条开启,值是0setMaxResults(b) //-- 每页查询的记录条数//演示代码如下List<LinkMan> list = session.createQuery("from LinkMan").setFirstResult(0).setMaxResults().list();
// 1.查询所有记录Criteria criteria = session.createCriteria(Customer.class);List<Customer> list = criteria.list();System.out.println(list);// 2.条件查询Criteria criteria = session.createCriteria(Customer.class);criteria.add(Restrictions.eq("name", "李健"));List<Customer> list = criteria.list();System.out.println(list);// 3.条件查询Criteria criteria = session.createCriteria(Customer.class);criteria.add(Restrictions.eq("name", "李健"));criteria.add(Restrictions.eq("age", 38));List<Customer> list = criteria.list();System.out.println(list);
Transaction接口:负责事务
/*Hibernate-required start */hibernate-core-5.0.7.Final.jar //核心hibernate-commons-annotations-5.0.1.Final.jar //注解javassist-3.18.1-GA.jar //动态代理dom4j-1.6.1.jar //XML解析antlr-2.7.7.jargeronimo-jta_1.1_spec-1.1.1.jarhibernate-jpa-2.1-api-1.0.0.Final.jarjandex-2.0.0.Final.jarjboss-logging-3.3.0.Final.jarstandard.jar/*Hibernate-required end *//*---------------------------------*///BeanUtils包commons-beanutils-1.8.3.jarcommons-logging-1.1.1.jar/*---------------------------------*///jstl包jstl.jarstandard.jar/*---------------------------------*///mysql驱动包mysql-connector-java-5.1.7-bin.jar/*---------------------------------*//*日志 log4j*/slf4j-api-1.6.1.jar //Hibernate推荐使用的日志接口(未实现)slf4j-log4j12-1.7.2.jar //log4j接口与实现间的链接log4j-1.2.16.jar //log4j具体实现/*---------------------------------*/
持久化类 = JavaBean(Java类) + xxx.hbm.xml(hbm的配置文件)
持久化类的编写规则
1. 提供一个无参数 public访问控制符的构造器 -- 底层需要进行反射.
2. 提供一个标识属性,映射数据表主键字段 -- 唯一标识OID.数据库中通过主键.Java对象通过地址确定对象.持久化类通过唯一标识OID确定记录
3. 所有属性提供public访问控制符的 set或者get 方法
4. 标识属性应尽量使用基本数据类型的包装类型
package com.itheima.domain;/*** 客户的JavaBean* @author Administrator*/public class Customer {/*** `cust_id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '客户编号(主键)',`cust_name` varchar(32) NOT NULL COMMENT '客户名称(公司名称)',`cust_user_id` bigint(32) DEFAULT NULL COMMENT '负责人id',`cust_create_id` bigint(32) DEFAULT NULL COMMENT '创建人id',`cust_source` varchar(32) DEFAULT NULL COMMENT '客户信息来源',`cust_industry` varchar(32) DEFAULT NULL COMMENT '客户所属行业',`cust_level` varchar(32) DEFAULT NULL COMMENT '客户级别',`cust_linkman` varchar(64) DEFAULT NULL COMMENT '联系人',`cust_phone` varchar(64) DEFAULT NULL COMMENT '固定电话',`cust_mobile` varchar(16) DEFAULT NULL COMMENT '移动电话',*/// 以后使用包装类,默认值是nullprivate Long cust_id;private String cust_name;private Long cust_user_id;private Long cust_create_id;private String cust_source;private String cust_industry;private String cust_level;private String cust_linkman;private String cust_phone;private String cust_mobile;public Long getCust_id() {return cust_id;}public void setCust_id(Long cust_id) {this.cust_id = cust_id;}public String getCust_name() {return cust_name;}public void setCust_name(String cust_name) {this.cust_name = cust_name;}public Long getCust_user_id() {return cust_user_id;}public void setCust_user_id(Long cust_user_id) {this.cust_user_id = cust_user_id;}public Long getCust_create_id() {return cust_create_id;}public void setCust_create_id(Long cust_create_id) {this.cust_create_id = cust_create_id;}public String getCust_source() {return cust_source;}public void setCust_source(String cust_source) {this.cust_source = cust_source;}public String getCust_industry() {return cust_industry;}public void setCust_industry(String cust_industry) {this.cust_industry = cust_industry;}public String getCust_level() {return cust_level;}public void setCust_level(String cust_level) {this.cust_level = cust_level;}public String getCust_linkman() {return cust_linkman;}public void setCust_linkman(String cust_linkman) {this.cust_linkman = cust_linkman;}public String getCust_phone() {return cust_phone;}public void setCust_phone(String cust_phone) {this.cust_phone = cust_phone;}public String getCust_mobile() {return cust_mobile;}public void setCust_mobile(String cust_mobile) {this.cust_mobile = cust_mobile;}@Overridepublic String toString() {return "Customer [cust_id=" + cust_id + ", cust_name=" + cust_name + ", cust_user_id=" + cust_user_id+ ", cust_create_id=" + cust_create_id + ", cust_source=" + cust_source + ", cust_industry="+ cust_industry + ", cust_level=" + cust_level + ", cust_linkman=" + cust_linkman + ", cust_phone="+ cust_phone + ", cust_mobile=" + cust_mobile + "]";}}
Customer.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.itheima.domain.Customer" table="cst_customer"><!-- 配置id见到name属性,JavaBean的属性见到column属性,是表结构的字段--><id name="cust_id" column="cust_id"><!-- 主键的生成策略increment:Hibernate中提供的一种增长机制(并发访问会出错)identity:数据库的自动增长(auto_increment)(Oracle数据库没有自动增长)sequence:底层使用的是序列的增长方式(Oracle自动增长需要使用)uuid:使用随机的字符串作为主键native:本地策略(MySQL-使用identity,Oracle-使用sequence)--><generator class="native"/></id><!-- 配置其他的属性 --><property name="cust_name" column="cust_name"/><property name="cust_user_id" column="cust_user_id"/><property name="cust_create_id" column="cust_create_id"/><property name="cust_source" column="cust_source"/><property name="cust_industry" column="cust_industry"/><property name="cust_level" column="cust_level"/><property name="cust_linkman" column="cust_linkman"/><property name="cust_phone" column="cust_phone"/><property name="cust_mobile" column="cust_mobile"/></class></hibernate-mapping>
hibernate.cfg.xml可以参考hibernate包hibernate-release-5.0.7.Final\project\etc\hibernate.properties
<?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><!-- 先配置SessionFactory标签,一个数据库对应一个SessionFactory标签 --><session-factory><!-- 必须要配置的参数有5个,4大参数,数据库的方言 --><!-- mysql数据库驱动 --><property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property><!-- mysql数据库名称 --><property name="hibernate.connection.url">jdbc:mysql:///hibernate_day01</property><property name="hibernate.connection.username">root</property><property name="hibernate.connection.password">root</property><!-- 数据库的方言:为每一种数据库提供适配器,方便转换--><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><!-- 生成数据库的表结构update:如果没有表结构,创建表结构。如果存在,不会创建,添加数据--><property name="hibernate.hbm2ddl.auto">update</property><!-- 映射配置文件,需要引入映射的配置文件 --><mapping resource="com/itheima/domain/Customer.hbm.xml"/></session-factory></hibernate-configuration>
/*** 测试保存*/// 获取sessionSession session = HibernateUtils.getSession();// 开启事务Transaction tr = session.beginTransaction();// 执行代码Customer c = new Customer();c.setCust_name("哈哈");// 保存session.save(c);// 提交事务事务tr.commit();// 释放资源session.close();
/*** 测试查询的方法*/// 原来:加载配置文件,获取Factory对象,获取sessionSession session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();// 创建查询的接口Query query = session.createQuery("from Customer");// 查询所有的数据 select * from 表List<Customer> list = query.list();for (Customer customer : list) {System.out.println(customer);}// 提交事务tr.commit();// 释放资源session.close();}
/*** 测试添加或者修改*/@Testpublic void testSaveOrUpdate(){// 原来:加载配置文件,获取Factory对象,获取sessionSession session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();/*// 演示错误Customer c = new Customer();// c.setCust_id(10L); 千万不能自己设置c.setCust_name("测试");// 保存或者修改session.saveOrUpdate(c);*/// 先查询再改Customer c = session.get(Customer.class, 6L);c.setCust_name("小泽");session.saveOrUpdate(c);// 提交事务tr.commit();// 释放资源session.close();}
/*** 测试修改*/@Testpublic void testUpdate(){// 原来:加载配置文件,获取Factory对象,获取sessionSession session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();// 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值Customer c = session.get(Customer.class, 6L);// 设置客户的信息c.setCust_name("小苍");c.setCust_level("3");// 修改session.update(c);// 提交事务tr.commit();// 释放资源session.close();}
/*** 测试删除的方法* 注意:删除或者修改,先查询再删除或者修改*/@Testpublic void testDel(){// 原来:加载配置文件,获取Factory对象,获取sessionSession session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();// 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值Customer c = session.get(Customer.class, 7L);// 删除客户session.delete(c);// 提交事务tr.commit();// 释放资源session.close();}
/*** 测试get()方法,获取查询,通过主键来查询一条记录*/@Testpublic void testGet(){// 原来:加载配置文件,获取Factory对象,获取sessionSession session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();// 测试查询的方法 2个参数:arg0查询JavaBean的class对象 arg1主键的值Customer c = session.get(Customer.class, 7L);System.out.println(c);// 提交事务tr.commit();// 释放资源session.close();}
/*** 测试工具类*/@Testpublic void testSave2(){// 原来:加载配置文件,获取Factory对象,获取sessionSession session = HibernateUtils.getSession();Transaction tr = session.beginTransaction();Customer c = new Customer();c.setCust_name("小风");session.save(c);// 提交事务tr.commit();// 释放资源session.close();}
/*** 测试保存客户*/@Testpublic void testSave(){/*** 1. 先加载配置文件* 2. 创建SessionFactory对象,生成Session对象* 3. 创建session对象* 4. 开启事务* 5. 编写保存的代码* 6. 提交事务* 7. 释放资源*//*// 1. 先加载配置文件Configuration config = new Configuration();// 默认加载src目录下hibernate.cfg.xml的配置文件config.configure();// 了解,手动加载// config.addResource("com/itheima/domain/Customer.hbm.xml");*/// 简写的方法Configuration config = new Configuration().configure();// 2. 创建SessionFactory对象SessionFactory factory = config.buildSessionFactory();// 3. 创建session对象Session session = factory.openSession();// 4. 开启事务Transaction tr = session.beginTransaction();// 5. 编写保存的代码Customer c = new Customer();// c.setCust_id(cust_id); 主键是自动递增了c.setCust_name("测试3");c.setCust_level("2");c.setCust_phone("110");// 保存数据,操作对象就相当于操作数据库的表结构session.save(c);// 6. 提交事务tr.commit();// 7. 释放资源session.close();factory.close();}
常用方法
save(obj);delete(obj);get(obj);update(obj);saveorupdate(obj);creatrQuery(obj);