十年架构师,带你初识SSM框架结构,深入开发Java就在今天

134 篇文章 1 订阅
38 篇文章 0 订阅

SSM(Spring+SpringMVC+MyBatis)框架集由Spring、MyBatis两个开源框架整合而成(SpringMVC是Spring中的部分内容)。常作为数据源较简单的web项目的框架。今天,咱们就在一起认识学习SSM架构。

Spring框架

Spring框架是Java应用最广的框架。它的成功来源于理念,而不是技术本身,它的理念包括IoC(Inversion of Control,控制反转)和AOP (Aspect Oriented Programming,面向切面编程)。

Spring loC简介

IoC是一个容器,在Spring中,它会认为--切Java资源都是JavaBean,容器的目标就是管理这些Bean和它们之间的关系。所以在Spring IoC里面装载的各种Bean,也可以理解为Java的各种资源,包括Java Bean 的创建、事件、行为等,它们由IoC容器管理。除此之外,各个JavaBean之间会存在一定的依赖关系,比如班级是依赖于老师和学生组成的,假设老师、学生都是Java Bean,那么显然二者之间形成了依赖关系,老师和学生有教育和被教育的关系。这些Spring IoC容器都能够对其进行管理。只是Spring IoC管理对象和其依赖关系,采用的不是人为的主动创建,而是由Spring IoC自己通过描述创建的,也就是说Spring是依靠描述来完成对象的创建及其依赖关系的。

比如插座,它依赖国家标准(这个标准可以定义为一个接口,Socket) 去定义,现有两种插座( Socket1和Socket2),如下图所示。

有两种插座可供选择,具体使用哪种呢?我们可以通过代码来实现使用插座1(Socket1)。

Socket socket= new Socket1() ; user. setSocket (socket) ; user. useSocket () ;

使用Socket socket = new Socket10);后,国家标准插座接口( Socket)就和插座1( Socket1)捆绑在一起了。这样就会有一个弊端:如果要使用其他的插座,就需要修改代码了。这种情况Socket接口和其实现类Socketl 耦合了,如果有一天不再使用Socketl,而是要使用Socket2,那么就要把代码修改为以下示例。

Socket socket = new Socket2 () ; user. setSocket (socket) ; user. useSocket() ;

如果有其他更好的插座,岂不是还要修改源码?一个大型互联网的对象成千上万,如果要不断修改,那么对系统的可靠性将是极大的挑战,Spring IoC可以解决这个问题。首先,我们不用new的方式创建对象,而是使用配置的方式,然后让Spring IoC容器自己通过配置去找到插座。先用一段XML描述插座和用户的引用插座1,如下

<bean id="socket" class="Socket1"/> <bean id="user" class="xxx.User"> <property name="socket" ref="socket"/> < /bean>

请注意这些不是Java代码,而是XML配置文件,换句话说只要把配置切换为:

<bean id=“scocket”class="Socket2">

就可以往用户信息中注入插座2,切换插座的实现类十分方便。这个时候Socket接口就可以不依赖任何插座,而通过配置进行切换,如下图所示。

 

上图的配置信息是“我要插座2”,相当于XML依赖关系配置,这个时候Spring IoC只会拿到插座2,然后通过国家标准插座接口注入给使用者,提供给使用者使用。换句话说,这是一种被动的行为,而需要的资源( Bean)通过描述信息就可以得到,其中的控制权在Spring IoC容器中,它会根据描述找到使用者需要的资源,这就是控制反转的含义。

这样的好处是Socket接口不再依赖于某个实现类,需要使用某个实现类时我们通过配置信息就可以完成了。这样想修改或者加入其他资源就可以通过配置完成,不需要再用new关键字进行创建对象,依赖关系也可以通过配置完成,从而完全可以即插即拔地管理它们之间的关系。

你不需要去找资源,只要向Spring loC容器描述所需资源,Spring IoC自己会找到你所需要的资源,这就是Spring IoC的理念。这样就把Bean之间的依赖关系解耦了,更容易写出结构清晰的程序。除此之外,Spring IoC还提供对Java Bean生命周期的管理,可以延迟加载,可以在其生命周期内定义一些行为等,更加方便有效地使用和管理Java资源,这就是Spring IoC的魅力。

Spring AOP

IoC的目标就是为了管理Bean,而Bean是Java面向对象(OOP)的基础设计,比如声明一个用户类、插座类等都是基于面向对象的概念。

有些情况是面向对象没办法处理的。举个例子,生产部门的订单、生产部门、财务部门三者符合OOP的设计理念。订单发出,生产部门审批通过准备付款,但是财务部门发现订单的价格超支了,需要取消订单。显然超支限定已经不只是影响财务部门了,还会影响生产部门之前所做的审批,需要把它们作废。我们把预算超支这个条件称为切面,它影响了订单、生产部门和财务部门3个OOP对象。在现实中,这样的切面条件跨越了3个甚至更多的对象,并且影响了它们的协作。所以只用OOP并不完善,还需要面向切面的编程,通过它去管理在切面上的某些对象之间的协作,如下图所示。

 

在上图中,实线是订单提交的流程,虚线是订单驳回的流程,影响它们的条件是预算超额,这是一个切面条件。

Spring AOP常用于数据库事务的编程,很多情况都如同上面的例子,我们在做完第一步数据库数据更新后,不知道下一步是否会成功,如果下一步失败,会使用数据库事务的回滚功能去回滚事务,使得第- 步的数据库更新也作废。在Spring AOP实现的数据库事务管理中,是以异常作为消息的。在默认的情况下(可以通过Spring的配置修改),只要Spring接收到了异常信息,它就会将数据库的事务回滚,从而保证数据的一致性。 这样我们就知道在Spring的事务管理中只要让它接收到异常信息,它就会回滚事务,而不需要通过代码来实现这个过程。比如上面的例子,可用一段伪代码来进行一些必要的说明,

/★* * Spring AOP处理订单伪代码 k @param order订单 **/ private void proceed (Order order) { //判断生产部门是否通过订单,数据库记录订单 boolean pflag = productionDept.isPass (order); if(pflag) {//如果生产 部门通过进行财务部门审批 if (financialDept. isOverBudget (order)) {//财 务审批是否超限 //抛出异常回滚事务,之前的订单操作也会被回滚 throw new RuntimeException ("预算超限!! "); } } }

这里我们完全看不到数据库代码,也没有复杂的try...catch...finally...语句。在现实中,Spring AOP的编程也是如此,这些东西都被Spring屏蔽了,不需要关注它,只需关注业务代码,知道只要发生了异常,Spring 会回滚事务就足够了。当然这段话还不算准确,因为事务和业务是十分复杂的,但是Spring已经提供了隔离级别和传播行为去控制它们,只是在入门的章节没有必要谈得如此复杂,后面会详细剖析它们,有了Spring的这些封装,开发人员就可以减少很多的代码和不必要的麻烦。

MyBatis简介

MyBatis的前身是Apache的开源项目iBatis。iBatis 一词来源于“internet”和“abatis"的组合,是一个基于Java的持久层框架。2010年这个项目由Apache software foundation迁移到Google code,并更名为MyBatis。2013 年11月,MyBatis 迁移到GitHub上,目前由GitHub提供维护。

MyBatis的优势在于灵活,它几乎可以代替JDBC,同时提供了接口编程。目前MyBatis的数据访问层DAO(DataAccessObjects)是不需要实现类的,它只需要一个接口和XML(或者注解)。MyBatis提供自动映射、动态SQL、级联、缓存、注解、代码和SQL分离等特性,使用方便,同时也可以对SQL进行优化。因为其具有封装少、映射多样化、支持存储过程、可以进行SQL优化等特点,使得它取代了Hibernate 成为了Java互联网中首选的持久框架。

Hibernate简介

要将POJO和数据库映射起来需要给这些框架提供映射规则,所以下一步要提供映射的规则,如下图所示。

 

在MyBatis或者Hibernate 中可以通过XML或者注解提供映射规则,这里讨论的是XML方式,因为在MyBatis中注解方式会受到一定的限制,所以MyBatis通常使用XML方式实现映射关系。

我们把POJO对象和数据库表相互映射的框架称为对象关系映射(Object Relational Mapping, ORM, 或O/RM,或O/R mapping) 框架。无论MyBatis或者Hibemate都可以称为ORM框架,只是Hibermate的设计理念是完全面向POJO的,而MyBatis 则不是。Hibermate基本不再需要编写SQL就可以通过映射关系来操作数据库,是一种全表映射的体现;而MyBatis则不同,它需要我们提供SQL去运行。

Hibernate是将POJO和数据库表对应的映射文件,如下图。

<?xml version="1.0"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0/ /EN" "http://www. hibernate.org/dtd/hibernate -mapping-3.0.dtd"> <hibernate-mapping> <class name=" com. learn. chapterl.pojo.Role" table="t_ role"> <id name="id" type= "java. lang . Integer"> <column name="id" /> <generator class="identity" /> </id> <property name="roleName" ' type="string">. <column name="role_ name" length="60" not-null="true" /> </property> <property name= "note" type="string"> 运 <column name="note" length="512" /> aits8yM </property> </class> </hibernate-mapping>

首先,对POJO和表t role 进行了映射配置,把两者映射起来了。然后,对POJO进行操作,从而影响t role 表的数据,比如对其增、删、查、改可以按照如所示方式操作。

Session session = null; Transaction tx = null; try { //打开Session session = HibernateUtil. getSessionFactory()。openSession(); //事务 tx = session. beginTransaction() ; / /POJO Role role = new Role() ; role.setId(1) ; role. setRoleName ("rolename1") ; role. setNote ("note1") ; session.save (role);//保存 Role role2 = (Role) session.get (Role.class, 1) ;//查询 role2. setNote ("修改备注") ; session. update (role2);//更新 System. err . println (role2. getRoleName ()) ; session.delete (role2) ; //删除 tx.commit();//提交事务 } catch I (Exception ex) { if (tx,!= null && tx.isActive()) { tx. rollback();//回滚事务 } ex.printStackTrace() ; } finally { if" (session != null && t session.isOpen()) session.close () ; } }

MyBatis

在移动互联网时代,MyBatis成为了目前互联网Java持久框架的首选,与Hibernate消除SQL不同,MyBatis 不屏蔽SQL。不屏蔽SQL的优势在于,程序员可以自己制定SQL规则,无须Hibernate自动生成规则,这样能够更加精确地定义SQL,从而优化性能。它更符合移动互联网高并发、大数据、高性能、高响应的要求。

显然MyBatis在业务逻辑上和Hibermate是大同小异的。其区别在于,MyBatis 需要提供接口和SQL,这意味着它的工作量会比Hibernate大,但是由于自定义SQL、映射关系,

所以其灵活性、可优化性就超过了Hibernate。 互联网可优化性、灵活性是十分重要的,因为一条SQL的性能可能相差十几倍到几十倍,这对于互联网系统是十分重要的。

Hibernate和MyBatis的区别

Hibernate和MyBatis的增、删、查、改,对于业务逻辑层来说大同小异,对于映射层而言Hibernate的配置不需要接口和SQL,相反MyBatis 是需要的。对于Hibernate而言,不需要编写大量的SQL,就可以完全映射,同时提供了日志、缓存、级联(级联比MyBatis强大)等特性,此外还提供HQL (Hibermate Query Language)对POJO进行操作,使用十分方便,但是它也有致命的缺陷。

由于无须SQL,当多表关联超过3个的时候,通过Hibermate的级联会造成太多性能的丢失,又或者我现在访问一个财务的表,然后它会关联财产信息表,财产又分为机械、原料等,显然机械和原料的字段是不-样的,这样关联字段只能根据特定的条件变化而变化,而Hibernate无法支持这样的变化。遇到存储过程,Hibernate只能作罢。更为关键的是性能,在管理系统的时代,对于性能的要求不是那么苛刻,但是在互联网时代性能就是系统的根本,响应过慢就会丧失客户,试想一下谁会去用一个经常需要等待超过10秒以上的应用呢?

以上的问题MyBatis都可以解决,MyBatis 可以自由书写SQL、支持动态SQL、处理列表、动态生成表名、支持存储过程。这样就可以灵活地定义查询语句,满足各类需求和性能优化的需要,这些在互联网系统中是十分重要的。

但MyBatis也有缺陷。首先,它要编写SQL和映射规则,其工作量稍微大Hibernate。其次,它支持的工具也很有限,不能像Hibernate那样有许多的插件可以帮助生成映射代码和关联关系,而即使使用生成工具,往往也需要开发者进一步简化,MyBatis 通过手工编码,工作量相对大些。所以对于性能要求不太苛刻的系统,比如管理系统、ERP 等推荐使用Hibernate;而对于性能要求高、响应快、灵活的系统则推荐使用MyBatis。

Spring MVC简介

长期以来Struts2与Spring的结合一直存 在很多的问题,比如兼容性和类臃肿。加之近年来Struts2漏洞问题频发,导致使用率大减。与此同时,生于Spring Web项目的MVC (Model View Cortrller)框架走到了我们的面前,Spring MVC结构层次清晰,类比较简单,并且与Spring的核心IoC和AOP无缝对接,成为了互联网时代的主流框架。

MVC模式把应用程序(输入逻辑、业务逻辑和UI逻辑)分成不同的方面,同时提供这些元素之间的松耦合。

Model (模型),封装了应用程序的数据和由它们组成的POJO。View (视图),负责把模型数据渲染到视图上,将数据以一定的形式展现给用户。Controller (控制器),负责处理用户请求,并建立适当的模型把它传递给视图渲染。在SpringMVC中还可以定义逻辑视图,通过其提供的视图解析器就能够很方便地找到对应的视图进行渲染,或者使用其消息转换的功能,比如在Controller的方法内加入注解@ResponseBody后,Spring MVC就可以通过其消息转换系统,将数据转换为JSON,提供给前端Ajax请求使用。

Spring MVC中的重点在于它的流程和一些重要的注解,包括控制器、视图解析器、视图等重要内容。


以上就是小编整理的SSM框架简介,只是个人的一些浅见,有哪里不准确的地方,还请各位大佬多多指出,咱们共同学习交流~~~

喜欢文章请多多点赞评论转发,关注小编,你们的指出支持就是小编最大的动力~~~

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值