A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

[技术笔记] 学习经历

© csbl 初级黑马   /  2018-7-6 09:59  /  659 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

                                                                                                    学习经历   
Hibernate是一个开放源代码的对象关系映射框架,它对 JDBC进行了非常轻量级的对象封装, 它将 POJO 与数据库表建立映射关系,是一个全自动的 orm 框架,hibernate 可以自动生成 SQL 语句,自动执行,使得 Java 程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate 可以应用在任何使用 JDBC 的场合,既可以在 Java 的客户端程序使用,也可以在Servlet/JSP Web 应用中使用。
对象关系映射(英语:ObjectRelation Mapping,简称 ORM,或 O/RM,或 O/R mapping),是一种程序技术,用于实现面向对象编程语言里不同类型系统的数据之间的转换。 对象-关系映射,是随着面向对象的软件开发方法发展而产生的。面向对象的开发方法是当 今企业级应用开发环境中的主流开发方法,关系数据库是企业级应用环境中永久存放数据的
主流数据存储系统。对象和关系数据是业务实体的两种表现形式,业务实体在内存中表现为
对象,在数据库中表现为关系数据。内存中的对象之间存在关联和继承关系,而在数据库中,关系数据无法直接表达多对多关联和继承关系。因此,对象-关系映射(ORM)系统一般以中间 件的形式存在,主要实现程序对象到关系数据库数据的映射。 ORM 模型的简单性简化了数据库查询过程。
使用 ORM 查询工具,用户可以访问期望数据,而不必理解数据库的底层结构。映射配置文件主要是用于描述实体类与数据表之间的映射关系。 位置:要与实体类在同一个包下. 名称:类名.hbm.xml 约束:hibernate 核心 jar 包下的 org.hibernate 包下hibernate-mapping-3.0.dtd 文件中查找
映射配置文件它的名称是类名.hbm.xml,它一般放置在实体类所在的包下。  这个配置文件的主要作用是建立表与类的映射关系。
  1. 统一声明包名,这样在<class>中就不需要写类的全名.
2. 关于<class>标签配置 name 属性:类的全名称 table 表的名称,可以省略,这时表的名称就与类名一致catalog 属性:数据库名称可以省略.如果省略,参考核心配置文件中 url 路径中的库 名称  3. 关于<id>标签 首先它必须存在。<id>是用于建立类中的属性与表中的主键映射。 name 类中的属性名称  column 表中的主键名称  column 它也可以省略,这时列名就与类中属性名称一致 length 字段长度 type 属性指定类型
<generator>它主要是描述主键生成策略. 4. 关于<property>标签它是描述类中属性与表中非主键的映射关系
Configuration
它主要是用于加载 hibernate 配置. Configuration config=new Configuration().config(); 主要加载 src 下的 hibernate.cfg.xmlConfiguration config=new Configuration();主要加载的 src 下的 hibernate.propertiesConfiguration config=new Configuration().config(核心配置文件名称);加载指定的名称的配置文
Session
Session 接口负责执行被持久化对象的 CRUD 操作(CRUD 的任务是完成与数据库的交流,包含了很多常见的 SQL 语句)。但需要注意的是 Session 对象是非线程安全的。问题:我们如何解决 session 的安全问题?  我们只需要在方法内部来使用 Session 就可以。
问题:Session 如何获取到? SessionFactory.openSession() ; 相当于直接通过 SessionFactory 创建一个新的 Session,使 用完成后要手动调用 close 来关闭。SessionFactory.getCurrentSession(); 获取一个与线程绑定的 Session,当我们提交或事务回 滚后会自动关闭。
Transaction 接口主要用于管理事务,它是 hibernate 的事务接口,对底层的事务进行了封装。 使用它可以进行事务操作。 commit 事务提交 rollback 事务回滚
问题:如果获取一个 Transaction 对象
Session.beginTransaction();
问题:如果在程序中没有开启事务,是否存在事务? 有事务,session 的每一个操作就会开启一个事务
Query 接口让你方便地对数据库及持久对象进行查询,它可以有两种表达方式:HQL 语言或 本地数据库的 SQL 语句。Query 经常被用来绑定查询参数、限制查询记录数量,并最终执行
查询操作。 通过 Query 主要完成查询操作. 我们通过 Query 可以执行 hql 语句.
Query query=Session.createQuery(hql); 下面这个可以执行 sql 语句
SQLQUerysqlQuery=Session.createSQLQuery(sql);
SQLQuery Query 的子.
SQLQuery
要想执行本地 sql
SQLQuerysqlQuery=session.createSqlQuery(String sql); 使用 addEntity 方法来将结果封装到指定的对象中,如果不封装,得到的是 List<Object> 如果 sql 中有参数,我们使用 setParameter 方法完成参数传递。 如果结果就是一个可以使用 uniqueResult()来得到一个单独对象
Criteria 接口与 Query 接口非常类似,允许创建并执行面向对象的标准化查询。值得注意的 Criteria 接口也是轻量级的,它不能在Session 之外使用。
首先我想使用 Criteria,必须得到 Criteria
Criteria criteria=Session.createCriteria()
查询所有操作Session.createCriteria(实体类.class)得到一个 Criteria 对象,调用 list 查询所有分页操作与 query 的方法一样
setFirstResult()    setMaxResults() 条件查询
criteria.add(Restrictions.eq(“name”,”xxxx”));
criteria.add(Restrictions.or(Restricitons.eq(),Restrictions.list()…..))
我们使用 Criteria 可以更加面向对象去操作,它非常适合进行多条件组合查询。
定义 hbm.xml 映射文件和 pojo 类时都需要定义主键,Hibernate 中定义的主键类型包括:自然主键和代理主键:  自然主键:具有业务含义 字段 作为主键,比如:学号、身份证号  代理主键:不具有业务含义字段作为主键(例如 自增 id),比如:mysql 自增主键, oracle 序列生成的主键、uuid()方法生成的唯一序列串
持久化类类三种状态介绍
1. 瞬时态:也叫做临时态或自由态,它一般指我们 new 出来的对象,它不存在 OID, hibernate session 无关联,在数据库中也无记录。它使用完成后,会被 jvm 直接 回收掉,它只是用于信息携带。简单说:无 OID 与数据库中的信息无关联,不在 session 管理范围内。
2. 持久态:在 hibernate session 管理范围内,它具有持久化标识OID 它的特点,在事 务未提交前一直是持久态,当它发生改变时,hibernate 是可以检测到的。 简单说:有 OID session 管理,在数据库中有可能有,也有可有没有。
3. 托管态:也叫做游离态或离线态,它是指持久态对象失去了与 session 的关联,托 管态对象它存在 OID,在数据库中有可能存在,也有可能不存在。 对于托管态对象,它发生改变时 hibernet 不能检测到。
persistenceContext 它是持久化上下文,它其实是真正缓存。 session 中定义了一系列的集合来存储数据,它们构成 session 缓存。 只要 session 没有关闭,它就会一直存在。 当我们通过 hibernate 中的 session 提供的一些 API 例如 save  get update 等进行操作时, 就会将持久化对象保存到 session 中,当下一次在去查询缓存中具有的对象(OID 值来判断)
就不会去从数据库查询,而是直接从缓存中获取。 Hibernate 的一级缓存存在的目的就是为了减少对数据库访问。
hibernate 中还有一个二级缓存,它是 SessionFactory 级别缓存。
一级缓存特点: 1. 当我们通过 session save,updatesaveOrupdate 进行操作时,如果一级缓存中没有 对象,会将这些对象从数据库中查询到,存储到一级缓存。 2. 当我们通过 session load,get,Query list 等方法进行操作时,会先判断一级缓存中是否存在,如果没有才会从数据库获取,并且将查询的数据存储到一级缓存中。
3. 当调用 session close 方法时,session 缓存清空。
Hibernate框架基于ORM设计思想,它将关系型数据库中的表与我们java中的类进行映射,一个对象就对应着表中的一条记录,而表中的字段对应着类中的属性。 数据库中表与表之间存在着三种关系,也就是系统设计中的三种实体关系。
我们在开发中要配置双向关联配置。---------可以通过任意一方来操作对方在操作代码,尽量来要进行单向关联。------可以尽量资源浪费。在双向关联中,会存在多余的 update 语句。我们可以使用 inverse 属性来设置,双向关联时由哪一方来维护表与表之间的关系。
使用 cascade 可以完成级联操作它可常用取值: none 这是一个默认值 save-update,当我们配置它时,底层使用 save update save-update 完成操作,级联保存临时对象,如果是游离对象,会执行 update. delete 级联删除 delete-ophan 删除与当前对象解除关系的对象。all 它包含了 save-update  delete 操作 all-delete-orphan 它包信了delete-orphan all 操作
我们使用注解完成多对多配置. 描述学生与老师. 使用@ManyToMany 来配置多对多,只需要在一端配置中间表,另一端使用 mappedBy 表示放置外键维护权。
Hibernate 提供以下几种检索对象方式: 1 导航对象图检索方式,根据已加载的对象导航到其它对象 2.OID 检索方式,按照对象的 OID 来检索对象 3.HQL 检索方式,使用面向对象的 HQL查询语言 4.QBC 检索方式,使用 QBC(Query byCriteria)API 来检索对象,这种 API 封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口 5.本地 SQL 检索方式,使用本地数据库的 SQL 查询语句
HQL 是我们在 hibernate 中是常用的一种检索方式。 HQLHibernate Query Language)提供更加丰富灵活、更为强大的查询能力因此 Hibernate HQL 查询方式立为官方推荐的标准查询方式,HQL 查询在涵盖 Criteria 询的所有功能的前提下,提供了类似标准 SQL 句的查询方式,同时也提供了更加面向对 象的封装。完整的 HQL 语句形式如下:Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc 其中的update/deleteHibernate3中所新添加的功能, 可见 HQL 查询非常类似于标准 SQL 查询。
我们可以将 hql 语句先定义出来,在使用时通过 session.getNamedQuery(hqlName);得到一个 Query,在执行. 问题:hql 定义在什么位置?  1.如果你有 hbm 配置文件,那么当前的 hql 操作是对哪一个实体进行操作,就在哪一个实体的配置文件中声明。
QBC(query by criteria),它是一种更加面向对象的检索方式。 QBC 步骤:  1.通过 Session 得到一个 Criteria 对象  session.createCriteria()  2.设定条件  Criterion 实例它的获取可以通过 Restrictions 类提供静态。   Criteria add 方法用于添加查询条件 3. 调用 list 进行查询  criterfia.list.
问题:什么是事务?  事务就是逻辑上的一组操作,组成这组操作的各个单元要么全部成功,要么全都失败。
问题:事务四个特性?  原子性:不可分割  一致性:事务在执行前后,要保证数据的一致。  隔离性:一个事务在执行的过程中,不应该受到其它事务的干扰。  持久性:事务一旦结束,数据持久化到数据库。 问题:不考虑事务的隔离性,会产生什么问题?  脏读:一个事务读取到另一个事务的未提交数据 不可重复读:一个事务读取到另一个事务提交的数据(主要是指 update),会导致两次读取 的结果不一致。 虚读(幻读): 一个事务读取到另一个事务提交的数据(主要是指 insert),会导致两次读取结果不一致. 问题:对于上述问题如何解决?
我们可以通过设置隔离级别来解决.  READ_UNCOMMITED 读取未提交,它引发所有的隔离问题  READ_COMMITTED  读已提交,阻止脏读,可能发生不可重复读与虚读.  REPEATABLE_READ 重复读  阻止脏读,不可重复读可能发生虚读 SERIALIZABLE 串行化解决所有问题 不允许两个事务,同时操作一个目标数据。(效率低下)
ORACLE 默认的是事务隔离级别  READ_COMMITTED MYSQL 默认的事务隔离级别  REPEATABLE_READ
HQL 优化
1.使用参数绑定
1.使用绑定参数的原因是让数据库一次解析 SQL,对后续的重复请求可以使用用生成好 的执行计划,这样做节省 CPU 时间和内存。  2.避免 SQL 注入
2.尽量少全长 NOT  
如果 where 子句中包含 not 关键字,那么执行时该字段的索引失效。
3.尽量使用 where 来替换 having
Having 在检索出所有记录后才对结果集进行过滤,这个处理需要一定的开销,而 where 子句限制记录的数目,能减少这方面的开销
4.减少对表的查询
在含有子查询的 HQL ,尽量减少对表的查询,降低开销
5.使用表的别名
当在 HQL 语句中连接多个表时,使用别名,提高程序阅读性,并把别名前缀与每个列上,这样一来,可以减少解析时间并减少列歧义引起的语法错误。
6.实体的更新与删除
hibernate3 以后支持 hql update delete 操作
抓取策略介绍
指的是查找到某个对象后,通过这个对象去查询关联对象的信息时的一种策略。一对一 <one-to-one> 一对多(多对一) <set>下有<one-to-many>  <many-to-one> 多对多 <set>下有<many-to-many> 我们主要是在<set><many-to-one><one-to-one>上设置 fetch  lazy
例如:查询一个客户,要关联查询它的订单客户是一的一方,在客户中有 set 集合来描述其订单,在配置中我们是使用
<set>
<one-to-many>
</set>.. 可以在 set 标签上设置两个属性  fetch  lazy Fetch 主要描述的是 SQL 语句的格式(例如是多条,子查询,多表联查 Lazy 控制 SQL 语句何时发送
例如:在查询一个订单时,要查询客户信息 <many-to-one> <one-to-one>也可以设置 fetch lazy Fetch 主要描述的是 SQL 语句的格式(例如是多条,子查询,多表联查 Lazy 控制 SQL 语句何时发送
Mavenapache下的开源项目,项目管理工具,管理java项目。
工程目录结构说明: project/src/main/java 主体程序 java源文件(不要放配置文件)
/src/main/resources 主体程序所需要的配置文件(不要放java文件)
/src/test/java 单元测试程序 java源文件
/src/test/resources 单元测试程序所用的配置文件
/target 编译输出目录
pom.xml Maven进行工作的主要配置文件。
Maven有三套相互独立的生命周期,分别是:cleandefaultsiteclean
要是清理项目、defaultMaven最核心的的构建项目、site是生成项目站点。每
一个大的生命周期又分为很多个阶段。后面的阶段依赖于前面的阶段,这点有点
Ant的构建依赖。生命周期本身相互独立,用户可以仅仅调用生命周期的某一
个阶段,也就是说用户调用了default周期的任何阶段,并不会触发clean周期以
site周期的任何事情。
创建index.jsp <%@ pagelanguage="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTDHTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"> <html> <head><meta http-equiv="Content-Type" content="text/html;charset=UTF-8"> <title>测试页面</title> </head> <body> 开启神秘的 Maven 世界~</body> </html>
SSH2框架需要添加的依赖如下: <dependencies> <dependency><groupId>javax.servlet</groupId><artifactId>servlet-api</artifactId><version>2.5</version> <scope>provided</scope></dependency> <dependency> <groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.0.7.Final</version> </dependency><dependency> <groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>4.2.4.RELEASE</version></dependency> <dependency><groupId>org.springframework</groupId> <artifactId>spring-beans</artifactId><version>4.2.4.RELEASE</version> </dependency><dependency> <groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>4.2.4.RELEASE</version> </dependency><dependency> <groupId>org.springframework</groupId><artifactId>spring-orm</artifactId><version>4.2.4.RELEASE</version> </dependency><dependency> <groupId>org.springframework</groupId><artifactId>spring-test</artifactId> <version>4.2.4.RELEASE</version></dependency> <dependency> <groupId>org.springframework</groupId><artifactId>spring-context-support</artifactId><version>4.2.4.RELEASE</version> </dependency><dependency> <groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>4.2.4.RELEASE</version> </dependency> <dependency><groupId>org.springframework</groupId><artifactId>spring-web</artifactId><version>4.2.4.RELEASE</version> </dependency><dependency> <groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.7</version> </dependency><dependency><groupId>org.apache.struts</groupId><artifactId>struts2-core</artifactId><version>2.3.24</version> </dependency> <dependency><groupId>org.apache.struts</groupId> <artifactId>struts2-spring-plugin</artifactId><version>2.3.24</version> </dependency> <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.6</version> </dependency> <dependency><groupId>jstl</groupId> <artifactId>jstl</artifactId><version>1.2</version> </dependency> </dependencies>
添加struts配置文件 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPEstruts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"><struts> <package name="default" namespace="/"extends="struts-default">
</package> </struts>修改web.xml 配置文件,添加以下配置<listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <context-param><param-name>contextConfigLocation</param-name><param-value>classpath*:applicationContext.xml</param-value></context-param> <filter><filter-name>openSessionInView</filter-name><filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping><filter-name>openSessionInView</filter-name> <url-pattern>/*</url-pattern></filter-mapping> <filter><filter-name>struts2</filter-name><filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping><filter-name>struts2</filter-name> <url-pattern>/*</url-pattern></filter-mapping>
编写实体类 packagecn.itcast.mavenweb.domain; /** * 部门 * @authorAdministrator * */ public class Dep {
private Long uuid; private String name;private String tele;
public Long getUuid() { return uuid; }public void setUuid(Long uuid) { this.uuid = uuid; } public String getName() {return name; } public void setName(String name) { this.name = name; } publicString getTele() { return tele; } public void setTele(String tele) { this.tele= tele; }
}
编写映射文件
src/main/resources 下创建包cn.itcat.mavenweb.domain
在此目录下创建映射文件dep.hbm.xml ,内容如下: <?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC"-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><hibernate-mapping> <classname="cn.itcast.mavenweb.domain.Dep" table="dep" ><id name="uuid" > </id> <propertyname="name" /> <property name="tele" /></class> </hibernate-mapping>
创建数据访问层接口DepDao packagecn.itcast.mavenweb.dao;
import java.util.List;
import cn.itcast.mavenweb.domain.Dep;
/** * 部门 Dao * @author Administrator * */ public interface DepDao {
public List<Dep> getList();
}

0 个回复

您需要登录后才可以回帖 登录 | 加入黑马