Servlet:
什么是Servlet
1. Servlet(Java 服务器小程序)是用Java编写的服务器程序,是由服务器调用和执行的,按照Servlet自身规范编写的Java类。Servlet可以看成是用Java编写的CGI。但是它的功能和性能比CGI更加强大。 Servlet是使用Java Servlet应用程序设计接口(API)及相关类和方法的Java程序。除了Java Servlet API,Servlet还可以使用用于扩展和添加到API的Java类软件包。
Servlet技术的特点
Servlet带给开发人员最大的好处是它可以处理客户端传来的HTTP请求,并返回一个响应。Servlet是一个Java的类,Java语言能够实现的功能,Servlet基本上都能实现(除了图形界面外)。 Servlet有以下优势
a. 可移植 因为Servlet由Java开发并符合规范定义和广泛接收的API,它可以再不提的操作系统平台和不同的应用服务器平台下移植。
b. 功能强大 Servlet可以使用Java API核心的所有功能,这些功能包括Web和URL访问、图像处理、数据压缩、多线程、JDBC和序列化对象等。
d. 简洁 Servlet代码面向对象,在封装方面具有先天的优势。
e. 集成 Servlet和服务器紧密集成,它们可以密切合作完成特定的任务。
f. 模块化 每一个Servlet可以执行一个特定任务,并且可以讲他们并在一起工作。Servlet之间是可以相互交流的
g. 扩展性和灵活性 Servlet本身的接口设计得非常精简,使得它有很强的扩展性。需要指出的是,Servlet不等于HttpServlet,后者是前者的一个常见扩展。
h. 高效耐久 Servlet一旦载入,它就驻留在内存中,这样加快了响应的速度。在服务器上仅有一个Java虚拟机在运行,它的优势在于,当Servlet被客户端发送的第一个请示激活,以后它将继续运行于后台,等待以后的请求。每个请求将生成一个线程而不是进程。
servlet使用不便之处
servlet具有容器依赖性,不利于单元测试;
servlet处理的请求很局限,一个<url-pattern>,多个请求访问同一个servlet的时候业务处理不方便,或者需要编写多个servlet。但是可以通过传递需要调用的方法作为参数使用反射再来调用相对应的方法
struts2:
面向切面编程的思想在Strut2中也有了很好的体现。最重要的体现就是拦截器的使用。拦截器就是一个一个的小功能单位,用户可以将这些拦截器合并成一个大的拦截器,也就是拦截器栈。只要配置为默认。所有action都可以使用
这些拦截器使用struts2相对servlet
1.参数封装更方便。可以使用属性驱动或者模型驱动实现。
2.文件上传只需要注意form表单的要求。提供对应的file属性和fileName即可完成文件上传
3.其拦截器封装了国际化和输入校验功能,实现更简洁。编写响应配置文件即可。但是使用较少。校验使用JS代码校验给用户体验更好。例如信息的效果展示。
4.获取servletAPI更加简便。可以直接使用ActionContext.getContext()/getSession()/getApplication().操作相应的域。也可以直接使用servletActionContext.getRequest()/getResponse()/getServletContext()来操作
5. 基于MVC架构,框架结构清晰,开发过程中只需要关注业务层的数据获取封装到对应的POJO中再根据对应的result返回到对应的view展示。
6.struts2拥有独自的一套taglib标签库。从struts2的值栈获取数据使用非常方便。但是该标签与struts2框架耦合紧密。如果需要项目改造页面改动将十分麻烦。工作量巨大。
7。struts2的action是多实例的,因此再与spring整合的时候需要配置为多例。否则值栈数据会混乱。action和页面取值将会错误
springMVC
- 用户发送请求至前端控制器DispatcherServlet
- DispatcherServlet收到请求调用HandlerMapping处理器映射器。
- 处理器映射器根据请求url找到具体的处理器,生成处理器对象及处理器拦截器(如果有则生成)一并返回给DispatcherServlet。
- DispatcherServlet通过HandlerAdapter处理器适配器调用处理器
- 执行处理器(Controller,也叫后端控制器)。
- Controller执行完成返回ModelAndView
- HandlerAdapter将controller执行结果ModelAndView返回给DispatcherServlet
- DispatcherServlet将ModelAndView传给ViewReslover视图解析器
- ViewReslover解析后返回具体View
- DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)。
- DispatcherServlet响应用户
truts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入
struts2实际上是通过setter getter方法与request打交道的
struts2中,一个Action对象对应一个request上下文
spring3 mvc不同,spring3mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去
在spring3mvc中,一个方法对应一个request上下文
spring3mvc的方法之间基本上独立的,方法之间不共享变量 ,
而struts2虽然方法之间也是独立的,但Action变量是共享的
这不会影响程序运行,却给我们编码 读程序时带来麻烦
由于Struts2需要针对每个Request进行封装,把Request,Session等Servlet生命周期的变量封装成一个一个Map,供给每个Action使用,并保证线程安全。所以在原则上,是比较耗费内存的
网上有说struts2效率比springmvc低。这是事实。证明的方法是通过大量数据的访问测试时间得出。这种做法不够科学。如果问到为什么效率高。我们可以从struts2多实例这点来回答
spring
spring的核心
IOC:控制反转,对象的创建交给容器创建。使用反射技术实现。然后通过内省注入依赖的属性值
AOP:面向切面编程,采用jdk或者cglib动态代理实现,对目标类的方法进行增强。传统的目标方法增强可以采用继承、装饰者、和动态代理。
AOP的应用场景: 权限、事物、日志、
spring的好处:
方便解耦,简化开发
Spring就是一个大工厂,可以将所有对象创建和依赖关系维护(IOC),交给Spring管理,其实spring里面管理bean的方式就是一个map key是ID value是 class 获取bean对象根据ID找到class的字符串类路径发射生成对象。
AOP编程的支持
Spring提供面向切面编程,可以方便的实现对目标方法的增强。例如常用的权限拦截、运行监控等(异常拦截)功能
JDBC
代码实例:
- Class.forName(“com.mysql.jdbc.Driver”);//注册驱动
- String url = “jdbc:mysql://localhost:3306/mydb1”;
- String username = “root”;
- String password = “123”;
- Connection con = DriverManager.getConnection(url, username, password);//获取连接
public void login(String username, String password) {
Connection con = null;
Statement stmt = null;
ResultSet rs = null;
try {
con = JdbcUtils.getConnection();
stmt = con.createStatement();
String sql = "SELECT * FROM user WHERE " +
"username='" + username +
"' and password='" + password + "'";
rs = stmt.executeQuery(sql);
if(rs.next()) {
System.out.println("欢迎" + rs.getString("username"));
} else {
System.out.println("用户名或密码错误!");
}
} catch (Exception e) {
throw new RuntimeException(e);
} finally {
JdbcUtils.close(con, stmt, rs);
}
}
PreparedStatement的使用
String sql = “select * from tab_student where s_number=?”; PreparedStatement pstmt = con.prepareStatement(sql); pstmt.setString(1, “S_1001”); ResultSet rs = pstmt.executeQuery(); rs.close(); pstmt.clearParameters(); pstmt.setString(1, “S_1002”); rs = pstmt.executeQuery(); |
在得到PreparedStatement对象后,调用它的setXXX()方法为“?”赋值,这样就可以得到把模板变成一条完整的SQL语句,然后再调用PreparedStatement对象的executeQuery()方法获取ResultSet对象。
注意PreparedStatement对象独有的executeQuery()方法是没有参数的,而Statement的executeQuery()是需要参数(SQL语句)的。因为在创建PreparedStatement对象时已经让它与一条SQL模板绑定在一起了,所以在调用它的executeQuery()和executeUpdate()方法时就不再需要参数了
PreparedStatement最大的好处就是在于重复使用同一模板,给予其不同的参数来重复的使用它。这才是真正提高效率的原因
PreparedStatement的好处:
- 防止SQL攻击;
- 提高代码的可读性,以及可维护性;
- 提高效率。
jdbc的问题
1、数据库连接频繁的创建和关闭,缺点浪费数据库的资源,影响操作效率
设想:使用数据库连接池
2、sql语句是硬编码,如果需求变更需要修改sql,就需要修改java代码,需要重新编译,系统不易维护。
设想:将sql语句 统一配置在文件中,修改sql不需要修改java代码。
3、通过preparedStatement向占位符设置参数,存在硬编码( 参数位置,参数)问题。系统不易维护。
设想:将sql中的占位符及对应的参数类型配置在配置文件中,能够自动输入 映射。
4、遍历查询结果集存在硬编码(列名)。封装麻烦。
设想:自动进行sql查询结果向java对象的映射(输出映射)。
hibernate与mybatis
1.两者最大的区别:
针对简单逻辑,Hibernate和MyBatis都有相应的代码生成工具,可以生成简单基本的DAO层方法。
针对高级查询,Mybatis需要手动编写SQL语句,以及ResultMap。而Hibernate有良好的映射机制,开发者无需关心SQL的生成与结果映射,可以更专注于业务流程。
2.开发难度对比
Hibernate的开发难度要大于Mybatis。主要由于Hibernate比较复杂、庞大,学习周期较长。
而Mybatis则相对简单一些,并且Mybatis主要依赖于sql的书写,让开发者感觉更熟悉。
3.sql书写比较
Mybatis的SQL是手动编写的,所以可以按需求指定查询的字段。不过没有自己的日志统计,所以要借助log4j来记录日志。
Hibernate也可以自己写SQL来指定需要查询的字段,但这样就破坏了Hibernate开发的简洁性。不过Hibernate具有自己的日志统计。
4.数据库扩展性比较
Mybatis由于所有SQL都是依赖数据库书写的,所以扩展性,迁移性比较差。
Hibernate与数据库具体的关联都在XML中,所以HQL对具体是用什么数据库并不是很关心。
总结:
Hibernate与MyBatis都可以是通过SessionFactoryBuider由XML配置文件生成SessionFactory,然后由SessionFactory 生成Session,最后由Session来开启执行事务和SQL语句。
而MyBatis的优势是MyBatis可以进行更为细致的SQL优化,可以减少查询字段,并且容易掌握。
Hibernate的优势是DAO层开发比MyBatis简单,Mybatis需要维护SQL和结果映射。数据库移植性很好,MyBatis的数据库移植性不好,不同的数据库需要写不同SQL。有更好的二级缓存机制,可以使用第三方缓存。MyBatis本身提供的缓存机制不佳。
MVC
MVC全名是Model View Controller,是模型(model)-视图(view)-控制器(controller)的缩写,一种软件设计典范,用一种业务逻辑、数据、界面显示分离的方法组织代码,将业务逻辑聚集到一个部件里面,在改进和个性化定制界面及用户交互的同时,不需要重新编写业务逻辑。
M是指业务模型,V是指用户界面,C则是控制器,使用MVC的目的是将M和V的实现代码分离,从而使同一个程序可以使用不同的表现形式。比如一批统计数据可以分别用柱状图、饼图来表示。C存在的目的则是确保M和V的同步,一旦M改变,V应该同步更新