使用ssh框架的目的:
将典型的J2EE结构,分为表现层、中间层(业务逻辑层)和数据服务层。三层体系将业务规则、数据访问及合法性校验等工作放在中间层处理。客户端不直接与数据库交互,而是通过组件与中间层建立连接,再由中间层与数据库交互。
一 struts2的核心与工作原理
在学习struts2之前,首先我们要明白使用struts2的目的是什么?它能给我们带来什么样的好处?
设计目标
Struts设计的第一目标就是使MVC模式应用于web程序设计。
mvc的好处:
利于批量生产、规模生产、相互协作、推广普及。
mvc的坏处:
不利个案创作、独立创作、难艺术化、难个性化。
技术优势
Struts2有两方面的技术优势,一是所有的Struts2应用程序都是基于client/server HTTP交换协议,The JavaServlet API揭示了Java Servlet只是Java API的一个很小子集,这样我们可以在业务逻辑部分使用功能强大的Java语言进行程序设计。
二是提供了对MVC的一个清晰的实现,这一实现包含了很多参与对所以请求进行处理的关键组件,如:拦截器、OGNL表达式语言、堆栈。
因为struts2有这样目标,并且有这样的优势,所以,这是我们学习struts2的理由,下面,我们在深入剖析一下struts的工作原理。
工作原理
Suruts2的工作原理可以用下面这张图来描述:
一个请求在Struts2框架中的处理大概分为以下几个步骤 :
1、客户端初始化一个指向Servlet容器(例如Tomcat)的请求
2、这个请求经过一系列的过滤器(Filter)
这个Filter 启动须要在在wed.xml配置文件里配置,配置详情如下:(注:前提要导入struts2的相关jar包)
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
配置了Filter后,就会读struts.xml配置文件 ,根据struts.xml配置文件找到对应的Action 并实例化该Action 调用其方法execute();
struts.xml配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN" "http://struts.apache.org/dtds/struts-2.3.dtd"> <struts> <package name="mypac" extends="struts-default"> <action name="index" class= "action.IndexAction" method="execute"> <result name="success">/index.jsp</result> <result name="error">/error.jsp</result> </action> </package> </struts>
<result name="success">/index.jsp</result>
<result name="error">/error.jsp</result>
调用其方法execute()后,就会返回一个字符串,根据对应的字符串找到对应的页面,返回给客户端(注:上面红色字体就是要和execute()返回的字符串相同才会找到对应页面)
Struts2的总结:
struts2给我的带来的好处如下:
1.获取表单内容,并组织生成参数对象2.根据请求的参数转发请求给适当的控制器3.在控制器中调用业务接口4.将业务接口返回的结果包装起来发送给指定的视图,并由视图完成处理结果的展现5.做一些简单的校验或是国际化工作
二 spring4 的工作原理
spring原理:
内部最核心的就是IOC了,动态注入,让一个对象的创建不用new了,可以自动的生产,这其实就是利用java里的反射,反射其实就是在运行时动态的去创建、调用对象,Spring就是在运行时,跟 xml Spring的配置文件来动态的创建对象,和调用对象里的方法的 。
Spring还有一个核心就是AOP这个就是面向切面编程,可以为某一类对象 进行监督和控制(也就是 在调用这类对象的具体方法的前后去调用你指定的 模块)从而达到对一个模块扩充的功能。这些都是通过 配置类达到的。
Spring目的:就是让对象与对象(模块与模块)之间的关系没有通过代码来关联,都是通过配置类说明管理的(Spring根据这些配置 内部通过反射去动态的组装对象)
要记住:Spring是一个容器,凡是在容器里的对象才会有Spring所提供的这些服务和功能。
Spring里用的最经典的一个设计模式就是:模板方法模式。(这里我都不介绍了,是一个很常用的设计模式), Spring里的配置是很多的,很难都记住,但是Spring里的精华也无非就是以上的两点,把以上两点跟理解了 也就基本上掌握了Spring.
在wed.xml配置(目的:启动spring 监听整个wed项目)
<listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener>
配置spring 配置文件如下:
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd"> <!-- 引入外部属性文件 --> <context:property-placeholder location="classpath:jdbc.properties" /> <bean id="mySessionFactory" class="org.springframework.orm.hibernate5.LocalSessionFactoryBean"> <!-- 注入连接池,包含了数据库用户名,密码等等信息 --> <property name="dataSource" ref="myDataSource" /> <!-- 配置Hibernate的其他的属性 --> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">true</prop> <prop key="hibernate.connection.autocommit">false</prop> <!-- 开机自动生成表 --> <prop key="hibernate.hbm2ddl.auto">update</prop> </props> </property> <property name="mappingResources"> <list> <value>news/entity/News.hbm.xml</value> </list> </property> </bean> <bean id="myDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="${jdbc.driver}" /> <property name="jdbcUrl" value="${jdbc.url}" /> <property name="user" value="${jdbc.user}" /> <property name="password" value="${jdbc.password}" /> <!-- 每300秒检查所有连接池中的空闲连接 --> <property name="idleConnectionTestPeriod" value="300"></property> <!-- 最大空闲时间,900秒内未使用则连接被丢弃。若为0则永不丢弃 --> <property name="maxIdleTime" value="900"></property> <!-- 最大连接数 --> <property name="maxPoolSize" value="2"></property> </bean> <bean id="myNewsAction" class="news.action.NewsAction" scope="prototype"> <property name="ns" ref="myNewsService"></property> </bean> <bean id="myNewsService" class="news.service.NewsServiceImpl" scope="prototype"> <property name="nd" ref="myNewsDao"></property> </bean> <bean id="myNewsDao" class="news.dao.NewsDaoImpl" scope="prototype"> <property name="sf" ref="mySessionFactory"></property> </bean> </beans>
引入的外部属性文件(jdbc.properties)目的:为了就算不懂java代码的人也可以配置数据库
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/news jdbc.user=root jdbc.password=123456 #oracle jdbc_oracle.driver=oracle.jdbc.driver.OracleDriver jdbc_oracle.url=jdbc:oracle:[email protected]127.0.0.1:1521:orcl jdbc_oracle.user=news jdbc_oracle.password=123456
sprinng的配置文件的简化(目的:少写一些配置文件) 实现方法通过spring的注解:
我们可以发现下面这段代码是不是感觉比较复杂或者说不好看 ,我们可以通过注解代替它
<bean id="myNewsAction" class="news.action.NewsAction" scope="prototype"> <property name="ns" ref="myNewsService"></property> </bean> <bean id="myNewsService" class="news.service.NewsServiceImpl" scope="prototype"> <property name="nd" ref="myNewsDao"></property> </bean> <bean id="myNewsDao" class="news.dao.NewsDaoImpl" scope="prototype"> <property name="sf" ref="mySessionFactory"></property> </bean>
我们可以直接删除上面这些配置文件,再添加一个注解的解释器:很简单只需配置一句:<context:component-scan base-package="news"></context:component-scan>(注:news 是须要注解类所在的包名,或者包名的前置)
上面只列举了在dao中的注解,我们还需要在action、service里也使用同样的方法添加注解。这里就不一一举例了。
[email protected]注解--定义控制器(类级别上的注解)action)
[email protected]注解--定义业务处理类(service)
[email protected]注解--定义底层数据库处理接口(dao)
[email protected]注解--实现注入(jdk)
[email protected]("prototype")--//非单例
三 hibernate 的核心与原理
Hibernate是开源的一个ORM(对象关系映射)框架。
ORM,即Object-Relational Mapping,它的作用就是在关系型数据库和对象之间做了一个映射。从对象(Object)映射到关系(Relation),再从关系映射到对象。这样,我们在操作数据库的时候,不需要再去和复杂SQL打交道,只要像操作对象一样操作它就可以了(把关系数据库的字段在内存中映射成对象的属性)。
Hibernate的核心:
Hibernate的优/缺点:
优点:
1、更加对象化
以对象化的思维操作数据库,我们只需要操作对象就可以了,开发更加对象化。
2、移植性
因为Hibernate做了持久层的封装,你就不知道数据库,你写的所有的代码都具有可复用性。
3、Hibernate是一个没有侵入性的框架,没有侵入性的框架我们称为轻量级框架。
对比Struts的Action和ActionForm,都需要继承,离不开Struts。Hibernate不需要继承任何类,不需要实现任何接口。这样的对象叫POJO对象。
4、Hibernate代码测试方便。
5、提高效率,提高生产力。
缺点:
1、使用数据库特性的语句,将很难调优
2、对大批量数据更新存在问题
3、系统中存在大量的攻击查询功能
四 Spring声明式事务
1.什么是声明式事务?
声明式事务(declarative transaction management)是spring提供的对程序事务管理的方式之一。Spring的声明式事务就是采用声明的方式来处理事务,用在Spring配置文件中声明式的处理事务来代替代码式的处理事务。这样的好处是,事务管理不侵入开发的组件,具体来说,业务逻辑对象就不会意识到正在事务管理之中,事实上也应该如此,因为事务管理是属于系统层面的服务,而不是业务逻辑的一部分,如果想要更改事务管理,也只需要在定义的配置文件中修改配置即可,在不需要事务管理的时候,只要在配置文件上修改一下,即可移去事务管理服务,无需改变代码重新编译,这样维护起来极其方便。
2.首先我们看看手动写事务如下图:
由上图可以看出,首先我们需要建立一个新的session.openSession(),其次通过session的getTransaction().begin()方法和getTransaction().commit()方法进行事务创建和事务提交,并且需要关闭session.close(),这样一来我们每次调用这个方法都会重新创建一个新的session,都要反复的做一样的事情,这样就不符合我们的软件工程设计思想,接下来我们使用声明式事务管理方式进行对代码的简化和调整。
使用springAOP声明式事务管理。
1.首先我们要到aop的jar包
2.然后在application.xml配置文件中进行事务配置:
<!--配置事务 --> <!--配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 --> <!--该类实现PlatformTransactionManager 接口,是针对Hibernate的特定实现 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <!--配置HibernateTransactionManager时须要注入SessionFactory的引用 --> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!--配置事务的增强处理,指定事务管理器 --> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="add*" propagation="REQUIRED" /> <tx:method name="del*" propagation="REQUIRED" /> <tx:method name="mod*" propagation="REQUIRED" /> <tx:method name="*" propagation="REQUIRED" read-only="true" /> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="interceptorPointCuts" expression="execution(* dao.*.*(..))" /> <aop:advisor advice-ref="txAdvice" pointcut-ref="interceptorPointCuts" /> </aop:config>
将上图dao的代码进行修改 将session.openSession()改成getCurrentSessionn(); 由Spring去帮我们去启动事务去管理。
2、使用@Transactional注解方式。
首先在application.xml配置文件里配置@Transactional注解的解析器具体如下:
<!--配置事务 --> <!--配置Hibernate的局部事务管理器,使用HibernateTransactionManager类 --> <!--该类实现PlatformTransactionManager 接口,是针对Hibernate的特定实现 --> <bean id="transactionManager" class="org.springframework.orm.hibernate5.HibernateTransactionManager"> <!--配置HibernateTransactionManager时须要注入SessionFactory的引用 --> <property name="sessionFactory" ref="sessionFactory"></property> </bean> <!--解析事务注解 --> <tx:annotation-driven transaction-manager="transactionManager"/>
接下来就注意里 这里的注解不是写在dao层 而是写在service层,应为是service调用了dao 大家千万注意了 具体如下: