¶一、Spring
¶1. 概念
Spring 框架运行时
1 test: spring 提供测试功能
2 Core Container:核心容器.Spring 启动最基本的条件.
2.1 Beans : Spring 负责创建类对象并管理对象
2.2 Core: 核心类
2.3 Context: 上下文参数.获取外部资源或这管理注解等
2.4 SpEl: expression.jar
3 AOP: 实现 aop 功能需要依赖
4 Aspects: 切面 AOP 依赖的包
5 Data Access/Integration : spring 封装数据访问层相关内容
5.1 JDBC : Spring 对 JDBC 封装后的代码.
5.2 ORM: 封装了持久层框架的代码.例如 Hibernate
5.3 transactions:对应 spring-tx.jar,声明式事务使
1.什么是Spring:Spring是一个基于IOC和AOP的结构J2EE系统的框架 。
2.容器(Container): Spring可以理解成一个管理类对象的大容器.
3 ApplicationContext 接口,是 BeanFactory 子接口.BeanFactory 的功能在 ApplicationContext 中都有.(BeanFactory 是老版本Spring的主要信息获得接口.)
4.从 Spring3 开始把 Spring 框架的功能拆分成多个 jar. Spring2 及以前就一个 jar
核心功能
-
IoC/DI 控制反转(IoC)/依赖注入(DI) ——解耦
-
AOP 面向切面编程 ——扩展
-
声明式事务
¶2. IoC/DI
¶2.1 IoC控制反转
- 不用通过new 实例化对象,而是将创建对象的控制权反转给Spring来处理。
- 最大的作用: 解耦。
IoC创建对象的三种方式
(1)通过构造方法创建
两种构造方法创建方式
- 无参构造创建:默认情况
- 有参构造创建:需要明确配置
使用步骤:
①需要在类中提供有参构造方法
②在 applicationContext.xml
中设置调用哪个构造方法创建对象,可以通过<constructor-arg>
指定构造方法
配置参数:
index : 参数的索引,从 0 开始
name: 参数名
type:类型(区分开关键字和封装类,如: int 和 Integer)
如果设定的条件匹配多个构造方法执行最后的构造方法
(2)通过实例工厂创建
需要先创建工厂,才能生产对象。
使用步骤:
①编写实例工厂
②在applicationContext.xml
中配置
1 | <bean id="factory" class="com.qcmoke.pojo.PeopleFactory"></bean> |
(3) 通过静态工厂创建
不需要创建工厂,快速创建对象
使用步骤:
(1)编写一个静态工厂(在方法上添加 static)
(2)在applicationContext.xml
中配置
1 | <bean id="peostatic" class="com.qcmoke.pojo.PeopleStaticFactory" factory-method="newInstance"></bean> |
¶2.2 DI依赖注入
- 可以为Bean注入普通数据类型属性值,还可以注入其他Bean的引用。
¶2.3 案例
①导包:四个核心包一个日志包(commons-logging)
commons-logging-1.1.3.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
②在 src 下新建 applicationContext.xml (文件名称和路径自定义)
1 | "1.0" encoding="UTF-8" xml version= |
默认配置文件被加载时创建对象.
③通过ApplicationContext容器调用applicationContext.xml 里配置的信息
通过调用getBean(“bean标签 id 值”,返回值类型)
来获取对象;如果没有第二个参数,默认是 Object
1 | ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml"); |
¶2. AOP
¶2.1 概念
AOP(Aspect Oriented Programming 面向切面编程)。 在程序原有纵向执行流程中,针对某一个或某一些方法添加通知,形成横切面的过程就叫做面向切面编程。
传统程序执行流程都是纵向执行流程,在原有纵向执行流程中添加横切面,不需要修改原有纵向程序代码就能实现原程序的扩展。
原有功能: 切点, pointcut
前置通知: 在切点之前执行的功能. before advice
后置通知: 在切点之后执行的功能,after advice
如果切点执行过程中出现异常,会触发异常通知.throws advice
所有功能总称叫做切面.
织入: 把切面嵌入到原有功能的过程叫做织入
特点:1.高扩展性 2.释放了部分逻辑.让职责更加明确
¶2.3 实现方式
有两种实现AOP的方式
- Schema-baed
- AspectJ
依赖:
aopalliance.jar aspectjweaver.jar
commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
¶2.3.1 Schema-based
(1)配置applicationContext.xml
导入xml约束(命名空间):
1 | "1.0" encoding="UTF-8" xml version= |
(2)编写切点类
Demo.java
1 | package com.qcmoke.test; |
(3)编写通知类
MyBeforeAdvice.java
1 | package com.qcmoke.advice; |
MyAfterAdvice.java
1 | package com.qcmoke.advice; |
(4) 在applicationContext.xml配置文件里配置<aop:config>
配置
1 | "1.0" encoding="UTF-8" xml version= |
(5)编写测试类
AopTest.java
1 | package com.qcmoke.test; |
¶2.3.2 AspectJ
(1)配置applicationContext.xml
需要将xml约束加入到applicationContext.xml文件开头。
1 | "1.0" encoding="UTF-8" xml version= |
(2)编写切点类
PointObject.java
1 | package com.qcmoke.test; |
(3)编写通知类
MyAspectJAdvice.java
1 | package com.qcmoke.advice; |
(4) 在applicationContext.xml配置文件里配置<aop:config>
配置
1 | "1.0" encoding="UTF-8" xml version= |
(5)编写测试类
AopTest.java
1 | package com.qcmoke.test; |
¶2.4 注解方式使用AOP
通过注解实现AOP的方式其实是基于AspectJ的方式。
实现步骤:
(1)导包:
aopalliance.jar
aspectjweaver.jar
commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
(2)配置applicationContext.xml
1 | "1.0" encoding="UTF-8" xml version= |
(3)编写切点类
假设如下:
PointObject.java
1 | package com.qcmoke.test; |
(4)编写通知类
MyAdvice.java
1 | package com.qcmoke.advice; |
(5) 配置applicationContext.xml
1 | "1.0" encoding="UTF-8" xml version= |
(6)编写测试类
AopTest.java
1 | package com.qcmoke.test; |
¶3. 声明式事务
编程式事务和声明式事务的区别:
¶3.1 概念
-
编程式事务是由程序员编程事务控制代码,而声明式事务得事务控制代码已经由 spring 写好,程序员只需要简单声明出哪些方法需要进行事务控制和如何进行事务控制即可。
-
声明式事务针对的都是 ServiceImpl 类下需要事务处理的方法.
-
事务管理器基于通知(advice)的(即AOP).
¶3.2 实现步骤
¶3.3 声明式事务中属性解释
- **name=”” *哪些方法需要有事务控制
1.1 支持通配符 - **readonly=”boolean” **是否是只读事务.
2.1 如果为 true,告诉数据库此事务为只读事务.数据化优化,会对
性能有一定提升,所以只要是查询的方法,建议使用此数据.
2.2 如果为 false(默认值),事务需要提交的事务.建议新增,删除,修
改. - propagation 控制事务传播行为.(针对多个增删改互相调用的情况)
3.1 当一个具有事务控制的方法被另一个有事务控制的方法调用
后,需要如何管理事务(新建事务?在事务中执行?把事务挂起?报异
常?)
3.2 REQUIRED (默认值): 如果当前有事务,就在事务中执行,如果当
前没有事务,新建一个事务.
3.3 SUPPORTS:如果当前有事务就在事务中执行,如果当前没有事
务,就在非事务状态下执行.
3.4 MANDATORY:必须在事务内部执行,如果当前有事务,就在事务
中执行,如果没有事务,报错.
3.5 REQUIRES_NEW:必须在事务中执行,如果当前没有事务,新建事
务,如果当前有事务,把当前事务挂起.
3.6 NOT_SUPPORTED:必须在非事务下执行,如果当前没有事务,正
常执行,如果当前有事务,把当前事务挂起.
3.7 NEVER:必须在非事务状态下执行,如果当前没有事务,正常执行,
如果当前有事务,报错.
3.8 NESTED:必须在事务状态下执行.如果没有事务,新建事务,如果
当前有事务,创建一个嵌套事务. - isolation=”” 事务隔离级别
4.1 在多线程或并发访问下如何保证访问到的数据具有完整性的.
4.2 脏读:
4.2.1 一个事务(A)读取到另一个事务(B)中未提交的数据,另一
个事务中数据可能进行了改变,此时A事务读取的数据可能和数据
库中数据是不一致的,此时认为数据是脏数据,读取脏数据过程叫
做脏读.
4.3 不可重复读:
4.3.1 主要针对的是某行数据.(或行中某列)
4.3.2 主要针对的操作是修改操作.
4.3.3 两次读取在同一个事务内
4.3.4 当事务A第一次读取事务后,事务B对事务A读取的淑君
进行修改,事务 A 中再次读取的数据和之前读取的数据不一致,过
程不可重复读.
4.4 幻读:
4.4.1 主要针对的操作是新增或删除
4.4.2 两次事务的结果.
4.4.3 事务A按照特定条件查询出结果,事务B新增了一条符合
条件的数据.事务 A 中查询的数据和数据库中的数据不一致的,事
务 A 好像出现了幻觉,这种情况称为幻读.
4.5 DEFAULT: 默认值,由底层数据库自动判断应该使用什么隔离界
别
4.6 **READ_UNCOMMITTED: **可以读取未提交数据,可能出现脏读,不
重复读,幻读.
4.6.1 效率最高.
4.7 **READ_COMMITTED:**只能读取其他事务已提交数据.可以防止脏
读,可能出现不可重复读和幻读.
4.8 **REPEATABLE_READ: **读取的数据被添加锁,防止其他事务修改
此数据,可以防止不可重复读.脏读,可能出现幻读.
4.9 **SERIALIZABLE: **排队操作,对整个表添加锁.一个事务在操作数
据时,另一个事务等待事务操作完成后才能操作这个表.
4.9.1 最安全的
4.9.2 效率最低的. - rollback-for=”异常类型全限定路径”
5.1 当出现什么异常时需要进行回滚
5.2 建议:给定该属性值.
5.2.1 手动抛异常一定要给该属性值. - no-rollback-for=””
6.1 当出现什么异常时不滚回事务.
¶4. 常用注解总结
注意:
-
使用注解一定要添加扫描的类所在的包路径
-
并且尽量开启cglib动态代理,(在使用AOP时,cglib兼容service接口接收代理对象,也兼容以service实现类接收代理对象;而jdk动态代理只兼容service接口接收代理对象)
-
使用注解后
default-autowire
全局自动注入配置就不生效了。
1 | <!-- 扫描含有注解的包,将包路径放到base-package属性值里,如果需要扫描多个包,包路径之间可以通过逗号分隔 --> |
@Component
创建类对象,相当于配置<bean/>
@Service
与@Component
功能相同.
2.1@Service
一般写在ServiceImpl
类上.@Repository
与@Component
功能相同.
3.1@Repository
一般写在数据访问层类上.@Controller
与@Component
功能相同.
4.1@Controller
一般写在控制器类上.@Resource
(不需要写对象的get/set
)
5.1 java 中jdk自带的注解
5.2 默认按照byName
注入,如果没有名称对象,按照byType
注入
5.2.1 建议把对象名称和 spring 容器中对象名相同@Autowired
(不需要写对象的 get/set)
6.1 spring 自带的注解
6.2 默认按照byType
注入.@Value()
获取 properties 文件中内容@Pointcut()
定义切点@Aspect()
定义切面类@Before()
前置通知@After
后置通知@AfterReturning
后置通知,必须切点正确执行@AfterThrowing
异常通知@Arround
环绕通知
¶二、Springmvc
MVC的概念:
-
M指的是module(模型)
-
V指的是view(视图)
-
C指的是controller(控制器)
传统的MVC开发模式中:
M包括service,dao,pojo,bean等
V包括jsp,html等
C包括servlet
而springmvc,不同的是springmvc是不包括传统mvc开发模型的service和dao的。而是对控制层进行mvc化封装。
¶1. 重要核心组件
- DispatcherServlet 前端控制器(分发器、请求入口,负责分发请求,接收所有请求,如果配置/不包含 jsp)
- HandlerMapping 处理器映射器(解析url请求,负责请求和控制器建立一一对应的关系以此来查找Controller)
- HandlAdapter:处理器适配器( 负责调用具体的法(Handler).)
- Controller(Handler)后端控制器(后端处理器)
- ViewResolver 视图解析器(定位和跳转页面,解析不同的文件
¶2 环境搭建
¶2.1 纯配置文件配置
(1)导包
commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
spring-webmvc-4.1.6.RELEASE.jar
(2) 配置前端控制器 (在web.xml中)
1 | "1.0" encoding="UTF-8" xml version= |
(3)创建后端控制器
DemoController.java
1 | package com.qcmoke.controller; |
(4)在src下配置springmvc.xml
1 | "1.0" encoding="UTF-8" xml version= |
¶2.2 注解搭建环境
(1)导包
commons-logging-1.1.3.jar
spring-aop-4.1.6.RELEASE.jar
spring-aspects-4.1.6.RELEASE.jar
spring-beans-4.1.6.RELEASE.jar
spring-context-4.1.6.RELEASE.jar
spring-core-4.1.6.RELEASE.jar
spring-expression-4.1.6.RELEASE.jar
spring-jdbc-4.1.6.RELEASE.jar
spring-tx-4.1.6.RELEASE.jar
spring-web-4.1.6.RELEASE.jar
spring-webmvc-4.1.6.RELEASE.jar
(2)配置前端控制器 (在web.xml中)
1 | "1.0" encoding="UTF-8" xml version= |
(3)创建后端控制器
DemoController.java
1 | package com.qcmoke.controller; |
(4)在src下配置springmvc.xml
1 | "1.0" encoding="UTF-8" xml version= |
¶3. 传参
针对于后端控制器处理方法的参数
默认要求前端传入的name名称要和控制器HandlerMethod的参数名称相同。返回值表示跳转到的页面
spring会自动将请求的数据值注入到方法的参数中,即使是bean对象,也同样会根据bean对象的get/set 方法进行注入。
-
参数是基本数据类型:
默认保证参数名称和请求中传递的参数名相同即可注入
如果请求参数名和方法参数名不对应使用@RequestParam(“请求的数据名称”)赋值,此外@RequestParam(defaultValue=“值”)可以设置参数默认值@RequestParam(required=true)要求请求必须传入值,否则出错
-
参数是对象类型
根据请求参数名和对象中属性名对应(get/set 方法)进行注入
-
参数是集合类型(请求数据为多个同名参数,如复选框)
参数使用集合即可获取注入的请求数据
必须使用@RequestParam()
¶4. 设置字符编码
需要在web.xml文件中添加以下过滤器配置
1 | <!-- 配置字符编码过滤器 --> |
¶三、Mybatis
¶spring整合mybatis
¶1.5.1 环境搭建:
(1) 导包
导 入 mybatis 所 有 jar 和 spring 基 本包,还有
spring-jdbc
spring-tx
spring-aop
spring-web
另外还要spring 整合 mybatis 的包mybatis-spring等
(2)配置 web.xml
目的是让tomcat启动时加载web.xml后自动加载applicationContext.xml文件(3)编写 spring 配置文件 applicationContext.xml
目的是让spring IOC/DI的作用来管理mybatis和service
¶1.5.2 编写代码
(1)正常编写 pojo
(2)编写 mapper,必须使用接口绑定方案或注解方案(必须有接口)
(4)正常编写 Service 接口和 Service 实现类
(5)需要在 Service 实现类中声明 Mapper 接口对象,并生成get/set 方法
¶四、Struts
struts执行流程简单描述图:
搭建步骤:
1.拷贝Struts2的核心Jar包到WEB-INF/lib/下
asm-3.3.jar
asm-commons-3.3.jar
asm-tree-3.3.jar
commons-fileupload-1.3.1.jar 用于实现文件上传功能的jar包。
commons-io-2.2.jar
commons-lang3-3.2.jar
freemarker-2.3.22.jar reemarker是比jsp更简单好用,功能更加强大的表现层技术,用来替代jsp的。 在Struts2中提倡使用 freemarker模板,但实际项目中使用jsp也很多。
javassist-3.11.0.GA.jar
log4j-api-2.2.jar
log4j-core-2.2.jar
ognl-3.0.6.jar 用来支持ognl表达式的,类似于EL表达式,功能比EL表达式强大的多。
struts2-core-2.3.24.jar 核心包
xwork-core-2.3.24.jar Struts2核心包,是WebWork内核。
2.在web.xml配置前端控制器FilterDispatcher
前端控制器实际上是一个过滤器,是所有请求的入口。
1 | "1.0" encoding="UTF-8" xml version= |
3.在src下配置名称为struts.xml
名称一定要是struts.xml,这是约束条件。
1 | <?xml version="1.0" encoding="UTF-8" ?> |
4.创建action
1 | package com.qcmoke.action; |
用到的pojo类:
1 | package com.qcmoke.pojo; |
转发到的页面:
1 | <%"utf-8"%> pageEncoding= |
¶五、Hibernate
¶1. 定义
Hibernate是一个开源,轻量级的ORM(对象关系映射)工具(框架)
对象关系映射技术ORM简化了数据创建,数据处理和数据访问。它是将对象映射到数据库中存储的数据(表)的编程技术。 不需要编写数据库特定的sql语句就能完成对数据库数据的操控,一定程度上摆脱了不同数据库sql差异带来的不便。
orm思想
(1)让实体类和数据库表进行一一对应关系(使用配置文件完成对应联系)
-
让实体类和数据库表对应
-
让实体类属性和表字段对应
(2)不需要用sql语句直接操作数据库表,而是通过操控实体类对象间接操控数据表。
¶2. 环境搭建
下面以用户管理的案例搭建java工程项目的方式来说明步骤。
项目结果如下:
¶2.1 数据库准备
这里使用的是mysql作为数据库来进行讲解。首先在数据库中创建一个数据库用来存Hibernate生成的表。
sql:
1 | mysql> create database ssh; |
¶2.2 导包
antlr-2.7.7.jar
dom4j-1.6.1.jar
geronimo-jta_1.1_spec-1.1.1.jar
hibernate-commons-annotations-5.0.1.Final.jar
hibernate-core-5.0.7.Final.jar
hibernate-entitymanager-5.0.7.Final.jar
hibernate-jpa-2.1-api-1.0.0.Final.jar
jandex-2.0.0.Final.jar
javassist-3.18.1-GA.jar
jboss-logging-3.3.0.Final.jar
log4j-1.2.16.jar
mysql-connector-java-5.0.4-bin.jar
slf4j-api-1.6.1.jar
slf4j-log4j12-1.7.2.jar
¶2.3 创建实体类和对应的映射文件
实体类src/com/qcmoke/entity/User.java
1 | package com.qcmoke.entity; |
映射配置文件src/com/qcmoke/entity/User.hbm.xml
1 | "1.0" encoding="UTF-8" xml version= |
¶2.4 核心配置文
src/hibernate.cfg.xml
1 | "1.0" encoding="UTF-8" xml version= |
¶2.5 测试类
src/com/qcmoke/hibernatetest/HibernateTest.java
1 | package com.qcmoke.hibernatetest; |
¶3. 三大查询对象
- Query
- Criteria
- SQLQuery
¶3.1 Query
1 使用query对象,可以不写sql语句,但是写hql语句
(1)hql:hibernate query language,hibernate提供查询语言,这个hql语句和普通sql语句很相似
(2)hql和sql语句区别:
-
使用sql操作表和表字段
-
使用hql操作实体类和属性
2 查询所有hql语句:
(1)from 实体类名称
3 Query对象使用
(1)创建Query对象
(2)调用query对象里面的方法得到结果