Struct2
Struts 2框架本身大致可以分为3个部分:
核心控制器FilterDispatcher、业务控制器Action和用户实现的企业业务逻辑组件。
核心控制器FilterDispatcher是Struts 2框架的基础,
包含了框架内部的控制流程和处理机制。
业务控制器Action和业务逻辑组件是需要用户来自己实现的。
用户在开发Action和业务逻辑组件的同时,还需要编写相关的配置文件,
供核心控制器FilterDispatcher来使用。
Struts 2的工作流程相对于Struts 1要简单,与WebWork框架基本相同,
所以说Struts 2是WebWork的升级版本。基本简要流程如下:
1 、客户端初始化一个指向Servlet容器的请求;
2、 这个请求经过一系列的过滤器(Filter)
(这些过滤器中有一个叫做ActionContextCleanUp的可选过滤器,
这个过滤器对于Struts2和其他框架的集成很有帮助,例如:SiteMesh Plugin)
3 、接着FilterDispatcher被调用,
FilterDispatcher询问ActionMapper来决定这个请是否需要调用某个Action
4、如果ActionMapper决定需要调用某个Action,
FilterDispatcher把请求的处理交给ActionProxy
5、ActionProxy通过Configuration Manager询问框架的配置文件,
找到需要调用的Action类
6、ActionProxy创建一个ActionInvocation的实例。
7、ActionInvocation实例使用命名模式来调用,
在调用Action的过程前后,涉及到相关拦截器(Intercepter)的调用。
8、一旦Action执行完毕,ActionInvocation负责根据struts.xml中的配置找到对应的返回结果 。返回结果通常是(但不总是,也可 能是另外的一个Action链)一个需要被表示的JSP或者FreeMarker的模版。 在表示的过程中可以使用Struts2 框架中继承的标签。 在这个过程中需要涉及到ActionMapper
9、响应的返回是通过我们在web.xml中配置的过滤器
10、如果ActionContextCleanUp是当前使用的,则FilterDispatecher将不会清理sreadlocal ActionContext;如果ActionContextCleanUp不使用,则将会去清理sreadlocals。
2、说下Struts的设计模式
MVC模式: web应用程序启动时就会加载并初始化ActionServler。用户提交表单时,一个配置好的ActionForm对象被创建,并被填入表单相应的数据,ActionServler根据Struts-config.xml文件配置好的设置决定是否需要表单验证,如果需要就调用ActionForm的Validate()验证后选择将请求发送到哪个Action,如果Action不存在,ActionServlet会先创建这个对象,然后调用Action的execute()方法。Execute()从ActionForm对象中获取数据,完成业务逻辑,返回一个ActionForward对象,ActionServlet再把客户请求转发给ActionForward对象指定的jsp组件,ActionForward对象指定的jsp生
成动态的网页,返回给客户。
3、拦截器和过滤器的区别
1、拦截器是基于java反射机制的,而过滤器是基于函数回调的。
2、过滤器依赖于servlet容器,而拦截器不依赖于servlet容器。
3、拦截器只能对Action请求起作用,而过滤器则可以对几乎所有请求起作用。
4、拦截器可以访问Action上下文、值栈里的对象,而过滤器不能。
5、在Action的生命周期中,拦截器可以多次调用,而过滤器只能在容器初始化时被调用一次。
4、struts1于struts2的比较
1、Action 类:
Struts1要求Action类继承一个抽象基类。Struts1的一个普遍问题是使用抽象类编程而不是接口。
Struts 2 Action类可以实现一个Action接口,也可实现其他接口,使可选和定制的服务成为可能。Struts2提供一个ActionSupport基类去 实现常用的接口。Action接口不是必须的,任何有execute标识的POJO对象都可以用作Struts2的Action对象。
2、线程模式:
Struts1 Action是单例模式并且必须是线程安全的,因为仅有Action的一个实例来处理所有的请求。单例策略限制了Struts1 Action能作的事,并且要在开发时特别小心。Action资源必须是线程安全的或同步的。
Struts2 Action对象为每一个请求产生一个实例,因此没有线程安全问题。(实际上,servlet容器给每个请求产生许多可丢弃的对象,并且不会导致性能和垃圾回收问题)
3、Servlet 依赖:
Struts1 Action 依赖于Servlet API ,因为当一个Action被调用时HttpServletRequest 和 HttpServletResponse 被传递给execute方法。
Struts 2 Action不依赖于容器,允许Action脱离容器单独被测试。如果需要,Struts2 Action仍然可以访问初始的request和response。但是,其他的元素减少或者消除了直接访问HttpServetRequest 和 HttpServletResponse的必要性。
4、可测性:
测试Struts1 Action的一个主要问题是execute方法暴露了servlet API(这使得测试要依赖于容器)。一个第三方扩展--Struts TestCase--提供了一套Struts1的模拟对象(来进行测试)。
Struts 2 Action可以通过初始化、设置属性、调用方法来测试,“依赖注入”支持也使测试更容易。
5、捕获输入:
Struts1 使用ActionForm对象捕获输入。所有的ActionForm必须继承一个基类。因为其他JavaBean不能用作ActionForm,开发者经 常创建多余的类捕获输入。动态Bean(DynaBeans)可以作为创建传统ActionForm的选择,但是,开发者可能是在重新描述(创建)已经存 在的JavaBean(仍然会导致有冗余的javabean)。
Struts 2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过 web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种 ModelDriven 特性简化了taglib对POJO输入对象的引用。
6、表达式语言:
Struts1 整合了JSTL,因此使用JSTL EL。这种EL有基本对象图遍历,但是对集合和索引属性的支持很弱。
Struts2可以使用JSTL,但是也支持一个更强大和灵活的表达式语言-- "Object Graph Notation Language " (OGNL).
7、绑定值到页面(view):
Struts 1使用标准JSP机制把对象绑定到页面中来访问。
Struts 2 使用 "ValueStack "技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。
8、类型转换:
Struts 1 ActionForm 属性通常都是String类型。Struts1使用Commons-Beanutils进行类型转换。每个类一个转换器,对每一个实例来说是不可配置的。
Struts2 使用OGNL进行类型转换。提供基本和常用对象的转换器。
9、校验:
Struts 1支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。
Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性
10、Action执行的控制:
Struts1支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。
Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。
为什么要使用Struts2
Struts2 是一个相当强大的Java Web开源框架,是一个基于POJO的Action的MVC Web框架。它基于当年的Webwork和XWork框架,继承其优点,同时做了相当的改进。
1.Struts2基于MVC架构,框架结构清晰,开发流程一目了然,开发人员可以很好的掌控开发的过程。
2使用OGNL进行参数传递。
OGNL提供了在Struts2里访问各种作用域中的数据的简单方式,你可以方便的获取Request,Attribute,Application,Session,Parameters中的数据。大大简化了开发人员在获取这些数据时的代码量。
3强大的拦截器
Struts2 的拦截器是一个Action级别的AOP,Struts2中的许多特性都是通过拦截器来实现的,例如异常处理,文件上传,验证等。拦截器是可配置与重用的,可以将一些通用的功能如:登录验证,权限验证等置于拦截器中以完成一些Java Web项目中比较通用的功能。在我实现的的一Web项目中,就是使用Struts2的拦截器来完成了系统中的权限验证功能。
4易于测试
Struts2的Action都是简单的POJO,这样可以方便的对Struts2的Action编写测试用例,大大方便了5Java Web项目的测试。
易于扩展的插件机制在Struts2添加扩展是一件愉快而轻松的事情,只需要将所需要的Jar包放到WEB-INF/lib文件夹中,在struts.xml中作一些简单的设置就可以实现扩展。
6模块化管理
Struts2已经把模块化作为了体系架构中的基本思想,可以通过三种方法来将应用程序模块化:将配置信息拆分成多个文件把自包含的应用模块创建为插件创建新的框架特性,即将与特定应用无关的新功能组织成插件,以添加到多个应用中去。
7全局结果与声明式异常
为应用程序添加全局的Result,和在配置文件中对异常进行处理,这样当处理过程中出现指定异常时,可以跳转到特定页面。
他的如此之多的优点,是很多人比较的青睐,与spring ,Hibernate进行结合,组成了现在比较流行的ssh框架,当然每个公司都要自己的框架,也是ssh变异的产品。
struts2有哪些优点?
1)在软件设计上Struts2的应用可以不依赖于Servlet API和struts API。 Struts2的这种设计属于无侵入式设计;
2)拦截器,实现如参数拦截注入等功能;
3)类型转换器,可以把特殊的请求参数转换成需要的类型;
4)多种表现层技术,如:JSP、freeMarker、Velocity等;
5)Struts2的输入校验可以对指定某个方法进行校验;
6)提供了全局范围、包范围和Action范围的国际化资源文件管理实现
struts2是如何启动的?
struts2框架是通过Filter启动的,即StrutsPrepareAndExecuteFilter,此过滤器为struts2的核心过滤器;
StrutsPrepareAndExecuteFilter的init()方法中将会读取类路径下默认的配置文件struts.xml完成初始化操作。struts2读取到struts.xml的内容后,是将内容封装进javabean对象然后存放在内存中,以后用户的每次请求处理将使用内存中的数据,而不是每次请求都读取struts.xml文件。
struts2框架的核心控制器是什么?它有什么作用?
1)Struts2框架的核心控制器是StrutsPrepareAndExecuteFilter。
2)作用:
负责拦截由<url-pattern>/*</url-pattern>指定的所有用户请求,当用户请求到达时,该Filter会过滤用户的请求。默认情况下,如果用户请求的路径
不带后缀或者后缀以.action结尾,这时请求将被转入struts2框架处理,否则struts2框架将略过该请求的处理。
可以通过常量"struts.action.extension"修改action的后缀,如:
<constant name="struts.action.extension" value="do"/>
如果用户需要指定多个请求后缀,则多个后缀之间以英文逗号(,)隔开。
<constant name="struts.action.extension" value="do,go"/>
struts2配置文件的加载顺序?
struts.xml ——> struts.properties
常量可以在struts.xml或struts.properties中配置,如果在多个文件中配置了同一个常量,则后一个文件中配置的常量值会覆盖前面文件中配置的常量值.
struts.xml文件的作用:通知Struts2框架加载对应的Action资源
struts2常量的修改方式?
常量可以在struts.xml或struts.properties中配置,两种配置方式如下:
1)在struts.xml文件中配置常量
<constant name="struts.action.extension" value="do"/>
2)在struts.properties中配置常量(struts.properties文件放置在src下):
struts.action.extension=do
struts2如何访问HttpServletRequest、HttpSession、ServletContext三个域对象?
方案一:
HttpServletRequest request =ServletActionContext.getRequest();
HttpServletResponse response =ServletActionContext.getResponse();
HttpSession session= request.getSession();
ServletContext servletContext=ServletActionContext.getServletContext();
方案二:
类 implements ServletRequestAware,ServletResponseAware,SessionAware,ServletContextAware
注意:框架自动传入对应的域对象
struts2是如何管理action的?这种管理方式有什么好处?
struts2框架中使用包来管理Action,包的作用和java中的类包是非常类似的。
主要用于管理一组业务功能相关的action。在实际应用中,我们应该把一组业务功能相关的Action放在同一个包下。
struts2中的默认包struts-default有什么作用?
1)struts-default包是由struts内置的,它定义了struts2内部的众多拦截器和Result类型,而Struts2很多核心的功能都是通过这些内置的拦截器实现,如:从请求中
把请求参数封装到action、文件上传和数据验证等等都是通过拦截器实现的。当包继承了struts-default包才能使用struts2为我们提供的这些功能。
2)struts-default包是在struts-default.xml中定义,struts-default.xml也是Struts2默认配置文件。 Struts2每次都会自动加载 struts-default.xml文件。
3)通常每个包都应该继承struts-default包。
struts2如何对指定的方法进行验证?
1)validate()方法会校验action中所有与execute方法签名相同的方法;
2)要校验指定的方法通过重写validateXxx()方法实现, validateXxx()只会校验action中方法名为Xxx的方法。其中Xxx的第一个字母要大写;
3)当某个数据校验失败时,调用addFieldError()方法往系统的fieldErrors添加校验失败信息(为了使用addFieldError()方法,action可以继承ActionSupport), 如果系统 的fieldErrors包含失败信息,struts2会将请求转发到名为input的result;
4)在input视图中可以通过<s:fielderror/>显示失败信息。
5)先执行validateXxxx()->validate()->如果出错了,会转发<result name="input"/>所指定的页面,如果不出错,会直接进行Action::execute()方法
struts2默认能解决get和post提交方式的乱码问题吗?
不能。struts.i18n.encoding=UTF-8属性值只能解析POST提交下的乱码问题。
请你写出struts2中至少5个的默认拦截器?
fileUpload 提供文件上传功能
i18n 记录用户选择的locale
cookies 使用配置的name,value来是指cookies
checkbox 添加了checkbox自动处理代码,将没有选中的checkbox的内容设定为false,而html默认情况下不提交没有选中的checkbox。
chain 让前一个Action的属性可以被后一个Action访问,现在和chain类型的result()结合使用。
alias 在不同请求之间将请求参数在不同名字件转换,请求内容不变
值栈ValueStack的原理与生命周期?
1)ValueStack贯穿整个 Action 的生命周期,保存在request域中,所以ValueStack和request的生命周期一样。当Struts2接受一个请求时,会迅速创建ActionContext,
ValueStack,action。然后把action存放进ValueStack,所以action的实例变量可以被OGNL访问。 请求来的时候,action、ValueStack的生命开始,请求结束,action、 ValueStack的生命结束;
2)action是多例的,和Servlet不一样,Servelt是单例的;
3)每个action的都有一个对应的值栈,值栈存放的数据类型是该action的实例,以及该action中的实例变量,Action对象默认保存在栈顶;
4)ValueStack本质上就是一个ArrayList;
5)关于ContextMap,Struts 会把下面这些映射压入 ContextMap 中:
parameters : 该 Map 中包含当前请求的请求参数
request : 该 Map 中包含当前 request 对象中的所有属性 session :该 Map 中包含当前 session 对象中的所有属性
application :该 Map 中包含当前 application 对象中的所有属性
attr:该 Map 按如下顺序来检索某个属性: request, session, application
6)使用OGNL访问值栈的内容时,不需要#号,而访问request、session、application、attr时,需要加#号;
7)注意: Struts2中,OGNL表达式需要配合Struts标签才可以使用。如:<s:property value="name"/>
8)在struts2配置文件中引用ognl表达式 ,引用值栈的值 ,此时使用的"$",而不是#或者%;
ActionContext、ServletContext、pageContext的区别?
1)ActionContext是当前的Action的上下文环境,通过ActionContext可以获取到request、session、ServletContext等与Action有关的对象的引用;
2)ServletContext是域对象,一个web应用中只有一个ServletContext,生命周期伴随整个web应用;
3)pageContext是JSP中的最重要的一个内置对象,可以通过pageContext获取其他域对象的应用,同时它是一个域对象,作用范围只针对当前页面,当前页面结束时,pageContext销毁,
生命周期是JSP四个域对象中最小的。
result的type属性中有哪几种结果类型?
一共10种:
dispatcher
struts默认的结果类型,把控制权转发给应用程序里的某个资源不能把控制权转发给一个外部资源,若需要把控制权重定向到一个外部资源, 应该使用
redirect结果类型
redirect 把响应重定向到另一个资源(包括一个外部资源)
redirectAction 把响应重定向到另一个 Action
freemarker、velocity、chain、httpheader、xslt、plainText、stream
拦截器的生命周期与工作过程?
1)每个拦截器都是实现了Interceptor接口的 Java 类;
2)init(): 该方法将在拦截器被创建后立即被调用, 它在拦截器的生命周期内只被调用一次. 可以在该方法中对相关资源进行必要的初始化;
3)intercept(ActionInvocation invocation): 每拦截一个动作请求, 该方法就会被调用一次;
4)destroy: 该方法将在拦截器被销毁之前被调用, 它在拦截器的生命周期内也只被调用一次;
5)struts2中有内置了18个拦截器。
struts2如何完成文件的上传?
1、JSP页面:
1)JSP页面的上传文件的组件:<s: file name=”upload” />,如果需要一次上传多个文件, 就必须使用多个 file 标签, 但它们的名字必须是相同的,即:
name=“xxx”的值必须一样;
2)必须把表单的enctype属性设置为:multipart/form-data;
3)表单的方法必须为post,因为post提交的数据在消息体中,而无大小限制。
2、对应的action:
1)在 Action 中新添加 3 个和文件上传相关的属性;
2)如果是上传单个文件, uploadImage属性的类型就是 java.io.File, 它代表被上传的文件, 第二个和第三个属性的类型是 String, 它们分别代表上传文
件的文件名和文件类型,定义方式是分别是:
jsp页面file组件的名称+ContentType, jsp页面file组件的名称+FileName
3)如果上上传多个文件, 可以使用数组或 List
Mybatis
1. Mybatis的介绍
1.1 什么是Mybatis?
Mybatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
1.2 特点:
Mybatis是支持普通SQL查询,存储过程和高级映射的持久层框架。对JDBC的操作数据库过程进行封装,可使用简单的xml或注解用于配置和原始映射,将接口和Java的pojo映射成数据库中的记录。
2.Mybatis入门
2.1 mybatis的架构图
2.2 mybatis配置并实现对数据库的CRUD步骤
前提:
mybatis下载 网址: https://github.com/mybatis/mybatis-3/releases
mybatis-3.2.7.jar mybatis的核心包
lib文件夹 mybatis的依赖包所在
mybatis-3.2.7.pdf mybatis使用手册
下载数据库驱动包: mysql-connector-java-5.1.40-bin.jar
加入mybatis核心包、依赖包、数据驱动包。
(1). config.xml文件:
作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 和spring整合后 environments配置将废除 -->
<environments default="development"> default: development:开发模式 / work:工作模式
<environment id="development"> id:数据源标志
<!-- 使用jdbc事务管理 -->
<transactionManager type = "JDBC" /> JDBC:JDBC事务 ;Manage:容器方式管理事务;自定义
<!-- 数据库连接池 -->
<dataSource type="POOLED"> JNDI:JNDI数据源 ;UNPOOLED:非数据库连接池 ;自定义
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/test?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="mapper/mapper.xml"/> 完整路径:包名.类名
</mappers>
</configuration>
(2). mapper.xml:
sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在config.xml中加载。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace:命名空间,用于隔离sql -->
<mapper namespace="mapper.mapper">
<!-- id:statement的id 或者叫做sql的id-->
<!-- parameterType:声明输入参数的类型 -->
<!-- resultType:声明输出结果的类型,应该填写pojo的全路径 -->
<!-- #{}:输入参数的占位符,相当于jdbc的? -->
<!-- 查询用户 -->
<select id="selectAllUser" parameterType="int" resultType="user.User">
Select * from mybatis
</select>
<select id="selectUserById" parameterType="int" resultType="user.User">
Select * from mybatis where id=#{id}
</select>
<select id="selectUserBylike" parameterType="int" resultType="user.User">
Select * from mybatis where username like #{username}
</select>
<!-- 修改用户 -->
<update id="UpdateAllUser" parameterType="user.User" >
Update mybatis set username = #{username}, age = #{age}
</update>
<update id="UpdateUserById" parameterType="user.User" >
Update mybatis set username = #{username} where id = #{id}
</update>
<!-- 增加用户 -->
<insert id="insertUser" parameterType="user.User" >
insert into mybatis(id,username,age) values(#{id}, #{username}, #{age});
</insert>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="user.User" >
delete from mybatis where id = #{id};
</delete>
</mapper>
(3).configMJBC.java
通过mybatis环境等配置信息构造SqlSessionFactory即会话工厂;
由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
public class MJdbc {
/**
* 获取SqlSessionFactory
*/
public static SqlSessionFactory getssFactory(){
String resource ="config.xml";
InputStream is = MJdbc.class.getClassLoader().getResourceAsStream(resource);
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is);
return ssf;
}
/**
* 获取SqlSession
*/
public static SqlSession getSqlSession(){
return getssFactory().openSession() ;
}
/**
* 获取SqlSession
* @param isAutoCommit
* true 表示创建的SqlSession对象在执行完SQL之后会自动提交事务
* false表示创建的SqlSession对象在执行完SQL之后不会自动提交事务,
* 这时就需要我们手动调用sqlSession.commit()提交事务
* @return SqlSession
*/
public static SqlSession getSqlss(boolean isAutoCommit){
return getssFactory().openSession(false) ;
}
}
(4).配置接口 IUser.java
/**
* 使用@Select注解指明SelectUserById方法要执行的SQL
* 根据Id查询用户
* @param id
*/
@Select("Select * from mybatis where id=#{id}")
public User SelectUserById();
/**
* 查询所有用户
* @return
*/
@Select("Select * from mybatis")
public void SelectAllUser();
/**
* 根据用户名模糊查询用户
*/
@Select("Select * from mybatis where username like %b%")
public void SelectUserBylike();
/**
* 根据Id修改用户
*/
@Update("Update mybatis set name = bao where id=#{id}")
public void UpdateUserById();
/**
* 修改全部用户
*/
@Update("Update mybatis set username = #{username} ")
public void UpdateAllUser();
/**
* 添加用户
*/
@Insert("insert into mybatis(id,username,age) values(#{id}, #{username}, #{age})")
public void InsertUser();
/**
* 删除用户
*/
@Delete("delete from mybatis where id = #{id}")
public void DeleteUser();
}
(5).配置IUser接口的实现类 M_test.java
public class M_test implements IUser{
public static void main(String[] args) {
M_test mt = new M_test();
mt.SelectUserById();
// mt.SelectAllUser();
// mt.UpdateUserById();
// mt.UpdateAllUser();
// mt.SelectUserBylike();
// mt.InsertUser();
// mt.DeleteUser();
}
@Override
public User SelectUserById() {
SqlSession sqlSession = MJdbc.getSqlSession();
Object object = sqlSession.selectOne("mapper.mapper.selectUserById",2);
System.out.println(object);
return (User) object;
}
@Override
public void SelectAllUser() {
SqlSession sqlSession = MJdbc.getSqlSession();
List<Object> list = sqlSession.selectList("mapper.mapper.selectAllUser");
System.out.println(list);
sqlSession.close();
}
@Override
public void SelectUserBylike() {
SqlSession sqlSession = MJdbc.getSqlSession();
List<Object> list= sqlSession.selectList("mapper.mapper.selectUserBylike", "%b%");
System.out.println(list);
}
@Override
public void UpdateUserById() {
User user = new User();
user.setId(1);
user.setUsername("bao");
user.setAge(16);
SqlSession sqlSession = MJdbc.getSqlSession();
sqlSession.update("mapper.mapper.UpdateUserById",user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void UpdateAllUser() {
User user = new User();
user.setUsername("ba");
user.setAge(1);
SqlSession sqlSession = MJdbc.getSqlSession();
sqlSession.update("mapper.mapper.UpdateAllUser",user);
sqlSession.commit();
sqlSession.close();
}
@Override
public void InsertUser() {
User user = new User();
user.setId(7);
user.setUsername("11");
user.setAge(18);
SqlSession sqlSession = MJdbc.getSqlSession();
int adduser = sqlSession.insert("mapper.mapper.insertUser",user);
System.out.println(adduser);
sqlSession.commit();
sqlSession.close();
}
@Override
public void DeleteUser() {
SqlSession sqlSession = MJdbc.getSqlSession();
int uid = sqlSession.delete("mapper.mapper.deleteUser", 7);
System.out.println(uid);
}
(6).小结:
6.1 测试程序步骤:
a. 创建SqlSessionFactoryBuilder对象
b. 加载SqlMapConfig.xml配置文件
c. 创建SqlSessionFactory对象
d. 创建SqlSession对象
e. 执行SqlSession对象执行查询,获取结果User
f. 打印结果
g. 释放资源
6.2 #{}和${}区别:
#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。
${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value。
6.3 parameterType和resultType:
parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中
6.4 selectOne和selectList:
selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常:
org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 3
at org.apache.ibatis.session.defaults.DefaultSqlSession.selectOne(DefaultSqlSession.java:70)
selectList可以查询一条或多条记录。
Spring
Spring知识点
一、 专业术语
1. 侵入式设计
引入框架,对现有的类的结构有影响,即需要实现或继承某些特定类。如:Struts框架
2. 非侵入式设计
引入框架,对现有的类结构没有影响。如:Hibernate、Spring
3. 控制反转(IoC)
控制反转(Inversion on Control 、IoC):把对象的创建交给外部容器完成。
4. 依赖注入(DI)
依赖注入(dependency injection):处理对象间的依赖关系
5. IoC和DI的区别
控制反转:解决对象创建的问题【对象创建交给其他类】
依赖注入:解决类与类紧耦合的问题。
例如,类A依赖于类B,常规的做法是在A中直接创建B的对象,然后再调用B对象的方法;控制反转就是将创建B对象的实例化交给第三方实现;然后再创建类B的操作接口I,并在A中创建接口I的对象,最后再由第三方将B的实例注入给A中的接口I的对象。这样实例化B类对象的控制权就由A交给了第三方,同时也解决了类A和类B紧耦合的问题。
6. AOP
面向切面编程(Aspect Oriented Programming)是软件编程思想发展到一定阶段的产物,是面向对象编程的有益补充。AOP一般适用于具有横切逻辑的场合,如访问控制、事务管理、性能监测等。面向切面编程简单地说就是在不改变源程序的基础上为代码段增加新的功能,对代码段进行增强处理。
7. 横切逻辑
在业务系统中,总有一些散落、渗透到系统各处且不得不处理的事情,这些穿插在既定业务中的公共操作就是所谓的横切逻辑,也称为切面。
8. 增强处理
在目标方法执行前后进行的操作或执行的功能就是增强处理。
9. 切点
可以插入增强处理的目标方法就是所谓的切点。
二、 Spring简介
Spring框架可以解决对象创建以及对象之间依赖关系的一个轻量级框架。Spring是一个全面的、企业应用开发一站式的解决方案,Spring贯穿表现层、业务层、持久层。但是Spring仍然可以和其他的框架无缝整合。
三、 Spring Jar包介绍
1. org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现
2. org.springframework.asm——spring3.0开始提供自己独立的asm jar包
3. org.springframework.aspects——Spring提供的对AspectJ框架的整合
4. org.springframework.beans——所有应用都用到,包含访问配置文件,创建和管理bean等。
5. org.springframework.context.support——Spring context的扩展支持,用于MVC方面
6. org.springframework.context——提供在基础IOC功能上的扩展服务,此外还提供许多企业级服务的支持,有邮件服务、任务调度、JNDI定位,EJB集成、远程访问、缓存以及多种视图层框架的支持。
7. org.springframework.core——Spring的核心工具包,其他包依赖此包
8. org.springframework.expression——Spring表达式语言
9. org.springframework.instrument.tomcat——Spring对tomcat连接池的集成
10. org.springframework.instrument——Spring对服务器的代理接口
11. org.springframework.jdbc——对JDBC 的简单封装
12. org.springframework.jms——为简化jms api的使用而做的简单封装
13. org.springframework.orm——整合第三方的orm实现,如hibernate,ibatis,jdo,jpa等
14. org.springframework.oxm——Spring对于object/xml映射的支持,可以让JAVA与XML来回切换
15. org.springframework.test——对JUNIT等测试框架的简单封装
16. org.springframework.transaction——为JDBC,HIBERNATE,JDO,JPA提供一致的声明式和编程式事务管理
17. org.springframework.web.portlet——Spring MVC的增强
18. org.springframework.web.servlet——对J2EE6.0 servlet3.0的支持
19. org.springframework.web.struts——整合对struts框架的支持,更方便更容易的集成Struts框架。
20. org.springframework.web——包含Web应用开发时,用到Spring框架时所需的核心类。
21. Org.springframework.web.mvc——包含SpringMVC应用开发时所需的核心类。
注意:core、beans、expression、context是Spring的核心jar包。使用Spring时必须导入commons-logging-*.jar包。
@Aspect 返回值
public class After {
@AfterReturning(pointcut="execution(* com..*.*(..))",returning="ret")
public void doAfter(JoinPoint pjp,Object ret) {
System.out.println("目标程序与AOP程序执行后将最后执行,返回参数为" + ret);
}
异常通知注解方法:
@Component
@Aspect
public class ThrowException {
@AfterThrowing(pointcut="execution(* com..*.*(..))", throwing="e")
public void doThrow(JoinPoint jp , Throwable e) {
}
}
最终通知注解方法:
@Component
@Aspect
public class AfterFinally {
@After(value="execution(* com..*.*(..))")
public void afterFinally(JoinPoint jp) {
}
}
环绕通知注解方法:
@Component
@Aspect
public class Around {
@org.aspectj.lang.annotation.Around("execution(* com..*.*(..))")
public String around(ProceedingJoinPoint pjp) {
}
}
七、Spring集成工具类
Spring提供了JdbcTemple工具类,用于对jdbc的操作进行了轻量级别的封装。
优点:
直接使用sql语句操作数据库。
支持数据库的分区。
使用java语言拼sql语句。
使用spring集成jdbc包含如下几步:
导入集成包、连接池包。
初始化连接池数据源对象。
初始化JdbcTemplate对象。
调用JdbcTemplate的API接口完成数据库操作。
导入集成包、连接池包
org.springframework.jdbc-3.0.2.RELEASE.jar
该包封装并简化了jdbc的操作,JdbcTemplate就在此包内。
连接池包
com.springsource.com.mchange.v2.c3p0-0.9.1.2.jar c3p0连接池。
数据库驱动包
ojdbc6.jar /mysql-connector-java-5.1.40-bin.jar
初始化连接池数据源对象
初始化连接池数据源对象:
ComboPooledDataSource,该对象包含连接数据库的基本属性、连接池的配置属性。
初始化JdbcTemplate对象
通过spring的依赖注入设定Dao类继承的dataSource属性
<bean id="jdbcDao" class="org.springframework.jdbc.core.JdbcTemplate" >
<property name="dataSource" ref="datasource"></property>
</bean>
完整配置
spring集成jdbc
//数据的增删改查
* jdbcTemplate.update("insert into users(id,uname,password)value(?,?,?)", "1","啦啦","123");
jdbcTemplate.update("delete from users where id = ? ", 13);
jdbcTemplate.update("update users set uname=? ,password=? where id=?", "aaa","111",1);
//查询数据
List<Users> list = jdbcTemplate.query("select * from users where id = 1", new RowMapper<Users>(){
@Override
public Users mapRow(ResultSet res, int arg1) throws SQLException {
System.out.println(arg1);
Users users = new Users();
users.setId(res.getInt("id"));
users.setUname(res.getString("uname"));
users.setPassword(res.getString("password"));
return users;
}});
for (Users i : list) {
System.out.println(i);
}
查询数据(根据uname):
Users users = jdbcTemplate.query("select * from users where uname = ?", new Object[]{"aaa"}, new ResultSetExtractor<Users>(){
@Override
public Users extractData(ResultSet reSet) throws SQLException, DataAccessException {
if(reSet.next()){
Users users = new Users();
users.setId(reSet.getInt("id"));
users.setPassword(reSet.getString("password"));
System.out.println(users);
return users;
}
return null;
}
});
八、jdbc的事物控制
事物的四大特性:
atomic(原子性):要么都发生,要么都不发生。
consistent(一致性):数据应该不被破坏。
isolate(隔离性):用户间操作不相混淆
durable(持久性):永久保存,例如保存到数据库中等
声明式事务管理
spring的事务管理器: spring没有直接管理事务,只是开发了事物管理器调用第三方组件完成事物控制。
READ_COMMITTED允许在并发事务已经提交后读取。
REPEATABLE_READ 对相同字段的多次读取是一致的,除非数据被事务本身改变。
SERIALIZABLE完全服从ACID的隔离级别。这在所有的隔离级别中是最慢的,它是典型的通过完全锁定在事务中涉及的数据表来完成的。
隔离级别 | 脏读 | 非重复读 | 幻像读 |
read uncommitted | 允许 | 允许 | 允许 |
read committed |
| 允许 | 允许 |
repeatable read |
|
| 允许 |
serializable |
|
|
|
8.1、使用Spring声明式 事物控制 分为如下几个部分:
1、配置事物控制管理器:jdbc的事物控制管理器为DataSourceTransactionManager
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="datasource"></property>
</bean>
2、配置事物通知:配置哪些函数(方法)委托spring进行事物管理,以及事物管理的隔离级别、传播行为、是否只读事物属性。
<tx:advice id="transaction" transaction-manager="transactionManager">
<tx:attributes>
<tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED" read-only="false"/>
</tx:attributes>
</tx:advice>
3、配置事物的切入点:也就是spring的哪些组件要配置事物通知(建议放在service层)。
<aop:config>
<aop:pointcut expression="execution(* com.service.*.*(..))" id="point"/>
<aop:advisor advice-ref="transaction" pointcut-ref="point"/>
</aop:config>
8.2、使用注解完成事物控制
1、扫描包:
<context:component-scan base-package="com.dao"></context:component-scan>
<context:component-scan base-package="com.service"></context:component-scan>
2、写一个Dao类
UserDa.java 类
@Component
public class UserDao {
@Autowired
JdbcTemplate jTemplate;
public int insertUser(Users user){
return jTemplate.update("insert into
users(id,uname,password)value(?,?,?)",
user.getId(),user.getUname(),user.getPassword());
}
3、写一个Service类
UserService .java
@Service
public class UserService {
@Autowired
UserDao userdao;
public int addUser(Users user){
return userdao.insertUser(user);
}
}
4.测试类
DataSourceTransactionManager dataSourceTransactionManager =
new DataSourceTransactionManager();
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("springconfig.xml");
UserService usService = (UserService) applicationContext.getBean("userService");
usService.addUser(new Users(100,"aa","123"));
applicationContext.close();
}
}
SpringMVC
一、 基本概念
1. Spring Web MVC是什么
Spring Web MVC是一种基于Java的实现了Web MVC设计模式的请求驱动类型的轻量级Web框架,即使用了MVC架构模式的思想,将web层进行职责解耦,基于请求驱动指的就是使用请求-响应模型,框架的目的就是帮助我们简化开发。
2. Spring Web MVC能帮我们做什么
l 清晰的角色划分:控制器(controller)、模型对象(model object)、Servlet分发器(DispatcherServlet)、处理器映射(handler mapping)、视图解析器(view resolver)等等。
每一个角色都可以由一个专门的对象来实现。
强大而直接的配置方式:将框架类和应用类都作为JavaBean配置,支持在一个context中引用其他context的中JavaBean。
可适配、非侵入的controller:你可以根据不同的应用场景,选择合适的控制器子类。
可重用的业务代码:你可以使用现有的业务对象作为命令或表单对象,而不需要在类似ActionForm的子类中重复它们的定义。
可定制的绑定(binding) 和验证(validation):比如将类型不匹配作为应用级的验证错误,这可以保存错误的值。再比如本地化的日期和数字绑定等等。在其他某些框架中,你只能使用字符串表单对象,需要手动解析它并转换到业务对象。
可定制的handler mapping和view resolution:Spring提供从最简单的的URL映射,到复杂的、专用的定制策略。与某些MVC框架强制开发人员使用单一特定技术相比,Spring显得更加灵活。灵活。
灵活的model转换: 在Springweb框架中,使用基于Map的名/值对来达到轻易地与各种视图技术的集成。
可定制的本地化和主题(theme)解析:支持在JSP中可选择地使用Spring标签库、支持JSTL、支持Velocity(不需要额外的中间层)等等。
3. Spring Web MVC架构
Spring Web MVC框架也是一个基于请求驱动的Web框架,并且也使用了前端控制器模式来进行设计,再根据请求映射规则分发给相应的页面控制器(动作/处理器)进行处理。
首先用户发送请求 ——> DispatcherServlet
前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
DispatcherServlet ——> HandlerMapping
HandlerMapping将会把请求映射为HandlerExecutionChain对象(包含一个Handler处理器(页面控制器)对象、多个HandlerInterceptor拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
DispatcherServlet ——> HandlerAdapter
HandlerAdapter将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
HandlerAdapter ——> 处理器功能处理方法的调用,
HandlerAdapter将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView对象(包含模型数据、逻辑视图名);
ModelAndView的逻辑视图名——> ViewResolver
ViewResolver将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
View——>渲染
View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
返回控制权给DispatcherServlet
由DispatcherServlet返回响应给用户,到此一个流程结束。
二、 Spring Web MVC入门代码
1. 先配置web.xml,加入代码
<servlet>
<servlet-name>servletMVC</servlet-name>
<servlet-class>
org.springframework.web.servlet.DispatcherServlet
</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>servletMVC</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
2. 配置servletMVC.xml的Spirng配置文件
3. 编写HelloController控制器
创建的类没用注解的情况下必须继承AbstractController抽象类
4. 编写一个lxt.jsp的页面
在页面上加${message } EL表达式
5. 然后通过在浏览器上输入url进行访问
http://localhost:8080/项目名/hello.do
6. 注意点
默认DispatcherServlet会加载WEB-INF/[DispatcherServlet的Servlet名字]-servlet.xml配置文件。如果想加载其他地方的spring mvc 配置文件,则web.xml中进行如下配置:
ModelAndView类的构造方法:有三个参数:
1:需要通过某个view进行显示
2:传递过去的name
3:name对应的value
7. 执行流程
三、 Spring MVC 的三种常用的HandlerMapping
handlerMapping的工作就是为每个请求找到合适的处理器java类。
1. BeanNameUrlHandlerMapping
通过url名称来映射处理请求的Handler
这个是默认Handler,官方推荐使用
<!-- HandlerMapping -->
<bean class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping" />
<!-- 控制器 -->
<bean id="/hello.do" class="com.mvc.HelloController" />
<!--根据url来找到相对的bean。根据bean给出的类去执行处理请求。-->
2. SimpleUrlHandlerMapping
通过bean名称来映射处理请求的Handler
<bean id="simpleUrlHandlerMapping"
class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
<property name="mappings">
<props>
<prop key="/hello.do">helloController</prop>
<prop key="/hello1.do">hello1Controller</prop>
</props>
</property>
</bean>
<bean id="helloController" class="com.mvc.HelloController" />
<bean id="hello1Controller" class="com.mvc.Hello1Controller" />
<!-- 根据<prop key=“/hello.do”>helloController</prop>的设置来找到相应的 bean-->
3. ControllerClassNameHandlerMapping
通过url名称来自动映射符合条件的Handler
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping" />
<!– 会匹配符合条件的Controller
如:XxxxxController的后缀Controller去掉并将字符改成小写-->
<!– 如果请求是hello 就会匹配 HelloController -->
<!– 如果请求是hello11 也会匹配 HelloController -->
因为存在不确定性,所以不推荐使用。
四、 Spring MVC 注解解析
首先先开启自动扫描
1. @Controller
注解表明了一个类是作为控制器的角色而存在的。Spring不要求你去继承任何控制器基类,也不要求你去实现Servlet的那套API。当然,如果你需要的话也可以去使用任何与Servlet相关的特性和设施。
@Controller注解可以认为是被标注类的原型(stereotype),表明了这个类所承担的角色。分派器(DispatcherServlet)会扫描所有注解了@Controller的类,检测其中通过@RequestMapping注解配置的方法。
当然,你也可以不使用@Controller注解而显式地去定义被注解的bean,这点通过标准的Spring bean的定义方式,在dispather的上下文属性下配置即可做到。但是@Controller原型是可以被框架自动检测的,Spring支持classpath路径下组件类的自动检测,以及对已定义bean的自动注册。
2. @RequestMapping
你可以使用@RequestMapping注解来将请求URL,如/appointments等,映射到整个类上或某个特定的处理器方法上。
一般来说,类级别的注解负责将一个特定(或符合某种模式)的请求路径映射到一个控制器上,同时通过方法级别的注解来细化映射,即根据特定的HTTP请求方法(“GET”“POST”方法等)、HTTP请求中是否携带特定参数等条件,将请求映射到匹配的方法上。
类级别的@RequestMapping注解并不是必须的。不配置的话则所有的路径都是绝对路径,而非相对路径。