第一章:初始MyBatis
一:框架技术
1.主流框架:1)Struts框架:从逻辑中分离出横切关注点的拦截器,减少或者消除配置文件,贯穿整个框架的强大表达式语言,支持可变更和可重用的基于MVC模式的标签API等
2)Hibernate框架:是一个优秀的持久化框架,负责简化将对象数据保存到数据库中,或从数据库中读取数据并封装到对象的工作,Hibernate通过简单配置和编码即可替代JDBC繁琐程序代码
3)Spring框架:是一个开源框架,渗透JavaEE技术方方面面,主要作为依赖注入容器和AOP实现存在,提供声明式事物,对DAO层的支持等简化开发的功能
4)SpringMVC框架:是Spring框架提供的构建Web应用程序的全功能MVC模块,拥有高度的可配置性,支持多种视图技术
5)MyBatis框架:是一个优秀的数据持久层框架,在实体类和SQL语句之间建立映射关系,是一种半自动化的ORM实现
二:MyBatis介绍及环境搭建
1.数据持久化概念:数据持久化是将内存中的数据模型转换为存储模型,以及将存储模型转化为内存中的数据模型的统称,例如文件的存储,数据的读取等都是数据持久化操作
2.MyBatis框架及ORM:1.MyBatis是内部封装了通过JDBC访问数据库的操作,支持普通的SQL查询,存储过程和高级映射,几乎消除所有JDBC代码和参数的手工设置以及结果集的检索
(MyBatis其主要思想是将程序中的大量SQL语句剥离出来,配置在配置文件中,实现SQL的灵活配置)
2.ORM:ORM即对象/关系映射,是一种数据持久化技术。它在对象模型和关系型数据库之间建立起对应关系
3.MyBatis通过简单的XML或者注解进行配置和原始映射,将实体类和SQL语句之间建立映射关系,是一种半自动化得ORM实现
4.基于ORM,MyBatis在对象模型和关系数据库的表之间建立一座桥梁,通过MyBatis建立SQL关系映射,以便捷的实现数据库的增删改查
3.MyBatis环境搭建:1)将MyBatis的两个jar包,log4j的jar包和MySQL的jar包放到项目中WEB-INF下的lib目录中
2)在项目下新建Source Folder类型的resources目录,
在resources目录下建文件名为mybatis-config.xml的MyBatis的核心配置文件
在resources目录下建文件名为database.properties的数据库配置文件
在resources目录下建文件名为log4j.properties的记录异常的配置文件
注意:mybatis-config.xml文件的几个常用元素的作用:1)configuration:配置文件的根元素节点
2)properties:通过resource属性从外部指定properties属性文件,描述数据库连接的相关配置位置也在resources目录下
3)settings:设置MyBatis运行中的一些行为,比如此处设置MyBatis的log日志实现为LOG4J,即使用log4j实现日志功能
4)environments:配置MyBatis的多套运行环境,将SQL映射到不同的数据库上,该元素节点下可以有多个environment子节点元素,但必须指定一个默认运行环境(通过default指定)
5)environment:配置MyBatis的一套运行环境,需指定运行Id,事务管理,数据源配置等相关信息
6)mappers:作用告诉MyBatis去哪找到SQL映射文件(即SQL语句,整个项目可以有多个或一个)
7)mapper: mappers的子元素节点,具体指定SQL映射文件的路径
3)创建持久类(POJO)和SQL映射文件:持久类指实例状态需要被MyBatis持久化到数据库中的类(即三层框架中的实体类)
4)创建DAO层,下建一个例:UserMapper.xml的文件,(在里面写SQL语句)
UserMapper.xml的文件的常用元素:mapper:映射文件的根元素节点,只有一个属性namespace(用于区分不同的mapper,全局唯一)
select:表示查询语句,是MyBatis常用元素之一;常用属性Id(命名空间唯一标识符),resultType(SQL语句的返回类型)
5)创建测试类:读取全局配置文件:mybatis-config.xml
创建SqlSessionFactory对象,此处可完成配置文件的读取
创建sqlSession对象,作用是调用mapper文件进行数据操作(需先把mapper文件引入mybatis-config.xml中才能生效)
关闭SqlSession对象
4.MyBatis框架的优缺点
1)优点:a.与JDBC相比,减少50%以上代码量
b.mybaties是最简单的持久化框架,小巧并简单易学
c.MyBatis相当灵活,不会对应用程序或者数据库设计有影响,降低代码的耦合度
d.提供XML标签,支持编写动态SQL语句
e.提供映射文件,支持对象与数据库的ORM字段关系映射
2)缺点:a.SQL语句的编写工作量较大
b.SQL语句依赖于数据库,导致数据库的移植性差
三:MyBatis的基本要素
1.MyBatis的三个基本要素:核心接口和类
MyBatis核心配置文件(mybatis-config.xml)
sql映射文件(mapper.xml)
2.SqlSessionFactoryBuilder:负责构建SqlSessionFactory,并提供多个builder()方法的重载
最大的特点就是:用过即丢,他的作用域存在方法体中,也是局部变量
3.SqlSessionFactory:是创建SqlSession实例的工厂
注意:openSession()方法的参数为Boolean值时,若传入true表示关闭事务控制,自动提交;false表示开启事务控制。若不传参,默认为true
SqlSessionFactory对象只要创建了,就会在整个应用程序中始终存在,它的作用域是全局的
4.SqlSession:用于执行持久化操作的对象,类似JDBC中的Connection,它提供面向数据库执行SQL命令所需的所有方法,可通过SQLSession实例直接运行已映射的SQL语句
SqlSession对应一次数据库会话,如关闭了就需重新创建
四:MyBatis的基本要素-核心配置文件
1.mybatis-config.xml文件结构:1)properties元素:描述的是外部化,可替代的属性
2)settings元素:作用是设置一些重要的设置选项,用于设置和改变MyBatis运行中的行为
3)typeAliases元素:作用是配置类型别名,简化操作
例子:
4)environments元素:默认运行Id,通过default指定当前运行环境Id为development
transactionmanager事物管理器,设置type类型为JDBC
dataSource元素:使用JDBC数据源接口来配置JDBC对象连接的资源
5)mappers元素:映射器,用来定义SQL的映射语句
使用类资源路径获取资源:
使用URL获取资源:
第二章:SQL映射文件
一:使用MyBatis实现条件查询
1.SQL映射文件:
SQL映射文件的顶级元素配置:mapper:映射文件的根节点元素
cache:配置给定命名空间的缓存
cache-ref:从其他命名空间引用缓存配置
resultMap;用来描述数据库结果集和对象的对应关系
Sql:可以重用的SQL块,也可被其他语句引用
insert:映射插入语句
update: 映射更新语句
delete:映射删除语句
select:映射查询语句
2.使用select完成单条件查询
Id:命名空间的唯一标识符,可以被用来引用这条语句
parameterType:表示查询语句传入参数的类型的完全限定名或别名
resultType:查询语句返回结果类型的完整类名或别名
参数传递:${参数名} 注意:数据库的字段名与pojo实体类的属性一致
3.使用select完成多条件查询
parameterType:基础数据类型:1)int String date等 2)只能传入一个参数,通过#{参数名}即可获取传入的值
复杂数据类型:1)Java实体类,map等 2)通过#{Map的key}即可获取传入的值
MyBatis入参:1)单参数入参:Java基础数据类型
2)多参数类型:Java实体类或者封装成Map
4.使用resultMap完成查询结果的展现
resultMap:对外部resultMap的引用,应用场景:1)数据库字段信息与对象属性不一致 2)复杂的联合查询,自由控制映射结果
resultMap元素的属性和子节点:Id属性:唯一标识,此Id值用于select元素resultMap属性的引用
type属性:表示该resultMap的映射结果类型
result子节点:标识一些简单属性,
column:表示从数据库中查询出来的字段名
property:表示查询出来的字段对应的值赋给实体类对象的哪个属性
resultType:表示返回类型,包括基础数据类型和复杂数据类型
resultMap和resultType的关联:二者不能同时存在,本质上都是Map数据类型
resultMap的自动映射级别:1)自动映射匹配前提是字段名与属性名一致
2)默认映射级别为partial:自动匹配所有属性
3)禁止自动匹配:将自动映射级别(autoMappingBehavior)为none
例子:
二:使用MyBatis实现增删改操作
1.使用insert完成添加语句
insert元素的属性:Id:1)命名空间中唯一的标识符 2)接口中的方法与映射文件中的SQL语句id一一对应
parameterType:传入SQL语句的参数类型
注意:insert、update、delete元素均没有resultType属性
2.使用update完成修改语句
update元素的属性:id:1)命名空间中唯一的标识符 2)接口中的方法与映射文件中的SQL语句id一一对应
parameterType:传入SQL语句的参数类型
3.使用注解@Param 来传入多个参数
例子:int updatePwd(@Param("id")Integer id,@Param("userPassword")String pwd);
注意:1)超过3个以上的参数最好封装成对象入参
2)参数固定的业务方法,最好使用多参数入参
4.使用delete完成删除语句
delete元素的属性:id:1)命名空间中唯一的标识符 2)接口中的方法与映射文件中的SQL语句id一一对应
parameterType:传入SQL语句的参数类型
三:使用resultMap实现高级结果映射
1.resultMap的元素属性:id:resultMap的唯一标识
type:Java实体类
resultMap子元素:id:一般对应数据库中该行的主键id,设置此项可提高MyBatis性能
result:映射到JavaBean的某个“简单类型”属性
2.association:映射到JavaBean的某个“复杂类型”属性,比如JavaBean类
复杂的类型关联,一对一
内部嵌套:映射一个嵌套JavaBean属性
association元素属性:property:映射数据库列的实体对象的属性
javaType:完整Java类名或者别名
resultMap:引用外部resultMap
association元素子元素属性:id
result:property:映射数据库列的实体对象的属性
column:数据库列名或者别名
associaition提供了另一个属性:resultMap
3.collection:作用和association元素作用一样
collection元素属性:property:映射数据库列的实体对象的属性
ofType:完整Java类名或者别名(集合所包括的类型)
resultMap:引用外部resultMap
collection:映射到JavaBean的某个“复杂类型”属性,比如集合
association元素子元素属性:id
result:property:映射数据库列的实体对象的属性
column:数据库列名或者别名
小结:resultMap自动映射(autoMappingBehavior)的三个匹配级别
NONE:禁止自动匹配
PARTIAL(默认):自动匹配所有属性,内部嵌套除外
FULL:自动匹配所有
四:resultMap自动映射级别和MyBatis缓存
1.MyBatis缓存:一级缓存
二级缓存
2.二级缓存的配置:MyBatis的全局cache配置
在Mapper XML文件中设置缓存,默认情况下是没有开启缓存的
在Mapper XML文件配置支持cache后,如果需要对个别查询进行调整,可以单独设置cache
第三章:动态SQL
一:使用动态SQL完成多条件查询
1.动态SQL元素属性:if:实现简单的条件选择
choose(when,otherwise):相当于Java中的switch语句,常与when和otherwise搭配
where:简化SQL语句中where的条件查询
set:解决动态更新语句
trim:可以灵活的去除多余的关键字
foreach:迭代一个集合,通常用于in条件
2.使用if+where实现多条件查询
例子:SELECT * FROM `smbms_user` u
and u.`userCode` LIKE CONCAT ('%',#{userCode},'%')
and u.`userName` LIKE CONCAT('%',#{userName},'%')
3.使用if+trim实现多条件查询
例子:
update smbms_user
userCode = #{userCode},
userCode = #{userName },
userPassword=#{userPassword },
trim的属性:prefix:前缀,作用是通过自动识别是否有返回值
suffix:后缀,作用是在trim包含的内容上加后缀
prefixOverrides:对于trim包含内容的首部进行指定内容的忽略
suffixOverrides:对于trim包含的首尾部进行指定内容的忽略
注意:使用if+trim替代if+set进行更新用户表数据,效果一样
三:使用foreach实现复杂查询
1.迭代一个集合,通常用于in条件
基本属性:item:表示集合中每一个元素进行迭代的别名
index:指定一个名称,表示在迭代过程中,每次迭代到的位置
open:表示该语句以什么开始
separator:表示每次进行迭代之间以什么符号作为分隔符
close:表示该语句以什么结束
collection:最关键并最容易出错的属性,改属性必须指定该属性值主要有三种情况
1)若入参为单参数且参数类型是list的时候,collection属性值为list
2)若入参为单参数且参数类型是一个数组的时候,collection属性值为array
3)若传入参数为多参数,就需把他封装成一个map进行处理
2.小结:MyBatis接收的参数类型:基本类型,对象,list,数组,Map
无论mybatis的入参是那种参数类型,MyBatis都会将参数放在一个Map中
1)若入参为基本类型:变量名作为key,变量值为value,此时生成map只有一个元素
2)若入参为对象:对象的属性名作为key,属性值为value
3)若入参为list:默认"list"为key,该List为value
4)若入参为数组:默认"array"为key,该数组为value
5)若入参为map:键值不变
3.choose(when,otherwise)
choose:相当于Java中switch语句,通常搭配when,otherwise使用
when:当其test属性中条件满足的时候,就会输出when元素中的内容
otherwise:当when中条件不满足的时候,就会输出otherwise元素中的内容
例子:
…
…
…
…
…
四:MyBatis实现分页功能
基本和servlet中实现分页差不多
第五章:Spring核心概念
一:初识Spring
1.轻量级框架, Java EE的春天,当前主流框架
2.目标:使现有技术更加易用,推进编码最佳实践
3.内容:IoC容器 AOP实现 数据访问支持(a.简化JDBC/ORM 框架 b.声明式事务) Web集成
4.Spring设计理念:Spring是面向Bean的编程
5.Spring 两大核心技术:a.控制反转(IoC:Inversion of Control ) /依赖注入(DI:Dependency Injection )
b.面向切面编程(AOP:Aspect Oriented Programming)
6.Spring的优点:1)低侵入式设计
2)独立于各种应用服务器
3)依赖注入特性将组件关系透明化,降低了耦合度
4)面向切面编程特性允许将通用任务进行集中式处理
5)与第三方框架的良好整合
二:SpringIoC:
1.控制反转也成为依赖注入,是面向编程中的一种设计理念,用来降低程序代码之间的耦合度
2.将组件对象的控制权从代码本身转移到外部容器
组件化的思想:分离关注点,使用接口,不再关注实现
依赖的注入:将组件的构建和使用分开
3.小结:1)设值注入
2)使用元素定义一个组件其属性
a.id属性:指定一个用来访问的唯一名称
b.name属性:指定多个别名,名字之间使用逗号、分号或空格进行分隔
三:面向切面编程(Spring AOP)
1.AOP的目标:让我们可以“专心做事”
2.AOP原理:1)将复杂的需求分解出不同方面,将散布在系统中的公共功能集中解决
2)采用代理机制组装起来运行,在不改变原程序的基础上对代码段进行增强处理,增加新的功能
3.所谓面向切面编程,是一种通过预编译和运行期动态代理的方式实现在不修改源代码的情况下给程序动态添加功能的技术
4.AOP相关基本概念
1)切面(Aspect):一个模块化的横切逻辑,可能会横切多个对象
2)连接点(Join Point):程序执行中的某个具体的执行点
3)增强处理(Advice):切面在某个特定连接点上执行的代码逻辑
4)切入点(Pointcut):对连接点的特征进行描述,可以使用正则表达式,增强处理和一个切入点表达式相关联,并在与这个切入点匹配的某个连接点上运行
5)目标对象(Target object):被一个或多个切面增强的对象
6)AOP代理(AOP proxy):由AOP框架所创建的对象,实现执行增强处理方法等功能
7)织入(Weaving):将增强处理连接到应用程序中的类型或对象上的过程
8)增强处理类型:前置增强 后置增强 环绕增强、异常抛出增强、最终增强等类型
5.使用Spring AOP实现日志输出
实现步骤:1)在项目中添加Spring AOP的jar文件
2)编写前置增强和后置增强实现日志功能
3)编写Spring配置文件,对业务方法进行增强处理
4)编写代码获取带有增强处理的业务对象
例子:目标方法: public class UserServiceImpl implements UserService {
//…省略代码
public void addNewUser(User user) {
dao.save(user);
}
}
增强处理: public class UserServiceLogger {
private static Logger log=Logger.getLogger(UserServiceLogger.class);
public void before(JoinPoint jp) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().
getName() + " 方法。方法入参:" + Arrays.toString(jp.getArgs()));
}
public void afterReturning(JoinPoint jp, Object result) {
log.info("调用 " + jp.getTarget() + " 的 " + jp.getSignature().
getName() + " 方法。方法返回值:" + result);
}
}
定义切入点:切入点:简单的说,就是连接点的查询条件
表达式匹配规则举例:public * addNewUser(entity.User): “*”表示匹配所有类型的返回值。
public void *(entity.User): “*”表示匹配所有方法名。
public void addNewUser(..): “..”表示匹配所有参数个数和类型。
* com.service.*.*(..):匹配com.service包下所有类的所有方法。
* com.service..*.*(..):匹配com.service包及其子包下所有类的所有方法
织入增强处理:织入:在切入点插入增强处理
第六章:IoC和AOP使用扩展
一:多种方式实现依赖注入
1.构造注入:创建带参构造方法(在service层的实现层里创建业务实现层的有参和无参方法。注意:无参方法无参数,有参方法的参数为dao层的接口名。例:userDao )
注意:编写带参构造方法后,Java虚拟机不再提供默认的无参构造方法,为了保证使用的灵活性,建议自行添加一个无参构造方法
分析:在Spring配置文件中通过元素为构造方法传参
例子:
注意:1)、一个元素表示构造方法的一个参数,且使用时不区分顺序。
2)、通过元素的index 属性可以指定该参数的位置索引,位置从0 开始。
3)、元素还提供了type 属性用来指定参数的类型,避免字符串和基本数据类型的混淆
2.构造注入和设值注入对比
构造注入:通过构造方法实现--时效性好--灵活性差,仅靠重载限制太多--通过匹配的构造方法实例化,但建议保留无参构造
设值注入:通过setter访问器实现--时效性差--灵活性好,但setter方法数量较多--通过无参构造实例化
3.使用p命名空间实现属性注入
p 命名空间的特点:使用属性而不是子元素的形式配置Bean的属性,从而简化了配置代码
语法:对于直接量(基本数据类型、字符串)属性:p:属性名="属性值"
对于引用Bean的属性:p:属性名-ref="Bean的id"
使用前要先要在Spring配置文件中引入p命名空间
例子:xmlns:p="http://www.springframework.org/schema/p"
使用p命名空间注入属性值
例子:
4.注入不同数据类型
注入直接量:1)使用标签实现 2)注意特殊字符的处理
引用Bean:1)使用标签实现 2)注意bean属性和 local 属性的区别
使用内部Bean:
注入集合类型的属性:分别使用、、
二:其他增强类型
1.异常抛出增强:1)特点:a.在目标方法抛出异常时织入增强处理
b.可拔插的异常处理方案
2)元素:定义异常抛出增强
3)
2.最终增强: 1)特点:a.无论方法是否抛出异常,都会在目标方法最后织入增强处理,即:该增强都会得到执行
b.类似于异常处理机制中finally块的作用,一般用于释放资源
c.可以为各功能模块提供统一的,可拔插的处理方案
2)元素:定义最终增强
3.环绕增强:1).特点:a.目标方法前后都可织入增强处理
b.功能最强大的增强处理
c.可获取或修改目标方法的参数、返回值,可对它进行异常处理,甚至可以决定目标方法是否执行
2)元素:定义环绕增强
4.小结《Spring AOP配置元素》
AOP配置元素 描 述
AOP配置的顶层元素,大多数的元素必须包含在元素内
定义切点
定义切面
定义最终增强(不管被通知的方法是否执行成功)
定义after-returning(后置)增强
定义after-throwing(异常)增强
定义环绕增强
定义前置增强
启动@AspectJ注解驱动的切面
三:使用注解实现IoC的配置
1.使用注解定义Bean:
注解方式将Bean的定义信息和Bean实现类结合在一起,Spring提供的注解有
a.@Component:实现Bean组件的定义
b.@Repository:用于标注DAO类
c.@Service:用于标注业务类
d.@Controller:用于标注控制器类
例子:@Repository("userDao")
public class UserDaoImpl implements UserDao {
…
}
2.使用注解实现Bean组件装配
使用@Autowired注解实现Bean的自动装配,默认按类型匹配,可以使用@Qualifier指定Bean的名称
例子:(1)@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired
@Qualifier("userDao")
private UserDao dao;
……
} //可以对类的成员变量进行标注
(2)@Service("userService")
public class UserServiceImpl implements UserService {
private UserDao dao;
@Autowired //也可以对方法的入参进行标注
public void setDao((@Qualifier("userDao") UserDao dao) {
this.dao = dao;
}
……
}
3.加载注解定义的Bean
例子:
4.使用Java标准注解完成装配
使用@Resource注解实现组件装配,默认按名称匹配
例子:(1)@Service("userService") //为dao属性注入名为userDao的Bean
public class UserServiceImpl implements UserService {
@Resource(name = "userDao")
private UserDao dao;
……
}
(2)@Service("userService") //查找名为dao的Bean,并注入给dao属性
public class UserServiceImpl implements UserService {
@Resource
private UserDao dao;
……
}
(3) //使用注解信息启动Spring容器
//指定需要扫描的基类包,多个包可用逗号隔开
(4) //使用@Resource注解实现组件装配,默认按名称匹配
@Service("userService")
public class UserServiceImpl implements UserService {
@Resource(name = "userDao") //为dao属性注入名为userDao的Bean
private UserDao dao;
……
}
@Service("userService")
public class UserServiceImpl implements UserService {
@Resource //查找名为dao的Bean,并注入给dao属性
private UserDao dao;
……
}
四:使用注解定义切面
1.AspectJ简介:
1)AspectJ:面向切面的框架,它扩展了Java语言,定义了AOP 语法,能够在编译期提供代码的织入
2)@AspectJ:AspectJ 5新增的功能,使用JDK 5.0 注解技术和正规的AspectJ切点表达式语言描述切面
3)Spring通过集成AspectJ实现了以注解的方式定义增强类,大大减少了配置文件中的工作量:
利用轻量级的字节码处理框架asm处理@AspectJ中所描述的方法参数名
注意:使用@AspectJ,首先要保证所用的JDK 是5.0或以上版本
2.使用注解标注切面
例子:/**
* 使用注解定义切面
*
* @author wzz
*
*/
@Aspect //定义切面
public class UserLogger {
private static final Logger log = Logger.getLogger(UserLogger.class);
// 定义切入点
@Pointcut("execution(* com.wzz.t6demo.service.impl.*.*(..))")
public void pointcut() {
}
// 注解前置增强
@Before("pointcut()")
public void before(JoinPoint jp) {
log.info("前置增强--调用" + jp.getTarget() + "的"
+ jp.getSignature().getName() + "方法。方法入参"
+ Arrays.toString(jp.getArgs()));
}
// 注解后置增强
@AfterReturning(pointcut = "pointcut()", returning = "returnValue")
public void afterReturning(JoinPoint jp, Object returnValue) {
log.info("后置增强--调用" + jp.getTarget() + "的"
+ jp.getSignature().getName() + "方法。方法返回值" + returnValue);
}
// 注解异常抛出增强
@AfterThrowing(pointcut = "execution(* com.wzz.t6demo.service.impl.*.*(..))", throwing = "e")
public void afterThrowing(JoinPoint jp, RuntimeException e) {
log.error("异常抛出增强--" + jp.getSignature().getName() + "方法发生异常:" + e);
}
// 注解环绕增强
@Around("execution(* com.wzz.t6demo.service.impl.*.*(..))")
public Object aroundLogger(ProceedingJoinPoint jp) throws Throwable {
log.info("环绕增强--调用" + jp.getTarget() + "的"
+ jp.getSignature().getName() + "方法。方法入参:"
+ Arrays.toString(jp.getArgs()));
try {
Object result = jp.proceed();
log.info("环绕增强--调用" + jp.getTarget() + "的"
+ jp.getSignature().getName() + "方法。方法返回值:" + result);// 执行目标方法并获得返回值
return result;
} catch (Throwable e) {
log.error(jp.getSignature().getName() + "方法发生异常:" + e);
e.printStackTrace();
} finally {
log.info(jp.getSignature().getName() + "方法结束执行");
}
return jp;
}
// 注解最终增强
@After("execution(* com.wzz.t6demo.service.impl.*.*(..))")
public void afterLogger(JoinPoint jp) {
log.info("最终增强--" + jp.getSignature().getName() + "方法结束执行");
}
3.Spring切面配置小结
1)使用注解方式定义切面可以简化配置工作量
2)常用注解有@Aspect、@Before、@AfterReturning、@Around、@AfterThrowing、@After等
3)在配置文件中添加 元素,启用对于@AspectJ注解的支持
经验:Spring在定义切面时提供了多种选择,应根据项目的具体情况做出选择:
1、如果项目采用JDK 5.0或以上版本,可以考虑使用@AspectJ注解方式,减少配置的工作量
2、如果不愿意使用注解或项目采用的JDK版本较低无法使用注解,则可以选择使用配合普通JavaBean的形式
第七章:MyBatis与Spring的整合
一.Spring对MyBatis的整合思路
1.要在Spring中使用MyBatis,需要在Spring的配置文件中定义一些类
2. SqlSessionFactoryBean:为整合应用提供SqlSession对象资源
3. SqlSessionTemplate:负责管理MyBatis的SqlSession,调用SQL映射语句,实现对数据库的访问
4. MapperFactoryBean:根据指定Mapper接口生成Bean实例
5. MapperScannerConfigurer:根据指定包批量扫描Mapper接口并生成实例
二.Spring整合MyBatis的准备工作
1.大致步骤:a.在项目中加入Spring,MyBatis及整合相关的jar文件
b.建立开发目录,创建实体类
c.创建数据访问接口
d.配置SQL映射文件
e.配置mybatis配置文件
三:实现Spring对MyBatis的整合
1.配置数据源:目前流行的数据源实现有dbcp,c3p0,Proxool等,本章采用dbcp方式配置
例子:
2.配置SqlSessionFactoryBean(通过配置SqlSessionFactoryBean获得SqlSessionFactory实例)
例子:
classpath:com/wzz/t7demo/**/*.xml
3.配置SqlSessionTemplate实现数据库的操作
例子:
4.编写业务逻辑代码并测试
例子:Logger logger = Logger.getLogger(UserTest.class.getName());
ApplicationContext context = new ClassPathXmlApplicationContext(
"applicationContext.xml");
UserService service = (UserService) context.getBean("userService");
List list = service.findUsersWithConditions();
for (User user2 : list) {
logger.debug("用户账号:" + user2.getUserCode() +"------"+"用户姓名:"
+ user2.getUserName());
}
5.使用MapperFactoryBean注入映射器
1)根据Mapper接口获取Mapper对象,它封装了原有的SqlSession.getMapper()功能的实现
2)映射器对应的SQL映射文件与映射器的类路径相同,该映射文件可以自动被MapperFactoryBean解析
例子://省略数据源配置
//配置SQLSessionFactoryBean
//配置DAO
//注入接口时 使用 value
//注入sqlSessionFactory ref>bean
//省略业务Bean配置
6.使用MapperScannerConfigurer注入映射器
MapperScannerConfigurer:自动扫描指定包下的Mapper接口,并将它们直接注册为MapperFactoryBean
例子://省略数据源配置
//配置SQLSessionFactoryBean
//配置DAO
//MapperScannerConfigurer递归扫描基准包下所有接口,若它们在SQL映射文件中定义过,
则动态注册为MapperFactoryBean,如此即可批量产生映射器实现类
7.小结
1)MapperScannerConfigurer 与@Autowired注解或@Resource注解配合使用,自动创建映射器实现并注入给业务组件,
能够最大限度地减少DAO组件与业务组件的编码和配置工作
例子:@Service("userService")
public class UserServiceImpl implements UserService {
@Autowired // 或 @Resource
private UserMapper userMapper;
//……代码省略
}
四:applicationcontext.xml文件
例子:
classpath:com/zl/t7/**/*.xml
五:为业务层添加声明式事务
1.配置声明式事务:1)声明式事务关注的核心问题是:对哪些方法,采取什么样的事务策略
2)配置步骤:a.导入tx和aop命名空间
b.定义事务管理器Bean,并为其注入数据源Bean
c.通过配置事务增强,绑定事务管理器并针对不同方法定义事务规则
d.配置切面,将事务增强与方法切入点组合
2.事务属性:1)propagation:事务传播机制:
REQUIRED(默认值)
REQUIRES_NEW 、MANDATORY、NESTED
SUPPORTS
NOT_SUPPORTED、NEVER
2)isolation:事务隔离等级
DEFAULT(默认值)
READ_COMMITTED
READ_UNCOMMITTED
REPEATABLE_READ
SERIALIZABLE
3。1)timeout:事务超时时间,允许事务运行的最长时间,以秒为单位。默认值为-1,表示不超时
2)read-only:事务是否为只读,默认值为false
3)rollback-for:设定能够触发回滚的异常类型
4)Spring默认只在抛出runtime exception时才标识事务回滚
5)可以通过全限定类名指定需要回滚事务的异常,多个类名用逗号隔开
6)no-rollback-for:设定不触发回滚的异常类型
7)Spring默认checked Exception不会触发事务回滚
可以通过全限定类名指定不需回滚事务的异常,多个类名用英文逗号隔开
4.使用注解实现事务处理
1)在Spring配置文件中配置事务管理类,并添加对注解配置的事务的支持
例子:
2)使用@Transactional为方法添加事务支持
例子: @Transactional
@Service("userService")
public class UserServiceImpl implements UserService {
……
@Transactional(propagation = Propagation.SUPPORTS)
public List findUsersWithConditions(User user) {
// 省略实现代码
}
}
5.@Transactional注解的属性
属性 类型 说明
propagation 枚举型:Propagation 可选的传播性设置。使用举例:@Transactional(propagation=Propagation.REQUIRES_NEW)
isolation 枚举型:Isolation 可选的隔离性级别。使用举例:@Transactional(isolation=Isolation.READ_COMMITTED)
readOnly 布尔型 是否为只读型事务。使用举例:@Transactional(readOnly=true)
timeout int型(以秒为单位) 事务超时。使用举例:Transactional(timeout=10)
第八章:Spring配置补充
一.灵活配置DataSource
1。使用属性文件配置数据源:a.数据库连接信息写在属性文件中
b.采用PropertyPlaceholderConfigurer可以引入属性文件,在Spring配置文件中采用诸如${url}的方式引用属性值
例子:
classpath:database.properties
注意:${……}的前后不要键入空格,以免报错!
2。使用JNDI数据源:通过JNDI从服务器容器中获取DataSource资源
a.在服务器环境中配置数据源
b.在Spring配置文件引用JNDI资源
例子:
java:comp/env/jdbc/smbms
二:Spring中Bean的作用域问题
1.Bean的作用域
作用域 说 明
singleton 默认值。Spring以单例模式创建Bean的实例,即容器中该Bean的实例只有一个
prototype 每次从容器中获取Bean时,都会创建一个新的实例
request 用于Web应用环境,针对每次HTTP请求都会创建一个实例
session 用于Web应用环境,同一个会话共享同一个实例,不同的会话使用不同的实例
global session 仅在Portlet的Web应用中使用,同一个全局会话共享一个实例。对于非Portlet环境,等同于session
例子:
……
2.singleton与prototype区别:
例子:
例子二:
3.使用注解指定Bean的作用域
使用@Scope注解指定Bean的作用域
例子:@Scope("prototype")
@Service("userService")
public class UserServiceImpl implements UserService {
// 省略其他代码
}
三:Spring自动装配
1.什么是自动装配:Spring可以根据属性类型、名称等自动进行注入
例子:
2.如何使用自动装配:设置元素的autowire属性
例子:
3.Spring提供的4种自动装配类型
取值 说明
no 默认值。Spring 默认不进行自动装配,必须显式指定依赖对象
byName 根据属性名自动装配。Spring 自动查找与属性名相同的id,如果找到,则自动注入,否则什么都不做
byType 根据属性的类型自动装配。Spring 自动查找与属性类型相同的Bean,如果刚好找到唯一的那个,则自动注入;
如果找到多个与属性类型相同的Bean,则抛出异常;如果没找到,就什么也不做
constructor 和byType 类似,不过它针对构造方法。如果 Spring 找到一个Bean和构造方法的参数类型相匹配,则通过构造注入
该依赖对象;如果找不到,将抛出异常
4.注意:自动装配使得配置文件可以非常简洁,但同时也造成组件之间的依赖关系不明确,容易引发一些潜在的错误,在实际项目中要谨慎使用
四:拆分Spring配置文件
1、为什么需要拆分配置文件:
1)项目规模变大,配置文件可读性、可维护性差
2)团队开发时,多人修改同一配置文件,易发生冲突
2、拆分策略
1)公用配置+每个系统模块一个单独配置文件(包含DAO、Service、Web控制器)
2)公用配置+DAO Bean配置+业务逻辑Bean配置+Web控制器配置
3)两种策略各有特色,适用于不同场合
3、引入拆分后的配置文件
两种方法:1)利用ClassPathXmlApplicationContext 的重载方法可以配置多个配置文件,用逗号隔开或者使用通配符
例子:public ClassPathXmlApplicationContext( String configLocation );
public ClassPathXmlApplicationContext( String… configLocations );
注意:以String[ ]方式传入多个配置文件名
2)使用 方式
例子:
第九章:Spring MVC体系结构和处理请求控制器
一:MVC设计模式
1.视图(View)-对应组件:JSP或者HTML文件
控制器(Controller)-对应组件:Servlet
模型(Model) -对应组件:JavaBean
2.JSP Model2:a.JSP:负责生成动态网页
b.Servlet:负责流程控制
c.JavaBean:负责业务逻辑处理
3.MVC 优点
1)多视图共享一个模型,大大提高代码的可重用性
2)MVC三个模块相互独立,松耦合架构
3)控制器提高了应用程序的灵活性和可配置性
4)有利于软件工程化管理
注意:完美的系统架构 = 松耦合+高重用性+高扩展性
4.MVC 缺点
1)原理复杂
2)增加了系统结构和实现的复杂性
3)视图对模型数据的低效率访问
二:Spring MVC介绍及其环境搭建
1.Spring MVC 环境搭建
导入所需jar包 (spring-web-3.2.13.RELEASE.jar, spring-webmvc-3.2.13.RELEASE.jar)
1.web.xml中配置Servlet
springmvc
springmvc
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
springmvc
/
2.创建Spring MVC配置文件(springmvc-servlet.xml)
方式一:手动配置
缺点:需要每次手动创建bean的 /index 增加了代码的重复性,故改进为注解@RequestMapping等同于
方式二:借助注解和扫描包进行配置
3.定义Controller类 处理请求的控制器
方式一:
3-1.继承与AbstractController extends AbstractController
3-2. @Override
protected ModelAndView handleRequestInternal(HttpServletRequest arg0,
HttpServletResponse arg1) throws Exception {
//在控制台输出信息验证是否执行
System.out.println("hello SpringMVC!");
return new ModelAndView("index");
}
缺点:每个类的只能继承与一个父类,具有一定的局限性所以替换为注解@Controller等同于extends AbstractController
方式二:
3-1. @Controller 注解标注该类为控制器
3-2. @RequestMapping("/index") 注解标注该类中的某个方法的对应HTTP请求URL
@RequestMapping({"/index","/"}) 定义多种访问方式
. @RequestMapping(value="index" method=RequestMethod.GET)
其中method定义请求类型
public ModelAndView index(){
System.out.println("hello,SpringMVC!"); MV.addObject("userName", userName);
MV.setViewName("index");
return MV;
}
@RequestParam 注解标注要传的参数
4.部署运行
部署TomCat @RequestMapping("/index")为所定义的url的末尾地址
http: //localhost:8080/test3/index
参数的传递
从Controller 到页面
方式一:使用ModelAndView 的属性
public ModelAndView index(){
ModelAndView MV=new ModelAndView();
MV.addObject("userName",” userName”);
MV.setViewName("index");
return MV;
}
*可以同时传入参数和视图名
其中.addObject(String attributeName,object attributeValue)对于单个数据的传入
.addAllObjects(Map modelMap) 对于多个参数传入
.setViewName(String viewName)指定一个逻辑视图名
.setView(View view) 指定一个具体的视图对象
方式二:使用Model接口
public String index(Model model){
System.out.println("hello,SpringMVC!");
model.addAttribute(String key, Object Value);
model.addAttribute("userName", ” userName”);
return ”index”;
}
方式三:使用Map集合
public String index(Map map){
System.out.println("hello,SpringMVC!");
map.put(String key, Object Value);
map.put("userName", ” userName”);
return ”index”;
}
方式四:@ModelAttibute
方式五:@SessionAttibutes
从页面到Controller
方式一: 使用@ResquestMapping中的属性params传参
@RequestMapping(value="/second",method=RequestMethod.GET, params="userName")
public String second(@RequestParam String userName) {
System.out.println(userName);
return "index";
}
url请求的路径http://localhost:8080/test3/second?userName=admin
方式二:使用@RequestParam注解实现
@RequestMapping("/index")
value:参数名
required: 默认为true 请求中必须包含对应的参数名,若不存在就抛出异常,
false请求中不必包含对应的参数名,但会返回空(null)
public String second(@RequestParam(value=”userName”,required=false) String userName) {
System.out.println(userName);
return "index";
}
三:String MVC
1.SpringMVC的优势:Spring框架提供了构建Web应用程序的全功能MVC模块——Spring MVC。Spring MVC框架提供了一个DispatcherServlet作用前端控制器来
分派请求,同时提供灵活的配置处理程序映射、视图解析、语言环境和主题解析,并支持文件上传。Spring MVC还包含了多种视图技术,例如JSP、Velocity、
Tiles、iText和POI等。Spring MVC分离了控制器、模型对象、分派器以及处理程序对象的角色,这种分离让它们更容易进行定制。
2.Spring MVC的特点:
(1)Spring MVC拥有强大的灵活性、非入侵性和可配置性。
(2)Spring MVC 提供了一个前端控制器DispatcherServlet,开发者无须额外开发控制器对象。
(3)Spring MVC分工明确,包含控制器、验证器、命令对象、模型对象、处理程序映射视图解析器,等等,每一个功能实现由一个专门的对象负责完成。
(4)Spring MVC可以自动绑定用户输入,并正确地转换数据类型。例如:Spring MVC能自动解析字符串,并将其设置为模型的int或float类型的属性。
(5)Spring MVC使用一个名称/值的Map对象实现更加灵活的模型数据传输。
(6)Spring MVC内置了常见的校验器,可以校验用户输入,如果校验不通过,则重定向回输入表单。输入校验是可选的,并且支持编程方式及声明方式。
(7)Spring MVC支持国际化,支持根据用户区域显示多国语言,并且国际化的配置非常简单。
(8)Spring MVC支持多种视图技术,最常见的有JSP技术以及其他技术,包括Velocity和FreeMarker。
(9)Spring 提供了一个简单而强大的JSP标签库,支持数据绑定功能,使得编写JSP页面更加容易。
3.Spring MVC 执行流程
第一步:用户发送请求到前端控制器(DispatcherServlet)。
第二步:前端控制器请求 HandlerMapping 查找 Handler,可以根据 xml 配置、注解进行查找。
第三步: 处理器映射器 HandlerMapping 向前端控制器返回 Handler
第四步:前端控制器调用处理器适配器去执行 Handler
第五步:处理器适配器执行 Handler
第六步:Handler 执行完成后给适配器返回 ModelAndView
第七步:处理器适配器向前端控制器返回 ModelAndView:ModelAndView 是SpringMVC 框架的一个底层对象,包括 Model 和 View
第八步:前端控制器请求试图解析器去进行视图解析:根据逻辑视图名来解析真正的视图。
第九步:试图解析器向前端控制器返回 view
第十步:前端控制器进行视图渲染:就是将模型数据(在 ModelAndView 对象中)填充到 request 域
第十一步:前端控制器向用户响应结果
4.SpringMVC常用注解
1)@Controller:负责注册一个bean 到spring 上下文中
2)@RequestMapping:注解为控制器指定可以处理哪些 URL 请求
3)@RequestBody:该注解用于读取Request请求的body部分数据,使用系统默认配置的HttpMessageConverter进行解析,然后把相应的数据绑定到要返回的对象上,
再把HttpMessageConverter返回的对象数据绑定到 controller中方法的参数上
4)@ResponseBody:该注解用于将Controller的方法返回的对象,通过适当的HttpMessageConverter转换为指定格式后,写入到Response对象的body数据区
5)@ModelAttribute:在方法定义上使用 @ModelAttribute 注解:Spring MVC 在调用目标处理方法前,会先逐个调用在方法级上标注了@ModelAttribute 的方法
在方法的入参前使用 @ModelAttribute 注解:可以从隐含对象中获取隐含的模型数据中获取对象,再将请求参数 –绑定到对象中,再传入入参将方法入参对象添加到模型中
6)@RequestParam :在处理方法入参处使用 @RequestParam 可以把请求参 数传递给请求方法
7)@PathVariable:绑定 URL 占位符到入参
8)@ExceptionHandler:注解到方法上,出现异常时会执行该方法
9)@ControllerAdvice:使一个Contoller成为全局的异常处理类,类中用@ExceptionHandler方法注解的方法可以处理所有Controller发生的异常
第十章:使用Spring MVC框架改造超市订单系统-1
一:单例模式
1.单例模式:系统运行期间,有且仅有一个实例
1)一个类只有一个实例——最基本的:只提供私有构造器
2)它必须自行创建这个实例:定义了静态的该类私有对象
3)它必须自行向整个系统提供这个实例:提供一个静态的公有方法,返回创建或者获取本身的静态私有对象
2.懒汉模式:在类加载时不创建实例,采用延迟加载的方式,在运行调用时创建实例
特点:1)线程不安全 2)延迟加载
解决线程安全的方法:同步(synchronized)
3.饿汉模式:在类加载时,就完成初始化
特点:1)线程安全 2)不具备延迟加载特性
4.饿汉模式和懒汉模式关键代码
/**
* 读取配置文件的工具类---单例模式
*
* @author wzz
*
*/
public class ConfigManager {
// 使用饿汉模式 得先new出来
private static ConfigManager configManager = new ConfigManager();
private static Properties properties;
// 私有构造器---读取数据库配置文件
private ConfigManager() {
String configfile = "database.properties";
properties = new Properties();
InputStream is = ConfigManager.class.getClassLoader()
.getResourceAsStream(configfile);
try {
properties.load(is);
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
// 懒汉模式 synchronized 同步锁用于保证线程安全
// public static synchronized ConfigManager getInstance(){
// if (configManager == null) {
// configManager = new ConfigManager();
// }
// return configManager;
// }
// 饿汉模式
public static ConfigManager getInstance() {
return configManager;
}
public String getValue(String key) {
return properties.getProperty(key);
}
}
5.小结:
注意: 在整个程序运行期间,有且仅有一个实例。若违背这一点,所设计的类就不是单例类
单例模式 懒汉模式 饿汉模式
概念 在类加载时不创建实例,采用延迟加载的方式, 在类加载的时候,就完成初始化
在运行调用时创建实例
特点 类加载速度快,但是运行时获取对象的速度较慢。 类加载较慢,但获取对象速度快。——“空间换时间”
——“时间换空间”
延迟加载 具备 不具备(静态内部类)
线程安全 线程不安全(同步:synchronized) 线程安全
6.单例模式的例子(BaseDao)
/**
* 操作数据库的基类---静态类
*
* @author wzz
*
*/
public class BaseDao {
protected Connection connection;
protected PreparedStatement pstm;
protected ResultSet rs;
public void getConnection() {
ConfigManager cm = ConfigManager.getInstance();
String driver = cm.getValue("driver");
String url = cm.getValue("url");
String user = cm.getValue("user");
String password = cm.getValue("password");
System.out.println(driver);
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, user, password);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
/**
* 查询操作
*
* @param connection
* @param pstm
* @param rs
* @param sql
* @param params
* @return
*/
public ResultSet executeQuery(String sql, Object[] params) throws Exception {
getConnection();
pstm = connection.prepareStatement(sql);
if (params!=null) {
for (int i = 0; i < params.length; i++) {
pstm.setObject(i + 1, params[i]);
}
}
rs = pstm.executeQuery();
return rs;
}
/**
* 更新操作
*
* @param connection
* @param pstm
* @param sql
* @param params
* @return
* @throws Exception
*/
public int execute(String sql, Object[] params) throws Exception {
getConnection();
int updateRows = 0;
pstm = connection.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
pstm.setObject(i + 1, params[i]);
}
updateRows = pstm.executeUpdate();
return updateRows;
}
/**
* 释放资源
*
* @param connection
* @param pstm
* @param rs
* @return
*/
public boolean closeResource(Connection connection, PreparedStatement pstm,
ResultSet rs) {
boolean flag = true;
if (rs != null) {
try {
rs.close();
rs = null;// GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if (pstm != null) {
try {
pstm.close();
pstm = null;// GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if (connection != null) {
try {
connection.close();
connection = null;// GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
return flag;
}
}
二:Spring MVC-Controller的单例管理
1.Spring MVC—Controller:1)默认scope为singleton 2)速度和性能优越
注意:1)Controller是单例的,其内部的成员变量都是公用的,开发时需要注意资源使用的问题
2)一般情况下,Controller内的成员变量就只有service对象
2.当输入查询条件时,如输入中文,会出现乱码,解决方案如下:
在web.xml中增加Spring字符编码过滤器;关键代码如下:
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
三:搭建Spring MVC+Spring+JDBC框架
1.加入Spring,Spring MVC,数据库驱动等相关的jar文件
2.Spring配置文件:
3.配置web.xml
log4jConfigLocation
classpath:log4j.properties
webAppRootKey
T10Demo1.root
org.springframework.web.util.Log4jConfigListener
4.UserController例子;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.wzz.T10demo.pojo.User;
import com.wzz.T10demo.servcice.UserService;
import com.wzz.T10demo.util.ConfigManagerDemo;
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService service;
@RequestMapping(value = "/index", method = RequestMethod.GET)
public String index() {
System.out.println(ConfigManagerDemo.getConfigManagerDemo());
try {
List userList = service.getUserlist();
for (User user : userList) {
System.out.println(user.getUserName());
}
} catch (Exception e) {
e.printStackTrace();
}
return "index";
}
}
5.异常的处理:1)对所有异常进行统一处理
2)配置SimpleMappingExceptionResolver:发生异常时使用对应的视图报告异常
例子:
error
第十一章:使用Spring MVC框架改造超市订单系统-2
一:文件上传
1.Spring MVC—文件上传:
1)MultipartResolver接口:用于处理上传请求,将上传请求包装成可以直接获取文件的数据,方便操作
2)两个实现类:a.StandardServletMultipartResolver:使用了Servlet3.0标准的上传方式
b.CommonsMultipartResolver:使用了Apache的commons-fileupload来完成具体的上传操作
2.实现步骤:1)导入jar文件
2)配置MultipartResolver:
配置MultipartResolver(springmvc-servlet.xml):使用CommonsMultipartResolver配置一个MultipartResolver解析器
例子:
//maxUploadSize:设置上传文件大小上限,单位为字节
//defaultEncoding:设置请求的编码格式,默认为ISO-8859-1,此处设置为UTF-8
3)编写文件上传表单页:
注意:a.method="POST" b.enctype="multipart/form-data":指定表单内容类型,支持文件上传
b.:用来上传文件的file组件
例子:
4)编写控制器
MultipartFile:Spring MVC会将上传文件绑定到MultipartFile对象中,并通过该对象完成文件的上传操作
注意:1.File.separator:a.Windows、Linux自适应路径分隔符 b.低入侵性的代码实现
2.必须对上传文件进行重命名原因:1)原文件名存在中文---------->乱码问题
2)原文件名与服务器上已有文件重名---------->覆盖问题
3)重新定义上传文件名(保证不重名):当前系统时间+随机数+“_Personal.jpg”
例子:/**
* 单文件上传
* @author wzz
*/
@Controller
@RequestMapping("/user")
public class FileUploadcontroller {
@RequestMapping(value = "/upload", method = RequestMethod.POST)
public String Fileupload(HttpSession session, HttpServletRequest request,
@RequestParam(value = "file") MultipartFile file) {
// 判断文件是否为空
if (!file.isEmpty()) {
// 准备保存文件目录
String path = request.getSession().getServletContext()
.getRealPath("statics" + File.separator + "uploadfiles");
// 获取文件原名称
String oldfileName = file.getOriginalFilename();
System.out.println("=============" + "文件原名称:" + oldfileName);
// 获取原文件后缀
String prefix = FilenameUtils.getExtension(oldfileName);
System.out.println("=============" + "原文件后缀:" + prefix);
// 获取原文件的类型
String fileType = file.getContentType();
System.out.println("=============" + "原文件的类型:" + fileType);
// 固定上传文件的大小
int filesize = 500000;
System.out.println("=============" + "上传文件的大小:" + file.getSize());
// 生成新文件名称(原文件名会重名 重名文件覆盖)
SimpleDateFormat dateFormat = new SimpleDateFormat(
"yyyyMMddHHmmssSSS");
Random random = new Random();
String newfileName = dateFormat
.format(random.nextInt(9999 - 1000) + 1000);
System.out.println("=============" + "新文件名称:" + newfileName);
// 开始上传文件
File fileName = new File(path, newfileName + "." + prefix);
System.out.println("=============" + "新文件名称:" + fileName);
// 检测path路径是否可用
if (!fileName.exists()) {
// 创建新目录
fileName.mkdirs();
}
try {
file.transferTo(fileName);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
return "/index";
}
}
/**
* 多文件上传
* @author wzz
*/
@Controller
@RequestMapping("/upload")
public class FileUploadController {
/**
* 文件上传
* 1.表单:enctype="multipart/form-data"
* 2.接收:POST
* MultipartFile :接收文件的接口
*
* @param request 用于获取session(用于产生文件上传保存文件的目录)
* @param multipartFile
* @return
*/
@RequestMapping(value = "/fileUpload", method = RequestMethod.POST)
public String fileUpload(HttpServletRequest request,
@RequestParam(value = "multipartFile") MultipartFile[] multipartFile) {
for (int i = 0; i < multipartFile.length; i++) {
// 1.判断页面是否提交了文件
if (!multipartFile[i].isEmpty()) {
// 2.准备保存文件的目录
String path = request.getSession().getServletContext()
.getRealPath("static" + File.separator + "upload");
System.out.println("==================" + path
+ "====================");
// 获取页面上传文件的信息
// 获取文件原名称
String orFileName = multipartFile[i].getOriginalFilename();
System.out.println("==============" + orFileName
+ "==================");
// 获取文件的后缀名 FilenameUtils.getExtension(原文件名);
String extFileName = FilenameUtils.getExtension(orFileName);
System.out.println("==============" + extFileName
+ "==================");
// 文件类型
String fileType = multipartFile[i].getContentType();
System.out.println("==============" + fileType
+ "==================");
// 文件的大小
long fileSize = multipartFile[i].getSize();
System.out.println("==============" + fileSize
+ "==================");
//===========生成文件名称(原文件名会重名 重名文件覆盖)=================
SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmssSSS");
Random random = new Random();
String newFileName = format.format(new Date()) + (random.nextInt(9999 - 1000) + 1000);
//===========生成文件名称(原文件名会重名 重名文件覆盖)=================
// 开始文件上传
// 1.检测路径是否可用的 2.准备文件新的名称
// 准备新的文件名称(为了避免文件覆盖)
File file = new File(path, newFileName +"."+ extFileName);
//检测path 路径是否为可用的
if (!file.exists()) {
//创建目录
file.mkdirs();
}
try {
// 文件上传
multipartFile[i].transferTo(file);
} catch (IllegalStateException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return "/index";
}
}
二:Spring表单标签
1.1)Spring提供的轻量级标签库 2)可在JSP页面中渲染HTML元素的标签
2.用法:1)必须在JSP页面的开头处声明taglib指令
2)引入标签声明之后就可使用Spring表单标签
例子:<%@ taglib prefix="fm"
uri="http://www.springframework.org/tags/form" %>
3.Spring常用表单标签
名 称 说 明
渲染表单元素
输入框组件标签
密码框组件标签
隐藏框组件标签
多行输入框组件标签
单选框组件标签
复选框组件标签
下拉列表组件标签
显示表单数据校验所对应的错误信息
4.fm:form标签:
modelAttribute:1)指定绑定的模型属性,默认为command 2)建议指定
action:1)指定表单提交的目标URL 2)可不指定,则自动提交到获取表单页面的URL
method:1)GET 2)POST
5.fm:input/标签
属 性 描 述
path 属性路径,表示表单对象属性,如userName、userCode等
cssClass 表单组件对应的CSS样式类名
cssErrorClass 当提交表单后报错(服务端错误),采用的CSS样式类
cssStyle 表单组件对应的CSS样式
htmlEscape 绑定的表单属性值是否要对HTML特殊字符进行转换,默认为true
注意:表单组件标签也拥有HTML标签的各种属性,比如:id、onclick等等,都可以根据需要,灵活使用
三:数据校验
1.服务器端的数据校验:1)利用Spring自带的验证框架 2)利用JSR 303实现
2.JSR 303:1)Java为Bean数据合法性校验所提供的标准框架
2)Spring MVC支持JSR 303标准的校验框架
3)JSR 303通过在Bean属性上标注校验注解指定校验规则,并通过标准的验证接口对Bean进行验证
4)http://jcp.org/en/jsr/detail?id=303
注意:1)Spring本身没有提供JSR 303的实现
2)实现者:Hibernate Validator
http://hibernate.org/validator
3.JSR 303 约束
约 束 说 明
@Null 被注释的元素必须为null
@NotNull 被注释的元素必须不为null
@AssertTrue 被注释的元素必须为 true
@AssertFalse 被注释的元素必须为 false
@Min(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@Max(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@DecimalMin(value) 被注释的元素必须是一个数字,其值必须大于等于指定的最小值
@DecimalMax(value) 被注释的元素必须是一个数字,其值必须小于等于指定的最大值
@Size(max, min) 被注释的元素的大小必须在指定的范围内
@Digits (integer, fraction) 被注释的元素必须是一个数字,其值必须在可接受的范围内
@Past 被注释的元素必须是一个过去的日期
@Future 被注释的元素必须是一个将来的日期
四:REST风格
1.Representational State Transfer,表述性状态转移,是一种软件架构风格
例子: @RequestMapping(value="/view/{id}",
method=RequestMethod.GET)
public String view(@PathVariable String id,Model model){
//......中间代码省略
}
"/view/{id}":URL中的{xxx}占位符参数
@PathVariable:接收REST风格URL中的参数
第十二章:Spring MVC扩展和SSM框架整合
一:JSON对象的处理
@ResponseBody:作用:将标注该注解的处理方法的返回结果直接写入HTTP Response Body中,一般会在异步获取数据时使用
例子:// produces={"application/json;charset=UTF-8"} 处理JSON中 中文乱码
@RequestMapping(value = “/getUserList”, method = RequestMethod.GET)
@ResponseBody
// 该方法返回JSON
public String getUserList() {
List userList = null;
try {
userList = userService.getUserList();
} catch (Exception e) {
e.printStackTrace();
}
return JSON.toJSONString(userList);
}
2.JSON数据的传递处理
1)解决JSON数据传递的中文乱码问题:
解决方案一:
@RequestMapping(value="/view",
method=RequestMethod.GET,
produces={"application/json;charset=UTF-8"})
/view:请求报文头的Accept 须与响应报文头中的Content-Type 类型一致,即:application/json
produces={"application/json;charset=UTF-8"}:指定返回的内容类型为json格式数据,并且字符串的转换编码为 “UTF-8”
优点:简单实用,并可做到灵活处理
解决方案二:
装配消息转换器StringHttpMessageConverter,设置字符编码为UTF-8
supportedMediaTypes属性:1)指定媒体类型:application/json 2)字符编码:UTF-8
优点:一次配置,永久搞定
2)解决JSON数据传递的日期格式问题
日期格式:时间戳 “yyyy-MM-dd”
解决方案一:
注解方式:@JSONField(format= "yyyy-MM-dd")
缺点:该解决方案的代码具有强侵入性,紧耦合,并且修改麻烦,所以在实际开发,不建议采用这种硬编码的方式来处理
解决方案二:
配置FastJson的消息转换器-FastJsonHttpMessageConverter:
设置features属性:指定输出时的日期转换器为WriteDateUseDateFormat
注意:FastJson规定了默认的返回日期类型DEFFAULT_DATE_FORMAT:yyyy-MM-dd HH:mm:ss故对于特殊类型字段,可使用@JSONField来控制
3)小结
对于JSON数据中的日期格式处理(FastJson):
1)默认输出时间戳
2)转换输出yyyy-MM-dd HH:mm:ss格式的日期:配置消息转换器中的 WriteDateUseDateFormat
3)注解优先( yyyy-MM-dd ):a.配置消息转换器中的WriteDateUseDateFormat
b. 增加属性注解@JSONField(format="yyyy-MM-dd")
3.配置多视图解析器(ContentNegotiatingViewResolver)
在Spring-servlet.xml中多视图解析器的配置:
1)根据请求所要求的MIME类型决定视图解析器
2)同样的内容数据可以通过不同的view来进行前台的数据展现
例子:/user/view.json?id=12
/user/view.html?id=12
/user/view.xml?id=12
3)关于配置多视图解析器的相关属性配置
a.favorParameter(有利参数):默认为true,表示支持参数匹配,可以根据请求参数的值确定MIME类型,默认的请求参数为format,如: /user/view?id=12&format=json
b.mediaTypes(中间型):根据请求参数值和MIME类型的映射列表
例子:
c.viewResolvers:表示网页视图解析器
二:数据转换和格式化
1.1)DataBinder(数据库):1)数据绑定的核心部件 2)核心调度
2).ConversionService(转换服务):1)Spring类型转换体系的核心接口
2)解决前台form表单中时间字符串到后台Date数据类型的转换问题
3)配置了 标签,并没有配置ConversionService,也能通过格式化注解来解决日期的转换问题
标签:
DefaultAnnotationHandlerMapping
AnnotationMethodHandlerAdapter
FormattingConversionServiceFactoryBean
3).BindingResult(绑定结果):包含已完成数据绑定的入参队象和相应的校验错误对象
2.编写自定义转换器
Converter转换接口:作用:将一种类型转换成另一种类型的对象
方法:convert()
实现步骤:1)自定义转换器(StringToDateConverter.java):
实现convert()方法:完成字符串到java.util.Date类型指定格式的转换
2)装配自定义的ConversionService
三:SSM框架整合步骤
1.新建web项目并导入相关的jar包(27个jar包)
2.配置web.xml:相关代码如下
WEB-INF/jsp/login.jsp
contextConfigLocation
classpath:applicationContext-*.xml
encodingFilter
org.springframework.web.filter.CharacterEncodingFilter
encoding
UTF-8
forceEncoding
true
encodingFilter
/*
spring
org.springframework.web.servlet.DispatcherServlet
contextConfigLocation
classpath:springmvc-servlet.xml
1
spring
/
org.springframework.web.context.ContextLoaderListener
log4jConfigLocation
classpath:log4j.properties
webAppRootKey
T12Demo2_SSM.root
org.springframework.web.util.Log4jConfigListener
3.配置文件(/resources)
1)applicationContext-Mybatist.xml:a.数据源相关配置
b.配置mybitas SqlSessionFactoryBean
c.组装SqlSessionFactoryBean与DAO层
d.创建事物控制器
e.注解式事物
具体代码:
2)springmvc-servlet.xml:a.开启扫描 启用注解
b. 配置字符编码集
c.静态资源映射
d.配置多视图解析器:允许同样的内容数据呈现不同的view
e.配置MultipartResolver,用于上传文件,使用spring的CommonsMultipartResolver
f.配置拦截器-interceptors
具体代码:
application/json;charset=UTF-8
text/html;charset=UTF-8
application/json
WriteDateUseDateFormat
3)导入database.properties的配置
4)导入log4j.properties的配置
5)导入mybatis-config.xml:a.配置typeAliases b.设置全局性懒加载
相关代码如下
4.数据对象模型(cn.smbms.pojo):所有的数据对象模型都放在这个包下
5.DAO数据访问接口(cn.smbms.dao):所有数据操作都放在此包下
6.系统服务接口(cn.smbms.service):负责业务逻辑处理
7.前端控制层Controller(cn.smbms.controller):前端控制器全放在此包下
8.系统工具类(cn.smbms.tools):此包放公共对象和资源以及工具类
9.前端页面(/WEB-INF/jsp):JSP页面内容全放在/WEB-INF/jsp目录下
10.静态资源文件(/WebRoot/statics):一般放js,css,images等静态资源文件
第十四章:Git
一:Git简介:
1.是一个免费,开源的分布式版本控制系统
2.可以敏捷高效的进行各种项目规模大小的项目版本管理
3.与SVN一样,都是用来项目代码的版本管理
4.Git是分布式,SVN是集中式
5.分布式在于开发者可以提交到本地,通过克隆在本地机器上复制一个完整的Git仓库适合离线工作
6.GitHub:基于Git的免费项目托管平台 网址(http://github.com ) MyBatis、Bootstrap等开源项目的代码均由GitHub托管
二:GitLab安装与环境配置
1.开源的版本管理系统,实现自托管的Git项目仓库
2.它拥有与GitHub类似的功能,可以浏览源代码、管理缺陷和注释
3.依赖组件包括ruby、MySQL、Git、Redis等
5.安装与配置:1)环境准备 纯净版的CentOS6.5
2)安装GitLab的依赖包
3)安装GitLab的rpm包 gitlab-ce-8.10.2-ce.0.el6.x86_64.rpm
4)执行gitlab-ctl reconfigure,完成GitLab的重新配置
5)修改GitLab的配置文件 gitlab.yml和gitlab.rb
6)执行gitlab-ctl reconfigure,按照新的配置重启服务
7)通过客户端浏览器访问GitLab服务器
6.GitLab的使用 :通过web界面进行主干、分支以及用户、组、项目仓库等管理配置工作
1)修改root用户和密码
2)个人用户登录和注册:a.Name:用户姓名
b.Username:登录并操作GitLab的用户名
c.Email:Email地址
d.password:最少八位的登录密码
New project:创建项目
New group:创建组
3)创建组:1)单击 New group 按钮
2)Group path:添加组名
3)Description:添加组的描述信息
4)输入完后,单击“Greate group”按钮,完成创建
4)创建项目:1)单击 New project 按钮
2)Project path:选择组
3)Project name:仓库名或者项目名,一般与项目名一致
4)Project description:项目描述
5)输入完后 单击“Greate project”按钮,完成创建
5)member管理:单击设置中 Member 选项,进入 Add new user to project界面,进行用户添加及用户权限分配,对于开发者一般会设置 Developer权限
7.Git客户端安装 :1)Git GUI Here:使用界面方式操作Git
2)Git Bash Here:使用命令行的方式操作Git
8.Git命令
git clone ***
git add 文件名/-A
git commit -m “消息内容“
git push (origin master)
git status
git fetch
git branch –a
git checkout 分支名
git push/pull
git merge 分支名
gitlab-ctl stop/start
注意:1)不要安装JDK、MySQL、SVN等软件
2)在实际项目开发中,每次push、merge之前或者checkout切换分支后,都需要先pull操作,以更新该分支上的最新代码
三:使用Bootstrap实现项目前端开发
1.简介:1)简单灵活可用于框架流行的用户界面和交互接口的HTML、CSS、JavaScript工具集
2)基于jQuery框架,并兼容大部分jQuery插件
3)基于HTML5、CSS3实现响应式设计
4)官网 http://getbootstrap.com
5)gentelella-master(素材提供) a.免费主题模板 b.基于Bootstrap核心框架进行的二次开发
2.gentelella-master在项目中的运用
1)资源包的引用:js css images Fonts 注意:按需引用,避免不必要的引入造成前端的冗余,从而影响页面的运行加载速度
2)页面元素缩写:直接复制 login.html页面登录的form表单进行复用,其他页面元素采用相同方式