使用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>
数据库连接配置和引入映射文件
二、SessionFactory
三、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="") )
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="") )
相关文章推荐
- HibernateTemplate回调函数的使用以及条件语句的拼接
- 大家用hibernate的时候, 使用hibernate的sequence自动增长序列, 数据库是oracle
- Hibernate/Spring/Struts架构使用OpenSessionInView的问题
- Hibernate的一些使用技巧
- 使用Hibernate Synchronizer开发Hibernate应用
- Hibernate使用注意事项
- hibernate中使用criteria的复合查询
- Hibernate jdbc 同时使用 id 自增
- Spring+Hibernate 4+Glassfish之使用JTA Transaction
- ThreadLocal的实现原理,及使用实例,解决spring,hibernate非web项目下的懒加载 no session or session was closed(2)!
- Hibernate中使用SchemaExport&amp;nbsp…
- hibernate,hql与sql的缓存使用
- 使用myeclipse开发第一个hibernate程序
- 使用Hibernate.initialize(Object obj)方法初始化一个代理对象或者集合
- 使用纯JDBC实现hibernate/mybatis的基本功能
- hibernate缓存使用注意事项
- Hibernate之集合映射的使用(Set集合映射,list集合映射,Map集合映射)
- struts+hibernate使用总结
- hibernate5.2.1版本使用
- hibernate的缓存使用