本文共 11743 字,大约阅读时间需要 39 分钟。
框架的概念:
框架(Framework):是一个提供了可重用的公共结构的半成品。它为我们构建新的应用程序提供了极大的便利。一方面提供了可以拿来就用的工具,更重要的是,提供了可重用的设计。框架这个词最早出现在建筑领域,指的是在建造房屋前期构建骨架。持久层框架:数据可以持久化;
作用:读写数据库,简化JDBC开发;主流框架的介绍
1.Struts 2框架 Struts 2以WebWork优秀的设计思想为核心,吸收了Struts框架的部分优点,提供了一个更加整洁的基于MVC设计模式实现的Web应用程序框架。它引入了几个新的框架特性:从逻辑中分离出横切关注点的拦截器,减少或消除配置文件,贯穿整个框架的强大表达式语言,支持可变更和可重用的基于MVC模式的标签API等。Struts 2充分利用了从其他MVC框架学到的经验和教训,使整个框架更加清晰,更加灵活。2.Hibernate框架
Hibernate是一个优秀的持久化框架,负责简化将对象数据保存到数据库中,或从数据库中读取数据并封装到对象的工作。Hibernate通过简单配置和编码即可替换JDBC烦琐的程序代码。Hibernate已经成为当前主流的数据库持久化框架,被广泛应用。3.Spring框架
Spring也是一个开源框架。它的目标是使现有的JavaEE技术更容易使用和促进良好的编程习惯。它是轻量级的框架,渗透了JavaEE技术的方方面面。它主要作为依赖注入容器和AOP实现存在,还提供了声明式事务,对DAO层的支持等简化开发的功能。Spring还可以方便地与SpringMVC、Struts 2、MyBatis、Hibernate等框架集成,其中大名鼎鼎的SSM集成框架指的就是基于SpringMVC+Spring+MyBati s的技术框架,使用这个集成框架将使我们的应用程序更加健壮、稳固、轻巧和优雅,这也就是当前最流行的Java技术框架;4.SpringMVC框架
SpringMVC是Spring框架提供的构建Web应用程序的全功能MVC模块,属于SpringFramework的后续产品,已经融合在Spring Web Flow里面,是结构最清晰的MVC Model2的实现。并且拥有高度的可配置性。支持多种视图技术。还可以进行定制化开发,相当灵活。此外,Script整合SpringMVC可以说是无缝集成,是一个高性能的架构模式。现在越来越广泛地应用于互联网应用的开发中。5.MyBatis框架
MyBatis是一个优秀的的数据持久层框架,在实体类和SQL语句之间建立映射关系,是一种半自动化的ORM实现。其封装性要低于Hibernate,性能优秀,并且小巧,简单易学,现在应用也越来越广泛。MyBatis框架及ORM
1.MyBatis框架简介: MyBatis是一个开源的数据持久层框架。它内部封装了通过JDBC访问数据库的操作,支持普通的SQL查询,存储过程和高级映射,几乎消除了所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis作为持久层框架,其主要思想是将程序中的大量SQL语句剥离出来,配置在配置文件中,实现SQL的灵活配置。这样做的好处是将SQL与程序代码分离,可以在不修改程序代码的情况下,直接在配置文件中修改SQL。2.什么是ORM
ORM(object/Relational Mapping)即对象/关系映射,是一种数据持久化技术。它在对象模型和关系数据库之间建立起对应关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据。MyBatis环境搭建
1.下载jar包 2.部署jar包 3.编写Mybatis核心配置文件 4.创建实体类 5.创建DAO接口 6.创建SQL映射文件 7.编写测试类创建MyBatis核心配置文件configuration.xml
//初始化时加载,映射到需要使用的Sql映射文件
Mybatis-config.xml文件的几个常用元素的作用如下:
创建持久化类(POJO)和SQL映射文件
持久化类是指其实列状态需要被MyBatis持久化到数据库中的类。在应用程序中,持久化类通常对应需要中的业务实体。MyBatis一般采用POJO编程模型来实现持久化类,与POJO类配合完成持久化工作是MyBatis最常见的工作模式。 POJO(Plain Ordinary Java Object),从字面上来将就是普通java对象。POJO类可以简单地理解为符合JavaBean规范的实体类,它不需要继承和实现任何特殊的Java基类或者接口。JavaBean对象的状态保存在属性中,访问属性必须通过对应的getter和setter方法。设置SQL映射文件
Sql映射文件namespace必须指定到一个接口进行实现,id指定为接口中的某个方法;
为类取别名
平时我们再写返回类型时,需要指定到包名位置下的类,例如:当类名比较长的时候我们编写代码的时候可能会比较麻烦,解决方法可以在mybatis-config.xml文件的节点下创建一个节点在这个节点中为类指定一个别名:
1.给包名取别名:这样包名下的类名就可以直接使用且类名不区分大小写;
2.给类名取别名这样直接使用指定的别名就可以了(也可以指定类原来的名字不过还是得带上包名);
DTD文件的引入
XML文件没有快捷键问题解决,需要导入两个DTD文件: 1.mybatis-3-config.dtd 2.mybatis-3-mapper.dtd 导入路径: Window—》Preperences—》MyEclipse—》Files and Editors—》XML—》Xml Catalog—》User Specified Entries3.打开之后为这个页面,选择File System找到mybatis-3-
config.dtd文件路径配置完后,Xml文件就有属性提示和标签提示;
MyBatis真正强大之处在于SQL映射语句,也是它的魅力所在。相对于它强大的功能,SQL映射文件的配置确非常简单。
什么是映射? 映射是个术语,指两个元素的集之间元素相互“对应”的关系;SQL映射文件的几个顶级元素配置:
1.mapper:映射文件的根元素节点,只有一个属性namespace(命名空间又可称为全限定类名),其作用如下:1.用于区分不同的mapper,全局唯一
2.绑定DAO接口,集面向接口编程。当namespace绑定某一接口之后,可以不用写该接口的实现类,MyBatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句。因此namespace的命名必须要跟接口同名。 2.cache:配置给定命名空间的缓存。 3.cache-ref:从其他命名空间引用缓存配置。 4.resultMap:用来描述数据库结果集和对象的对应关系。 5.sql:可以重用的SQL块,也可以被其他语句引用。 6.insert:映射插入语句。 7.update:映射更新语句。 8.delete:映射删除语句。 9.select:映射查询语句。
使用select完成多条查询
当使用多条数据的时候系统可能映射不到指定的类型,这使我们就需要使用到注解(@Param(“p”))来为变量或对象指定别名; 接口中:public int update(@Param("p") paging p,@Param("name") String name);
映射的xml文件中:
update paging set name=#{p.name},sex=#{p.sex} where name=#{name}
//#{}为占位符
除此之外也能使用下标来代替(传递的类型不为类的类型的时候):update paging set name=#{0},sex=#{1} where name=#{2}
模糊查询:
在mysql中有一个concat函数,使用concat函数将参数进行拼接,代码如下:使用resultMap完成查询结果的展示
为什么要使用resultMap: 在使用select读取数据库的数据过程中,select语句会自动将读取的结果集封装在实体类的属性中,但前提是实体类中的属性必须和数据库中的字段名相同,那么如果不相同的情况下select读取的结果集将无法映射到实体类中,对此有两种方法解决: 1.将实体类属性名修改对应数据库表中的列名; 2.通过resultMap来映射自定义结果,代码如下: 1.编写结果映射节点2.通过结果映射节点的id属性和select节点中的resultMap属性匹配:
resultMap元素的属性值和子节点:
1.id属性:唯一表示,此id值用于select元素对resultMap属性的引用;
2.type属性:表示该resultMap的映射结果类型。3.result子节点:用于标识一些简单的属性,其中column属性表示从数据库中查询的字段名,property则表示查询出来的字段对应的值赋给实体类中的哪个属性。
4.id子节点:唯一标识,用来标识数据库表中的主键,此节点如果不写则默认表示查询出来的第一列为主列;
association(关联)
association映射到JavaBean的某个“复杂类型”属性,比如JavaBean内部嵌套一个复杂数据类型(JavaBean)属性,这种情况就属于复杂类型的关联(主外键连接)。但是需要注意association仅处理一对一的关联关系;为什么使用association?
当我们使用多表联查的时候,查询的结果集只能映射到一个JavaBean(实体类),此时一个JavaBean中的属性不能与数据库中的列名进行映射关系,所以需要在JavaBean中再嵌套一个JavaBean, 但是数据库的外键列和嵌套的JavaBean类型也不匹配此时便需要使用到association元素;//此时的association就相当于一个外键表
resultMap可以通过extends属性继承resultMap,例如我们需要重复使用一个resultMap时,这样就可以使用到继承了,代码如下:
Entirys继承pagingResult后便可实现父类的所有功能,也可实现自己的功能,和Java继承用一样;
Collection(集合)
实现一对多映射关系,例如数据库中的数据为:实现时数据为:
实现一对多和association(关联)一样需要使用到多表联查,但不同的是associatio我们实现的是在javaBean中嵌入一个javaBean但一对多collection(集合)不一样,顾名思义,此时我们需要在JavaBean中嵌入一个泛型集合,实现如下:
在一对多的映射情况下,collection会自动映射,所以两条y2数据出来的只会是一个,而对应y2的数据根据配置的collection自动映射到了javabean封装的list泛型集合中;
resultMap自动映射级别和MyBaties缓存
//设置自动匹配级别,name值设置和下面代码一样1.NONE: 禁止自动匹配
2.PARTIAL(默认):自动匹配所有属性,有内部嵌套(association、collection)的除外; 3.FULL:自动匹配所有;关于使用白盒测试注意事项
在mybatis-config.xml文件中的节点下配置:白盒测试的方法不能携带参数也不能有返回值;
动态SQL是mybatis的一个强大特性。在使用JDBC操作数据时,如果查询条件特别多,将多条数据串联成SQL字符串是一件痛苦的事情,通常的解决方法是写很多的if-else条件语句对字符串进行拼接,并确保不能忘了空格或在字段的最后省略逗号。MyBatis使用一种强大的动态SQL语言来改善这种情况。动态SQL基于OGNL的表达式,可使我们方便地在SQL语句中实现某些逻辑,用于实现动态SQL的元素如下:
1.if:利用if实现简单的条件选择。
2.choose(when、otherwise):相当于java中的switch语句,通常与when和otherwise搭配。 3.where:简化SQL语句中where的条件判断; 4.set:解决动态更新语句; 5.trim:可以灵活地去除多余的关键字; 6.foreach:迭代一个集合,通常用于in条件;
使用if+where实现多条件查询
Select * from 表名and id=#{parameter(参数)} and name=#{parameter(参数)}
使用where标签执行动态SQL有很多好处:
1.当where中没有内容时,sql语句会默认去除where,例如上面的代码if条件都不成立,那么将省略where标签变成:Select * from 表名;
2.如果where条件内如果有or 或 and开头的条件,when会自动去除以or或and开头的条件,例如:
select * from gradeand id=#{参数}
3.使用if+trim实现多条件查询
trim元素也会自动识别其标签内是否有返回值,若有返回值,会在自己包含的内容前加上某些前缀,也可在其后加上某些后缀,与之对应的属性是prefix和suffix;也可以把包含内容的首部某些内容覆盖(忽略),或者把尾部的某些内容覆盖,与之对应的属性是prefixOverrides和suffixOverrides;4.Mybatis完成复杂查询
对于SQL条件循环(in语句),需要使用foreach标签。Foreach标签中的属性如下: Item:表示集合中每一个元素进行迭代时的别名。 Index:用于表示在迭代过程中,每次迭代到的位置。 Open:表示该语句以什么开始,open=”(”这个(会自己追加在前面而不是你自己写的。 close:表示该语句以什么结束,close=”)”这个(会自己追加在前面而不是你自己写的。 separator:表示以什么相隔; Collection:最关键并最容易出错的属性,需格外注意,该属性必须指定,不同情况下,该属性的值是不一样的,主要有三种情况: 1.若入参为单参数且参数类型是一个List的时候,collection属性值为list。 2.若入参为单参数且参数类型是一个数组时,collection属性值为array。 3.若传入参数为多参数,我们就需要把它们封装为一个Map进行处理。什么是spring?
它是一个Bean容器,能够帮我们管理JavaBean(能够帮我们实例化创建对象); DI(依赖注入) 它还可以帮我们把属性值提前赋值好(注入,注入值,注入对象) A、要能够注入值,要求有set方法 B、你的类要满足规范的JavaBean C、它会自动帮你做基本类型转换开闭原则:(OCP open close principle)
1.对扩展开放(你可以添加新的类和代码文件,替换原有的类文件或代码文件); 2.对修改关闭(不可以修改原有的代码)Spring的三大核心思想:IOC(控制反转),DI(依赖注入),AOP(面向切面编程)。
(1)IOC(控制反转) 实现将组件间的关系从程序内部提到外部容器(spring的xml)来管理。 首先外部容器(spring.xml)中会动态的注册业务所需的对象(接口/类)(2)DI(依赖注入)
组件之间的依赖关系由容器在应用系统运行期来决定, 也就是由容器动态地将某种依赖关系的目标对象实例注入到应用系统中的各个关联的组件之中。控制反转(Inversion of Control,IoC),也称为依赖注入(Dependency Injection,DI),是面向对象编程中的一种设计理念,用来降低程序代码之间的耦合度。
控制反转:其实就是控制权转移,不再由类的内部构建对象,而是交由外部容器来构建对象;1.编写spring工具类
//spring工具类public class springUtil { //初始化Spring容器ApplicationContext private static ApplicationContext applicationContext=null; static{ //静态代码块加载配置文件 applicationContext=new ClassPathXmlApplicationContext("applicationContext.xml"); } //通过Id得到bean实例(也可以通过类类型得到) public static Object getBean(String beanId){ return applicationContext.getBean(beanId); }}
2.spirng DI(依赖注入)
依赖注入:你依赖什么,或者说你缺少什么,你需要什么,我就给你注入什么,给你赋值,给你设置。 基本属性,使用value注入值(注意: 注入时需要有setter方法):复杂属性,使用ref注入值(注意: 注入时需要有setter方法):
面向切面编程(Aspect Oriented Programming,AOP)是软件编程思想发展到一定阶级的产物,是面向对象编程(Object Oriented Programming,OOP)的有益补充。AOP一般适用于具有横切逻辑的场合,如访问控制,事务管理,性能监测等。
(处理横向拦截的的任务) AOP:(aspect oriented programming 面向切面编程(处理横向拦截的任务))1.它的本质就是方法拦截
2.能够在方法执行之前,或者方法执行之后,自动完成某些事情(执行某些代码) 3.拦截到到了方法以后,要做什么事情(增强、通知、advice -前置通知、后置通知) 4.哪些方法会被拦截(即拦截的面有多大) 织入:weaving(把通知和被拦截的目标对象组织起来的过程); 切面:pointcut 或者叫切入点 5.五种增强: a、前置增强:把拦截的方法看成try-catch,那么前置增强就相当于切入到try的最前面。 b.后置增强:把拦截的方法看成try-catch,那么前置增强就相当于切入到try的最后面。 c、异常增强:切入到方法当中捕获发生的异常,相当于catch部分。 d、最终增强:其作用相当于finally一样,切入到方法的最后一部分。 e、环绕增强:织入方法的前后执行,环绕增强方法包裹住了织入的方法,环绕增强可以决定是否调用织入方法。 6.无代码侵入性(即不需要修改原有的代码只需配置xml文件)
expression:表达式,下面的是表达式编写的语法规格:
(?代表这个参数可选) execution(modifiers-pattern?、return-type-pattern、declaring-type-pattern?、name-pattern、param-pattern 、throws-pattern? ) execution表达式参数: modifiers-pattern:访问修饰符:public protected private;(可选) return-type-pattern:返回值类型 String、int …; declaring-type-pattern:包名(可选); name-pattern:方法名; param-pattern:参数列表; throws-pattern:异常类型; 注意: 1.返回值类型、方法名、参数是不可省略的组成部分; 2.省略不写的部分,表示不做要求; 3.可以带上包名,对指定报下的指定类进行拦截execution(* com.dao..(…)); 4.方法名也可以用通配符execution(* com.dao..add(…)); 5.可以对包下的后台包进行拦截execution(* com.dao….(…)),意思是(访问修饰符 任何返回值 包名…所有类.所有方法(…所有数据类型))Spring获取拦截的参数和返回结果:
1.获取参数: 在前置增强中设置参数JoinPoint去拦截获取参数,例如: public void printAfter(JoinPoint po) { System.out.println(po.getArgs()[0]); } 通过getArgs()[0]方法和参数列表的下标得到参数; 2.获取返回值 在后置增强中设置参数Object去拦截获取返回值,例如: public void printAfter(Object ob) { System.out.println(ob); } 注意这里需要配置xml文件当中的属性returning=“object的参数”,例如:多种方式实现依赖注入:
1.构造方式注入(时效性要高于set方法注入,在构造对象的时候就初始化注入好了); A.通过参数index注入:B.通过参数name注入:
C.通过参数type注入:
D.如果参数是对象使用ref注入:
2.使用p命名空间实现属性注入
首先引入p命名空间:xmlns:p="http://www.springframework.org/schema/p"
使用p:有参构造参数名(注意需要有无参构造才能使用)
如果注入的是对象,需要以-ref结尾,例如p:dao-ref=”userDao”
注入不同数据类型:
List集合注入:null值注入:
使用标签使用注解实现IoC的配置
@Component(“实现类”):此注解加在实现类上面,表示将此类交由spring托管,等同于下面这句代码:A、如果不设定名字,那么就默认类名首字母小写;
B、如果自定义名字,那么使用这种写法:@Component(“pet”); C、此注解如果要生效,需要开启组件扫描,让spring去扫描特定包下的类,看看哪个类有注解任何把它加入进来,配置如下:其他作用相同的注解:
@Repository:仓库、数据仓库,数据访问对象(指向数据访问层) @Service:服务,业务逻辑层 @Controller:控制器@Autowired注解:自动注入,自动装配(spring自带的注入注解)
1.根据类型来注入(bytype),如果有多个相同类型(Component (“id”)和对象名相同除外),则报错; 2.如果需要根据名字来指定注入(byName),则使用注解指定@Qualifier(“类名(注意:首字母小写)”); 3.此注解可以加在私有属性上,Spring会通过反射机制直接注入,并不调用set方法,所以set方法可以省略; 4.也可以加上set方法上,spring会通过调用这个set方法来注入; 5.也可以加在构造函数上;@Resource:自动注入,自动装配(Java官方提供的注入注解,更好用,推荐使用)
1.首先根据属性名或者set方法名称来注入 ,即byName; 2.如果根据名字查找失败,则自动切换为根据数据类型匹配自动查找,即byType; 3.如果根据数据类型查找,找到两个或两个以上,则报错; 4.此注解可以加在私有属性上,Spring会通过反射技术直接注入,并不调用set方法,所有set方法可以省略; 5.也可以加上set方法上,spring会通过调用这个set方法来注入; 6.也可以加在构造函数上; 7.如果需要指定注入的bean名称,可以在注解里面加属性:@Resource(name=”类名(注意:首字母小写)”);AspectJ简介
Aspect是一个面向切面的框架,它扩展了Java语言,定义了AOP语法,能够在编译期提供代码的织入,所以它有一个专门的编译器用来生成遵守字节编码规范的Class文件。 AOP的实现和配置有两套: 1.xml方式,spring自带的; 2.注解方式,是使用AspectJ组件实现的,Spring只是做了封装 想要使用@Aspect注解,需要添加spring自动代理:3.想要使用AspectJ注解进行拦截需要在当前类添加@Aspect注解,如下所示:
其次在需要使用的增强上添加注解,例如前置增强:
4.AspectJ使用注解进行五大增强
A.前置增强:@Before(“execution()”); B.后置增强:@AfterReturning(“execution()”); C.最终增强:@After(“execution()”); D.异常增强:@AfterThrowing(pointcut = “execution(public * entity…Cat.*(…))”,returning = “ob”); E.环绕增强:@Around(“execution()”),使用环绕通知会拦截整个方法,此时这个方法不被调用,想要调用的话可以在环绕通知添加参数:ProceedingJoinPoint,再通过这个对象调用proceed()方法转载地址:http://lqqzi.baihongyu.com/