本帖最后由 小石姐姐 于 2018-6-29 11:17 编辑
[石家庄校区]hibernate框架笔记总结
ORM(Object-Relation-Mapping)框架:对象关系映射框架 是对JDBC的轻量封装 通过操作对象来操作数据库 jar包required包 驱动包 日志包,日志配置文件(放到src下) 配置文件
映射配置文件
类名.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.cyahua.domain.Customer" table="t_customer" catalog="hibernatetest">
<id name="id" column="id" length="11">
<generator class="native"></generator>
</id>
<property name="name" column="name" length="20"></property>
<property name="address" column="address" length="50"></property>
</class>
</hibernate-mapping> 统一声明包名,这样在<class>中就不需要写类的全名. 关于<class>标签配置 name属性:类的全名称 table 表的名称,可以省略,这时表的名称就与类名一 catalog属性:数据库名称 可以省略.如果省略,参考核心配置文件中url路径中的库名称 关于<id>标签 首先它必须存在。<id>是用于建立类中的属性与表中的主键映射。 name中的属性名称 column表中的主键名称 column它也可以省略,这时列名就与类中属性名称一致 length 字段长度 type属性 指定类型 <generator>它主要是描述主键生成策略. 关于<property>标签 它是描述类中属性与表中非主键的映射关系 核心配置文件 hibernate.cfg.xml hibernate.properties 放到src下
hibernate中的数据类型
| | | | | | | | | | | | | | | | | | | | | | | | | | | | boolean、java.lang.Boolean | | | | | | boolean、java.lang.Boolean | | | boolean、java.lang.Boolean | | | java.util.Date、java.sql.Date | | | java.util.Date、java.sql.Time | | | java.util.Date、java.sql.Timestamp | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | |
hibernate工作原理由hibernate.cfg.xml中的<mappingresource="com/xx/User.hbm.xml"/>读取解析映射信息。 通过config.buildSessionFactory();//得到sessionFactory。 sessionFactory.openSession();//得到session。 session.beginTransaction();//开启事务。 persistent operate; session.getTransaction().commit();//提交事务 关闭session; 关闭sessionFactory;
c3p0连接池配置 <!-- 设置连接提供者 -->
<property name="hibernate.connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</property>
<property name="hibernate.c3p0.max_size">20</property> <!-- 最大连接数 -->
<property name="hibernate.c3p0.min_size">5</property> <!-- 最小连接数 -->
<property name="hibernate.c3p0.timeout">50</property> <!-- 超时等待时间 -->
<property name="hibernate.c3p0.idle_test_period">3000</property> <!--空闲连接时间 --> Seesion
如何解决session的线程不安全问题? 在方法内部创建、使用即可 常用api sessionFactory.openSeesion();需要手动调用close()方法关闭 sessionFactory.getCurrentSession();提交事务或回滚时自动close,需要在核心配置文件中配置如下属性 <property name="hibernate.current_session_context_class">thread</property> save() update() delete() get() load() saveOrUpdate() createQuery()操作hql createSQLQuery()操作本地sql createCriteria()完成条件查
Transaction开启事务: session.beginTransaction() 提交: commit(),session.getTransaction().commit() 回滚 rollback(),session.getTransaction().rollback() 如果没有开启事务,那么session的每一个操作都是一个事务,且事务默认不提交 一对一关系添加关联映射1.在任意一方添加外键,指向另一方的主键.
2.两个主键一致.
在pojo中设置私有对象字段.
class Employee{
private Archives archives;
}
class Archives{
provate Employee employee;
}
对多关系添加关联映射(也叫多对一)
1.在多的一方创建外键列指向一的一方的主键.
class Cutomer{
private Set<Order> orders;
}
class Order{
private Costomer costomer;
}
一对多的hbm映射文件costomer.hbm.xml配置<!--客户中的订单是多,所以是one-to-many--><set> <key column="和多的一方共同维护的外键列名称"></key> <!--指明客户pojo中订单的泛型--> <one-to-many class="订单的全类名"></one-to-many></set>
order.hbm.xml配置<!--order是多所以用的是many-to-many--> //一般多的一方维护外键<many-to-one name="当前pojo中的客户对象名称" class="指明客户对象类的全路径" column="创建外键列的名称"></many-to-one>
封装数据时候,我们都是双向关联,这种写法比较繁琐...
双向关联测试问题:必须配置表自自动刷新表结构<property name="hibernate.hbm2ddl.auto">update</property>我创建了一个客户,客户有三个订单,相互创建关系,如果在配置文件中不配置cascade="save-update"属性也可以执行成功,首先插入了一个costomer对象,让后三个订单,最后更新订单表中的外键,这样的话,属实浪费资源.问题:cascade的作用是什么?问题:could not execute statement 无法执行语句
单项关联测试org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: cn.hibernate.domain.Customer如果不设置 cascade="save-update"就会报上面错误,代表一个持久化对象关联了一个瞬时对象一般在多的一方设置cascade="save-update",因为多的一方设置delete,他会将一的一方也会删除,将一的一方删除,随之又会将一的一方的所有关联字段都会删除.
级联删除在操作级联删除的前提条件必须将设置级联,这样保证数据完整性.在一的一方设置 cascade="delect" 级联删除在删除用户时候,底层是先查询出来该用户,在查询该所属该用户的所有订单,先设置为null,然后在逐个删除.
注解开发如何配置实体类@Entity@Table(name="表名称",catalog="数据库名称")@id@GeneraterValue(strategy=GenerationType.IDENTITY)@Column(name="列名称",length=.nullable="true")@Temporal//日期@Transient 忽略字段如果不想在数据库中生成那个字段
主键生成策略为UUID@ID@genericGenerator(name="myuuid",strastegy="uuid").....
Hibernate检索方式概述1.对象导航图检索方式通过映射关系,通过导航方式,检索他关联的持久化对象信息.例如Customer c = session.get(Customer.class,2);c.getOrders().size();
2.oid检索方式Session.get(Customer.class,3);session.load(Order.class,1);通过先获取oid操作持久化对象.
3.hql检索方式1.重点:hql基本语法 String sql= "from Customer";Query query = session.createQuery(sql);List<Customer> list = query.list();2.排序 desc降序 asc升序String sql ="from Order order by money";(根据对象属性)3.条件查询(查询价格大于2000)String sql = "from Order where money >?";Qeruy query = session.createQuery(sql);query.setParameter(0,/范围/);query.list();4.分页检索String sql="form Order";Query query = session.createQuery(sql);query.setFirstResult((2-1)*9);query.setMaxResult(9);List<Order> list = query.list(); 5.分组String sql = "select sum(money) from Order group by c";(根据c)6.投影查询(查找指定的字段)String sql = "select new Customer(name,address) from Costomer";注意:必须提供无参构造和指定的构造.7.命名查询:现将hql语句定义出来,通过Session.getNameQuery("名称");声明位置:1.在对应的hbl.xml中配置<query name="名称"> from Costomer</query>2.在实体中定义方法@Qeruy(name="方法名称","");
4.qbc检索方式query by criteria,一种更加面想对象的检索方式criteria对象qbc步骤:1.得到对象session.createCriteria();2.设定条件3.调用list()1)基本检索@Test//查询所有客户 public void Test1(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); Criteria criteria = session.createCriteria(Customer.class); List<Custeria>list = criteria.list(); session.getTransaction().commit(); session.close();}2)排序检索@Test//根据订单价格排序puiblic void Test(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); Criter criter = session.createCriteria(Order.class); criter.addOder(org.hibernate.criterion.Order.desc("money")); List<Order> list = criter.list(); System.out.println(list); session.getTransaction().commit(); session.close();}3)条件检索@Test//查询名称叫张某public void Test3(){ Session session = HibernateUtils.openSession(); session.beginTransaction(); //查询名称叫张_的人 Session session = session.createCriteria(Customer.calss); Criterion like = Restrictions.like("name","张_"); criter.add(like); Customer customer = criteria.list();&criteria.uniqueResult(); System.out.println(customer); session.getTransaction().commit(); session.close();}多个条件检索:!!!统计查询Object obj = criteria.setProjection(Projections.rowCount()).uniqueResult();System.out.prinln(obj) ---204)离线条件查询DetachedCriteria dc = DetachedCriteria.()
三种主键开发一对一注解两种外键映射(主要),主键映射,在任意一方添加一列作为外键在一方创建外键列@JoinColumn(name="外键名称")在另一方放弃对外键列的维护@OneToOne(targetEntity=目标实体.class,mappedBy="另一方的字段类")
一对多主键一的一方配置@OneToMany(targetEntity=多的一方的.class,mappedBy="外键交给多的一方管理",orphanRemoval)多的一方配置@ManyToOne(targetEntity="一的一方的.class")@JoinColumn(name="外键名称")级联操作根据实际情况而定@Cascade(CascadeType.SAVE-UPDATE)
事务四种隔离级别READ_UNCOMMITED 读取未提交,它引发所有的隔离问题READ_COMMITTED 读已提交,阻止脏读,可能发生不可重复读与虚读.REPEATABLE_READ 重复读 阻止脏读,不可重复读 可能发生虚读SERIALIZABLE 串行化 解决所有问题 不允许两个事务,同时操作一个目标数据。 (效率低下)ORACLE 默认的是事务隔离级别 READ_COMMITTEDMYSQL 默认的事务隔离级别 REPEATABLE_READ
|