首页 > 代码库 > 8.28笔记
8.28笔记
1.在项目中引入jar包,并且添加引用
2.创建hibernate.cfg.xml配置文件
需要配置的内容
1.1Driver_class:驱动
Url:配置
Username:用户名
Password:密码
1.2.方言的配置
1.3在后台生成SQL打印到console台
1.4关联小配置
3.配置小配置
在entity包中创建一个和实体类同名的xml文件。Student.hbm.xml
4.我想save a record to db,what’s step we should do?
解析:1.引入jar包
2.书写大配置文件
大配置文件必须放置在项目根目录(专业classpath下):界定:就是src
<?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>
<session-factory>
<!-- Database connection settings 数据库连接设置-->
<!-- 驱动类 -->
<property name="connection.driver_class">oracle.jdbc.OracleDriver</property>
<!-- url地址 -->
<property name="connection.url">jdbc:oracle:thin:@localhost:1521:orcl</property>
<property name="connection.username">dog</property>
<property name="connection.password">dog</property>
<!-- SQL dialect (SQL 方言) -->
<property name="dialect">org.hibernate.dialect.Oracle10gDialect</property>
<!-- Echo all executed SQL to stdout 在控制台打印后台的SQL语句 -->
<property name="show_sql">true</property>
<!-- 格式化显示SQL -->
<property name="format_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<!-- 关联小配置 -->
<mapping resource="cn/happy/entity/Student.hbm.xml" />
</session-factory>
</hibernate-configuration>
3.创建小配置
<?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="cn.happy.entity">
<class name="Student" table="STUDENT">
<id name="sid" column="SID">
<!-- 主键生成策略:native:
native:如果后台是Oracle
后台是MySQL,自动应用自增
assigned:程序员给主键赋值
uuid:32位的16进制数
sequence
native
-->
<generator class="sequence">
<param name="sequence">SEQ_NUM</param>
</generator>
</id>
<property name="name" type="string" column="NAME"/>
<property name="age"/>
</class>
</hibernate-mapping>
4.测试类
Configuration cfg=new Configuration().configure(“默认读取src下的名称为hibernate.cfg.xml”);
SessionFactory sessionFactory=cfg.buildSessionFactory();
Session session=sessionFactory.openSession();
//执行 insert update delete 操作,HIbernate中必须开启事务
Transaction tx=session.beginTransaction();
Session.save(xxx);
Tx.commit();
Session.close();
作业:
1.今天的HIbernate入门案例写成blogs文章
2.自己完成通过HIbernate做到 修改,删除,查询例子
3.让你的机器上有idea环境
2016年8月6日13:38:54
1.hibernate中两种配置文件,
Hibernate.properties
Hibernate.cfg.xml
读取的是Hibernate.properties
2.sessionFactory重量级的,一个程序中只能有一个,并且是线程安全的。Session每个线程一份,线程非安全!
3.HIbernate中的是session,不是http协议中的session。当然他也不是connection,初学者可以看成是connection
4.PO=POJO+xml配置
5.HIbernate框架位于应用程序和数据库之间,将数据库底层操作完全封装。应用po对象进行HIbernate操作,完成对数据库的操作。
6.Java对象的三种状态
1.瞬时状态
Student stu=new Student(); //session和数据库中都没有
2.持久态 (OID)
Session.save(stu);//session和数据库中都有
3.游离态 (OID)
Session.close();//session中没有,数据库中有
7.ORM原理
思维:一个标准可以统领N个实现
POJO和PO
Configuration:SchemaExport:生成后台的SQL脚本
SessionFactory:一个应用程序中,只能有一个.
Session:多线程并发情况,解决线程安全的方案
方案一:通过synchronized关键字
方案二:ThreadLocal get() set()
Java对象的三种状态
8.作业:序列化和持久化
Load和get()
saveOrUpdate()和merge()
Session线程非安全
关于代理对象
2016年8月8日13:38:50
1.load()和get()区别
解析:
1.1我们在程序中提供的OID,对应的底层数据库没有编号,load()报错,get()得到null
Load()报错的情况
1.2 延迟加载
Load()延迟加载 ,原因:产生的是代理对象
Get()非延迟加载, 原因:对象本身
共同特点:session.get(Student.class,1)
Session.load(Student.class,1)
策略:先检索session级别的缓存,如果没有,接着检索二级缓存,然后二级缓存也没有,检索数据库
2.session存储机制,一级缓存(Session)和二级缓存(SessionFactory)区别
3.脏检查
什么时机,HIbernate会进行脏检查。
清理缓存
清空缓存
4.如何在HIbernate继承log4j日志框架
5.数据库的四种隔离级别,隔离级别出现目的,解决什么问题
脏读,不可重复读,和幻象读
Oracle数据库默认事务隔离级别:Read-Commited
丢失更新(乐观锁和悲观锁)
6.小细节
2016年8月9日14:16:45
Save()
Update()
SaveOrUpdate()
Merge()
Delete()
检索单个对象
Load()
Get()
批量查询所有记录
HQL:HIbernate Query Language HIbernate查询语言
From +类名
场景1:从数据表中拎出所有的姓名,打印到控制台
-----------------------------------------------------
2016年8月11日13:44:52
1.HQL概念
2.HQL查询所有列
From Student
List<Student> list=session.createQuery(“from Student”).list();
3.检索部分列
List<Object[]> list= session.createQuery(“select age,name from Student”).list();
4.检索单列
List<String> list= session.createQuery(“select name from Student”).list();
5.参数书写和赋值方式
两种,第一种:?
query.setParameter(“0”,”张三”);
第二种:名称 :属性名
query.setParameter(“属性名”,”属性值”)
6.动态查询
核心代码:
job |
salary |
StringBuilder sb=new StringBuilder (“select stu from Student stu where 1=1 ”);
If(stu.getJob()!=null){
Sb.apppend(“ and job=:job ”);
}
....
...
..
Query query=session.creatQuery(sb.toString());
Query.setProperties(stu);
StringBuffer和StringBuilder区别?
解析: StringBuffer和StringBuilder类都表示内容可以被修改的字符串,StringBuilder是线程不安全的,运行效率高,如果一个字符串变量是在方法里面定义,这种情况只可能有一个线程访问它,不存在不安全的因素了,则用StringBuilder。如果要在类里面定义成员变量,并且这个类的实例对象会在多线程环境下使用,那么最好用StringBuffer。
1.分页
我要学生表中的4---6条数据
1.关联关系中的单向多对一
Eg> 员工(多的一方)和部门(一的一方)
步骤:1.构建两个实体类,在entity层
Dept.class
package cn.happy.entity;
/**
* 1.1 部门表
* @author happy
*
*/
public class Dept {
private Integer deptNo;
private String deptName;
public Integer getDeptNo() {
return deptNo;
}
public void setDeptNo(Integer deptNo) {
this.deptNo = deptNo;
}
public String getDeptName() {
return deptName;
}
public void setDeptName(String deptName) {
this.deptName = deptName;
}
}
package cn.happy.entity;
/**
* 1.2 员工类
* @author happy
*
*/
public class Emp {
private Integer empId;
private String empName;
//记住 部门信息
private Dept dept;
public Integer getEmpId() {
return empId;
}
public void setEmpId(Integer empId) {
this.empId = empId;
}
public String getEmpName() {
return empName;
}
public void setEmpName(String empName) {
this.empName = empName;
}
public Dept getDept() {
return dept;
}
public void setDept(Dept dept) {
this.dept = dept;
}
}
2.创建两个hbm小配置文件
Emp.hbm.xml
<many-to-one name=”dept” class=”Dept” column=”deptNo”></many-to-one>
3.构建大配置
引入小配置
4.测试类
3.一对多
Dept.hbm.xml
<set name=”emps”>
<key column=”deptNo”></key>
<one-to-many class=”Emp”></one-to-many>
</set>
4.cascade:级联
级联添加:当我添加部门的时候,自动添加员工
5.inverse:反转
周五作业:
1.7个人,周一提问HQL语句和关联映射
2.形成blogs,多对一单向关联
一对多双向关联
晚上完成的
3.按照我的文档或者视频。。两种多对多配置,并且形成blogs。
云题库相关知识点! 周一上午考试!
4.预习第七章视频,缓存。二级缓存视频。
---------------九章 注解,Cretiater查询-----
MyBatis框架
-------------------------------------------------------------------
8月29日 HIbernate内测+Struts2 第一章
2016年8月13日13:39:54
1.关联映射
多对一单向关联
在Emp类植入Dept属性
Emp.hbm.xml
<many-to-one name=”dept” class=”Dept” column=”detpNo”></many-to-one>
一对多双向关联
部门中建立员工集合
在Emp类植入Dept属性
Dept.hbm.xml
<set name=”emps”>
<key column=”deptNo”></key>
<one-to-many class=”Emp”/>
</set>
1.多对多单向
2.多对多的双向
Project
Emp
方案二:有第三张表关系表介入的
Project
Emp
ProEmp
3个小配置
3.延迟加载
立即加载:
2016年8月15日13:41:54
1.session.openSession() 随机从Session工厂中拎出一个Session
程序员手动的关闭Session
Session.getCurrentSession():获取一个和线程绑定的session。如果发现线程变量中没有 session,也是使用openSession.当事务有出口(commit ,rollback)的时候,自动将session关闭.
你要想在程序中使用getCurrentSession,得再大配置中加一个
<!-- <property name="current_session_context_class">thread</property> -->
2.no session问题
问题引发:因为dao使用load(),默认延迟加载的,当在biz关闭session之后,UI层无法获取对象的非ID属性值。
解决方案:1.变成get,即时加载
2.用Hibernate.isInitialized(obj)被初始化。
3.类级别的lazy=”false”
4.实体类用final修饰,由于大家都知道。延迟加载的原因是内存中有代理对象(其实是Emp类的子类)。咱们可以让一个类没有子类。
5.在biz层先用一道需要UI使用到的属性。然后在biz关闭。
6.b/s,Hibernate提供了一个解决方案:OpenSessionInView。
2.1 类级别的查询策略
Lazy:true (默认值)
False
3.多对一关联的查询策略
Lazy:proxy (默认值)
No-proxy
false
4.一对多,或者多对多
Fetch:影响Hibernate针对底层SQL的生成。
当fetch和lazy连用的时候,有两种情况必须知道
情况一:当fetch取值为Join的时候,lazy属性会被忽略。Set集合中的lazy,或者多对一中配置的lazy。
情况二:当咱们使用query接口的list()方法,他会忽略配置中的左外连接查询,这个时候lazy属性重新发挥作用。
5.三种场景下,lazy各自取值和默认值。
4.openSessionInView模式
UI开启session
每当有一个请求过去,先走过滤器。开事务,开session
2016年8月16日13:40:46
缓存:就是一块空间,用来保存经常访问的数据
分类:一级和二级缓存(查询缓存基于二级缓存)
一级和session相关,和一次事务相关!
1.二级缓存的插件配置
EHCache插件
1.引入3个jar包
2.在大配置中
3.在src下添加ehcache.xml文件,从etc获取文件即可。
2.get和load方法数据可以进入,一级缓存和二级缓存,并且可以从一级缓存和二级缓存取数据。但是如果使用list(),这个时候只能将数据放入二级缓存,不能取,如果想取出数据,可以使用iterator方法()
3.关于query接口的list()和iterator()区别
4点!
4.集合缓存
5.N+1问题
描述:形成1条SQL+N条SQL
Iterator()
一对多,
弊病:
对数据库访问还是必须考虑性能问题的, 在设定了1 对多这种关系之后, 查询就会出现传说中的n +1 问题。
1 )1 对多,在1 方,查找得到了n 个对象, 那么又需要将n 个对象关联的集合取出,于是本来的一条sql查询变成了n +1 条
2)多对1 ,在多方,查询得到了m个对象,那么也会将m个对象对应的1 方的对象取出, 也变成了m+1
怎么解决n +1 问题?
1 )lazy=true, hibernate3开始已经默认是lazy=true了;lazy=true时不会立刻查询关联对象,只有当需要关联对象(访问其属性,非id字段)时才会发生查询动作。
2)二级缓存, 在对象更新,删除,添加相对于查询要少得多时, 二级缓存的应用将不怕n +1 问题,因为即使第一次查询很慢,之后直接缓存命中也是很快的。
不同解决方法,不同的思路,第二条却刚好又利用了n +1 。
3) 当然你也可以设定fetch=join
-----2016年8月18日09:13:24
1.list()方法
只能向缓存中放入数据,不能取(查询缓存除外)
List()和iterator()区别
1.返回类型
2.查询策略不同:iterator()取出所有id,根据id检索,形成N+1问题。List一条SQL。
3.延迟加载角度,iterator()代理对象,list()对象本身
优化策略,批量删除
一对一
Fk: Foreign key (外键配置)
Resume1 Resid rescardNo rescardName
ResumeUserId
|
Users1 (主的一方) Uid Uname Upass
|
Pk方式配置一对一
Users2.hbm.xml
Users1 Uid (pk,fk) Uname Upass
表中形成外键约束
|
Resume1(主的一方) Resid pk rescardNo rescardName |
<id> <generator name=”foreign”> <param name=””>resume2 <> </id>
<one-to-one constrained=”true”></> |
组件映射
3.HQL连接查询
query.createQuery(hql代码)
query.doWork()
query.list()
Query.iterator()
query.createSQLQuery(sql代码)
2016年8月22日13:35:08
1.QBC(Query by Criteria)进行检索
1.没有任何条件
Criteria接口
Criteria.add() 仍然是他本身
2.带条件查询
Restrictions.eq() :Criterion 类型,作为Criteria的参数存在
3.关于别名的设置方式
criteria.createAlias(“dept”,”别名”)
关联查询 (用多的一方作为条件。获取多的一方的集合)
在CreateCriteria(一的一方的字节码)
4.Restrictions.in( )
2016年8月23日14:15:59
注解
@Entity
@Id
@Column
@Table
@GeneratedValue:设置属性的生成策略
@自定义的生成器
@GenericGenerator
HIbernate持久层和一个Orm框架。
担当角色
持久层的一个框架
访问数据的一个原理图
出发点Session.XXXXXX系列
推导Session-------->SessionFactory
SessionFactory----->new Configuration().configure(“hibernate.cfg.xml”).buildSessionFactory()
MyBatis:学习成本低,半自动化ORM框架,性能比HIbernate高,SQL语句是程序员手工定制的。程序员可以控制SQL语句的性能。
前身叫Ibatis 。并且被 .NET领域 ,挖掘过去叫NHibernate,
Hibernate比较笨重。
主流企业已经全线摒弃HIbernate,启用MyBatis。
据不完全统计,每10个开发团队,有11个在用Mybatis.
------------入门案例
1.检索部门信息
1.1 做实体类
@Override
public String toString() {
return "Dept [deptNo=" + deptNo + ", deptName=" + deptName + "]";
}
1.2 写MyBatis 大配置 mybatis-config.xml
<transactionManager type="JDBC" />
<!-- 数据源的方式 POOLED -->
<dataSource type="POOLED">
<property name="driver" value=http://www.mamicode.com/"oracle.jdbc.OracleDriver" />
<property name="url" value=http://www.mamicode.com/"jdbc:oracle:thin:@localhost:1521:orcl" />
<property name="username" value=http://www.mamicode.com/"dog" />
<property name="password" value=http://www.mamicode.com/"dog" />
</dataSource>
1.3 写小配置 Dept.xml
<select id="selectAllDept" resultType="cn.happy.entity.Dept">
<!-- 这里写的SQL,而不是HQL,SQL中的表名是不区分大小写的 -->
select * from dept
</select>
植入SQL
1.4 写测试类
//session---->SQLSesssionFactory----->SqlSessionFactoryBuilder
Reader reader=Resources.getResourceAsReader("mybatis-config.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader);
8.28笔记