您的位置:首页 > 其它

使用Hibernate

2018-03-01 14:56 441 查看
一、Hibernate的第一个程序

1、导入jar包2.domain,以及映射文件User.hbm.xml User.hbm.xml的语法格式:<-- package类的权限定名 --><hibernate-mapping package=""><class name="" table=""> <id name="" column=""> <generator> </id> <property name="" column=""/></class></hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.fkjava.day01._01_crud.domain">
<class name="User" table="t_user">
<id name="id" column="uid">
<generator class="native"/>
</id>
<property name="name"  column="uname"/>
<property name="salary"  column="usalary"/>
<property name="hireDate"  column="uhiredate"/>
</class>
</hibernate-mapping>
3.核心配置文件hibernate.cfg.xml,放到resource中

数据库连接配置和引入映射文件
<!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.dialect">org.hibernate.dialect.MySQL5Dialect</property>
<!-- 配置数据库驱动 -->
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!-- 配置数据库url -->
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/hibernatedemo</property>
<!-- 配置数据库账号 -->
<property name="hibernate.connection.username">root</property>
<!-- 配置数据库密码 -->
<property name="hibernate.connection.password">admin</property>
<!-- 配置session从当前线程中获取 -->
<property name="hibernate.current_session_context_class">thread</property>

<!-- 显示SQL语句 -->
<property name="hibernate.show_sql">true</property>
<!-- 格式化SQL语句 -->
<property name="hibernate.format_sql">true</property>

<!-- 自定生成数据库表的方式 -->
<property name="hibernate.hbm2ddl.auto">update</property>

<!-- 关联映射文件 -->
<!-- <mapping resource="org/fkjava/day01/_01_crud/domain/User.hbm.xml"/> -->
<!-- <mapping resource="org/fkjava/day01/_03_/cfg/Student.hbm.xml"/> -->
<mapping resource="org/fkjava/day01/_04_/oid/Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
Configuration cfg = new Configuration().configure();
SessionFactory factory = cfg.buildSessionFactory();
Session session=  factory.openSession();
// 5.打开事务
session.getTransaction().begin();
// 6.DML操作:
session.save(u);// 保存操作
session.delete(u);
session.update(u);
User user = session.get(User.class, id);
//清空一级缓存所有对象
//session.clear();
//删除一级缓存指定对象
//session.evict(user);
List<User> list = session.createQuery("select u from User u ").list();
// 7.提交/回滚事务
session.getTransaction().commit();
// 8.关闭Session
session.close();


二、SessionFactory
SessionFactory对象:
1.负责创建Session对象
2.数据库的连接信息是配置SessionFactory;
3.SessionFactory是线程安全的,SessionFactory的创建需要很大的系统开销,实际上,在创建sessionFactory的时候才会去连接数据库,一般的,针对一个应用,一个数据库服务器,只需要一个SessionFactory实例就够了.
4.SessionFactory的重要方法:使用银行转账案例,说明openSession和getCurrentSession
1).openSession:这个方法代表,开启一个全新的Session(测试环境)
1.全新的连接
2.全新的事务
3.全新的一级缓存
2).getCurrentSession:得到当前上下文中的session,绑定到当前线程.(开发环境)
1.如果当前上下文中存在session,则使用该session;
2.如果当前上下文中不存在session,则使用opensession创建一个新的session;
3.要使用getCurrentSessoin,必须在hibernate.cfg.xml中配置
<property name="hibernate.current_session_context_class">thread</property>
4.getCurrentSession得到的session是和事务绑定的(Spring集成Hibernate的方式);
1,无论是DML还是DQL ,都必须开启事务
2,当事务提交的时候,session就跟着关闭了.-->此时不需要人为的调用:session.close()


三、OID(就是对象在数据库中对应的主键的属性)
四、session常用方法(一级缓存 类型+OID) session.flush();把一级缓存的脏数据同步到数据库中 session.load(对象,OID);查询数据库中对象(延迟加载,发送sql语句只有真正使用这个对象才会发送,就是使用非主键属性时) load实现原理?使用动态代理,为load的domain动态创建了一个子类,在这个子类中,复写所有非主键调用方法,在这些方法中,去发送. load原理: 1).Hibernate框架的中的javassist组件创建了代理类以及对象. 2).该对象提供了非主键属性的getter方法和toString方法. 3):该对象存在是否加载完毕的状态,访问属性是先判断对象是否加载完毕,如是直接返回该属性之,否则发送SQL查询该对象. get方法返回的总是持久化状态的对象;get方法立刻发送一条SELECT语句,结果可以用if - null来判断load方法并不会立刻发送一条SELECT语句去查询对象,而要到真正在使用(使用一个非主键属性)这个对象的时候,才会去发送SELECT语句,我们把这种方式叫做延迟加载(lazy-load)/懒加载
五、持久化对象的状态 临时状态(没有OID,不在session(即一级缓存)中) 持久化状态(有OID,在session中) 游离状态(有OID,不在session中) 删除状态(就是持久化状态即将从session删掉的状态)session负责改变状态,事务负责同步数据在save操作的时候,需要拿到OID(有些主键生成策略是通过发送sql语句拿到OID,有些不用发送SQL语句就可以拿到OID)脏的持久化对象同步到数据库.(session快照)1: save方法只需要把对象从临时变成持久化状态,只需要找到OID即可.不同的ID生成策略, 有的必须发生INSERT才能得到ID,有的不需要发生INSERT就可以得到ID,所以此时,不需要发送INSERT语句.2: 因为delete方法仅仅只是把游离对象或持久化对象变成删除状态,并不负责发生SQL.3: 持久化对象的属性真正发生改变时,才会发生UPDAE语句. 六、集合映射 1.映射文件配置<!-- 映射Set集合 --><set name="emailSet" table="user_emails_set"><key column="user_id" /><element column="address" type="string" /></set> <!-- 映射Collection/List集合 --><bag name="emailBag" table="user_emails_bag"><key column="user_id" /><element column="address" type="string" /></bag> 2.对象之间的关系(进行关联的时候get方法都是使用延迟加载,所以不会发送sql查找关联的对象,只有使用该对象才会发送sql语句)(先保存没有关联的数据,在保存有外键关联的数据,就不会有脏数据)(维护外键和放弃外键的维护)(单向多对一用的最多) 1)单向多对一(这个外键关联对象) <many-to-one name="dept" column="dept_id"/> 2)单向一对多 <set name="emps" table="t_employee"> <key column="dept_id"/> <one-to-many/> </set> 3)双向一对多,多对一 inverse:放弃外键维护 cascade:级联操作 4)双向的多对多 <set name="teachers" table="students_teachers"> <key column="student_id"/> <many-to-many column="teacher_id"/> </set> 七、hibernate常用的两种查询方式 session.createNativeQuery(sql,返回的对象类型的字节码,如果是数组不用写); session.createQuery(hql,返回的对象类型的字节码,如果是数组不用写);
八、分页查询 setFirstResult/setMaxResult九、位置占位符和命名占位符 就是hql中? 变为:变量名(随意起) 十、投影查询 查询持久化类的一个或多个属性 List<Object[]> list = session.createQuery(hql).list();
十一、封装查询结果HQ封装: new list new map new EmployeeVO(值对象) List<List<object>> list=session.createQuery(hql).list();List<Map<objiect,object>> list=session.createQuery(hql).list();List<EmployeeVO> list=session.createQuery(hql).list();
十二、hql中的集合操作(对集合的操作(size属性或size函数获取集合元素数量 ) is empty) select p from Project p where p.employees.size>0
十三、连接查询 select e.name,d.name from Employee e inner/left join e.dept d;
十四、聚焦函数和子查询 AVG() MAX() COUNT()

十五、事务并发访问问题和事务隔离级别1.事务并发5大问题 第一类丢失更新(一个提交,另一个回滚,提交的也回滚) 脏读(读到未提交的另一个事务的数据) 虚读(读取到已经提交的数据) 不可重复读(读到已经修改的数据) 第二类丢失更新(两个都提交,后一个覆盖前一个)2.4个隔离级别(3个不能处理第一类丢失更新和第二类丢失更新,通过hibernate的锁机制来处理)
十六、悲观锁、乐观锁 悲观所就是给数据上锁 乐观锁不会上锁,但是在更新的时候会判断
十七、JPA(使用注解或者xml配置文件进行描述对象-关系表的映射关系 加载方式 抓取策略) 1.注解 @Entity @Table @id @GeneratedValue @Column @Temporal @Transients 2.配置文件persistence.xml放在classpath/mata-inf 配置文件中的persistence-unit持久化单元相当于session-factory,name必须要写,用来创建持久化管理对象工厂用 持久化对象管理工厂EntityManagerFactory相当于SessionFactory 持久化管理的对象EntityManager相当于SessionEntityManger方法 1,persist;把对象从临时对象转成持久化对象——save;2,find;直接查询一个持久化对象——get;3,merge:把游离对象变成持久化对象——update;4,getReference;相当于load,延迟加载;加载一个持久化对象——load;5,createQuery;创建查询对象;6,createNativeQuery;创建SQL查询对象;7,remove;把持久化对象/游离对象转化为临时对象——delete;8,detach;把持久化对象转化成游离对象——evict;9,close:关闭EntityManager; 3. 放弃维护外键 @ManyToMany(mappedBy="teachers") teachers自己在另一方集合属性名称4.自定义第三方表 @joinTable(name="", joinColumns=@joinColumn(name="" ,referencedColumnName=""), inverseJoinColuns=@joinColumn(name="" ,referemcedColumnName="") )
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Hibernate 使用