SSH框架总结
来源:互联网 发布:王柳雯的淘宝店 编辑:程序博客网 时间:2024/06/05 09:22
SSH框架总结
一、搭建SSH框架
1.1导入相关Jar包 大约45个
1.2相关配置文件
1.2.1web.xml
1、配置ContextLoaderLinstener,用于加载spring 的applicationContext.xml配置文件 默认加载位置为web-inf下的,需要指明 配置文件位置 contextConfigLocation 如果配置文件找不到,就会报FileNotFound找不到异常 <!--配置Spring加载 监听器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!--配置全局参数 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:applicationContext.xml</param-value> </context-param> clsspath是spring中特有的用于标识类路径下1、1在配置Struts2可以配置OpenSessionInViewFilter 用于解决nosession问题,非必须, 必须配置在struts2核心控制器之前 <filter> <filter-name>openSessionInViewFilter</filter-name> <filter-class>org.springframework.orm.hibernate5.support.OpenSessionInViewFilter</filter-class> </filter> <filter-mapping> <filter-name>openSessionInViewFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>2、配置Struts核心控制器 StrutsPreparedAndExecuteFilter 两个作用:加载struts2配置文件在init方法中加载,配置文件只加载一次,对用户的action请求或空白请求进行拦截 <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>3、配置Spring编码过滤器 CharacterEncodingFilter 用于解决post请求乱码问题 可以配置参数 encoidng UTF-8 非必须,因为如果使用struts2与spring整合时,struts2本身就解决了post请求乱码问题 <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <!--配置参数,指定使用UTF-8编码 --> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
1.2.2struts.xml文件配置
1、struts2的配置文件: default.properties 配置struts运行中的常量 struts-default.xml 配置拦截器以及结果视图,以及bean的配置 struts-xxx-plugin.xml 插件的配置文件,非必须 struts.xml 程序员编写的配置文件,配置常量,action,自定义拦截器等 struts.properties 配置常量,一般不需要配置,在struts.xml文件中配置2、package配置 name 包名,唯一 namespace名称空间 默认为 "/" extends 继承的父包 默认为struts-default3、action配置 name 访问名称 Action_* *表示访问方法 class 类的全限定类名或者spring中对应的id名称 method 方法 ${1}表示第一个*代表的内容 result 逻辑视图 interceptor-ref 明确指明当前使用的是哪个拦截器 可以配置param name namespace+name 路径为action的完整访问路径4、interceptor配置 interceptors 表示所有拦截器 interceptor 配置自定义的拦截器 name 拦截器的名称 ,class拦截器的全限定类名 interceptor-stack 配置拦截器栈 interceptor-ref 配置拦截器引用 name拦截器的名称 自定义拦截器放在默认拦截器栈后面 default-interceptor-ref 默认拦截器配置 name=拦截器或着拦截器栈名称5、拦截器 拦截器是struts2的基石,很多功能都是基于拦截器实现的,在用户访问action方法之前执行,采用责任链的设计模式 ,采用递归调用的方式执行。6、拦截器的编写 实现Interceptor接口 继承AbstractInterceptor类 继承MethodFilterInterceptor类 我们一般使用继承AbstractInterceptor <struts> <constant name="struts.enable.DynamicMethodInvocation" value="false" /> <constant name="struts.devMode" value="true" /> <!--配置上传文件大小 --> <constant name="struts.multipart.maxSize" value="20000000"></constant> <!-- 加载国际化配置文件 --> <constant name="struts.custom.i18n.resources" value="uploadError" /> <!--全局包,用于配置全局信息 --> <package name="public" namespace="/" extends="struts-default"> <interceptors> <interceptor name="loginInterceptor" class="loginInterceptor"></interceptor> <interceptor-stack name="myInterceptorStack"> <interceptor-ref name="defaultStack"></interceptor-ref> <!-- 自定义拦截器放在默认拦截器后面 --> <interceptor-ref name="loginInterceptor"> <!-- 设置不需要拦截的方法--> <param name="excludeMethods">customerAction_list,linkmanAction_list,sysUserAction_login,sysUserAction_loginUI</param> </interceptor-ref> </interceptor-stack> </interceptors> <default-interceptor-ref name="myInterceptorStack"></default-interceptor-ref> <global-results> <result name="loginError">/login.jsp</result> <result name="success">/jsp/success.jsp</result> <result name="error">/jsp/error.jsp</result> </global-results> </package> <include file="struts/struts-sysUser.xml"></include> <include file="struts/struts-customer.xml"></include> <include file="struts/struts-linkman.xml"></include> <include file="struts/struts-saleVisit.xml"></include> </struts>
1.2.3applicationContext.xml文件配置
1、配置数据源,用于连接数据库 C3P0数据源 ComboPooledDataSource driverClass jdbcUrl user password DBCP数据源 BasicDataSource JDBC数据源 DriverManagerDataSource2、配置sessionFactory 是sring与hibernate整合的关键点 类LocalSessionFactoryBean dataSource configLocations(classpath:hibernate.cfg.xml)3、配置Hibernate事务管理器 transactionManager 需要注入sessionFactory4、配置声明式事务通知 transaction-manger 指明使用的事务管理器 tx:method 表示哪些方法使用事务 name为方法名,propagation为事务行为 <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED"/> <tx:method name="delete*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="find*" read-only="true"/> <tx:method name="*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> 声明式事务的原理:AOP AOP的原理是什么?动态代理模式 动态代理模式?JDK实现动态代理,cglib实现动态代理 这两种方式的区别:JDK动态代理时目标对象一定实现接口,而cglib可以不实现 JDK动态代理用的类?Proxy.newProxyInstance() Cglib代理如何实现? 1.创建一个Enhancer eh = new Ehancer(); 2.Eh.setSuperClass(); 3.设置回调:eh.setCallback(); 4.生成代理对象:eh.create(); 1. 事务管理器的配置 父接口:PlatformTransactionManager Hibernate事务管理器的子类:HibernateTransactionManager Jdbc事务管理器的子类:DataSourceTransactionManager PlatformTransactionManager它的内部是什么工作的? TransactionDefinition:事务定义信息 TransactionStatus:事务状态 它需要根据TransactionDefinition这个对象,得到事务的定 义信息,再根据事务的执行状态TransactionStatus,来决定事务是提交还是回滚。 2. 事务通知的配置:<tx:advice> 事务通知advice为什么可以作用到切入点表达式所指定的类中的方法? 因为在配置声明式事务时,它的本质也是去生成代理子类对象,所以此时只要根据你指定的切入点表达式的要求,针对目标对象直接生成代理对象,而同时通过aop来实现横向代码的动态织入,从而实现了事务的控制。它对应的通知类型,可以认为环绕通知。5、配置声明式事务与aop整合 aop:pointcut 配置切入点表达式 expresssion(需要事务执行的方法) <aop:config> <aop:pointcut expression="execution(* cn.lx.crm.service.impl.*.*(..))" id="myPointcut"/> <aop:advisor advice-ref="txAdvice" pointcut-ref="myPointcut"/> </aop:config>6、配置文件分离的思想 公共配置+分层思想 applicationContext.xml applicationContext-dao.xml applicationContext-service.xml applicationContext-action.xml 公共配置+分模块思想 applicationContext.xml applicationContext-customer.xml7、bean配置的作用域 request\session\global session\singleton\prototype signleton 单例 prototype 多实例 配置action时,一定要配置多实例8、bean生命周期 spring配置文件加载时创建 init destory9、bean对象的创建三种方式 构造函数 实例工厂 静态工厂10、bean对象注值的三种方式 setter注值 构造函数注值 p名称空间注值
1.2.4 hibernate.cfg.xml文件配置
1、配置SQL方言<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>2、配置自动建表<property name="hibernate.hbm2ddl.auto">update</property>3、配置显示SQL<property name="hibernate.show_sql">true</property>4、配置格式化SQL<property name="hibernate.format_sql">true</property>5、配置session绑定本地线程<property name="hibernate.current_session_context_class">org.springframework.orm.hibernate5.SpringSessionContext</property>6、配置事务隔离级别<property name="hibernate.connection.isolation">4</property>7、导入映射文件<mapping resource="cn/lx/crm/domain/BaseDict.hbm.xml"/>
1.2.5 准备PO类及映射文件
1、PO类的编写规范: 1. 私有属性 2. 提供公有的无参构造 3. 提供 私有属性的公有getter与setter 4. 类名不能用final 5. 实现java.io.Serailizable接口 6. 是一个公有类 7. 如果是基本类型的属性,请使用它的对应包装类 2、映射文件命名 类名.hbm.xml <class name=”包名.类名” table=””> <id name=”” column=””> <generator class=”uuid,assigned,identity,increment,native,sequence”/> </id> <property name=”” column=”” not-null=”tru” type=”” length=”” /> <property name=”” column=”” not-null=”tru” type=”” length=”” /> </class> 3、关联关系的配置 分别为一对多关系、多对一关系、多对多关系、一对一关旭 Customer的类中: 一对多 Private Set<Linkman> linkmans = new HashSet<Linkman>(0); Customer.hbm.xml文件中 <set name=” linkmans” cascade=”” inverse=”” fetch=”join|select” lazy=”true|false|extra”> <key column=”外键字段名”/> <one-to-many class=” Linkman” /> </set> Cascade取值:all,save-update,delete,delete-orphan, delete-orphan-all Inverse取值:true,false,默认为false Cascade与inverse的区别? 1. cascade代表父子项操作时的级联关系 2. inverse代表控制权交给谁管理,true代表控制权交给对方管理 3. inverse一般 设置为true,交给多方维护,这样可以提高效率 fetch的特点:fetch=”join”时lazy失效,同时它采用迫切左外连接实现的查询 它可以解决noSession问题 Fetch=select,它将采用多条sql语句的形式进行查询,发出sql的时机由lazy来决定,想立即发出sql就用lazy=”false”,希望在加载这个记录时才出现sql语句,就让lazy=”true|extra” 多对一的配置: Linkman.java中配置: Private Customer customer; Linkman.hbm.xml文件 <many-to-one name=”customer” class=” Customer” column=”外键字段名”></ many-to-one> 多对多的配置: SysUser与SysRole用户与角色 SysUser.java Private Set<SysRole> sysRoles = new HashSet<SysRole>(0); SysUser.hbm.xml文件 <set name=”” table=”” inverse=”true”> <key column=”关联到自身的来自中间表的外键”/> <many-to-many class=” SysRole” column=” 关联到SysRole来自中间表的外键”/> </set>
2 DAO模式
1.编写BaseDao<T>接口2.编写实现类BaseDaoImplPublic BaseDaoImpl<T> extends HibernateDaoSupport implements BaseDao<T>{ Class clz; Public BaseDaoImpl(){ Type type = this.getClass().getGenericSuperClass(); ParameterizedType pt = (ParameterizedType)type; clz = (Class)Pt.getActualArgumentsType()[0]; } Public List<Customer> findAll(){ return this.getHibernateTemplate().find(“from ”+clz.getName()); }}Class CustomerDaoImpl extends BaseDaoImpl<Customer> implements CustomerDao{}getHibernateTemplate().find()内部的本质是什么执行的?Session session = sessionFactory.openSession();AOP:横向插入事务开启的代码Query query = Session.createQuery(“from “+clz.getName());Query.list();AOP: 横向插入事务提交或回滚的代码Hibernate实现数据检索的5种方式get/load 加载时使用对象的OID(Object Identity Qualified 对象的唯一标识)QBC Query By Criteria Criteria c = session.createCriteria(Customer.class);HQL Query query = session.createQuery(“”);对象导航 前提:先配置好对象之间的关联关系 Set<linkman> linkmans = customer.getLinkmans();SQL :SQLQuery query = session.createSQLQuery(“sql”).addEntity(Customer.class);面试:get/load加载数据的区别?1. get立即加载,load延迟加载2. load加载的对象为代理对象,get加载的是真实对象3. load加载失败会出现异常,而get加载失败返回null4. get加载时就会出现sql语句,而load只会调用属性时才会真正加载(才会有sql)5. load方法也可以实现与get方法相同的效果:第一种方法只要在相应的映射文件中找到class结点,添加一个lazy=”false” 第二种方法:在PO定义时加上final结论,加载数据失败时,load总是会抛出异常
3 Hibernate一级缓存
一级缓存:它是与session关联在一起的,如果session不存在了,一级缓存也就不存在了。 一级缓存的内部结构: Hashtable,就是key-value对。 结于持久态的对象,没有调用update()方法,也会实现更新操作?因为它会根据一级缓存中的快照区与真实对象进行比较,如果有更新,就会在事务提交时,将更新后的结果刷出到数据库中。(tx.commit();默认就会调用session.flush();) 一级缓存中常用的操作方法: clear();清空一级缓存 evict(Object obj)在一级缓存中清空指定的对象 flush()可以做到一级缓存中数据与数据库中数据的同步更新 refresh()再次将数据库中的数据查询出来,填充一级缓存
4 struts2的封装数据的方式
1.获取参数 ServletActionContext.getRequest.getParameter(“custId”);2解耦合方式获取参数 ActionContext.getContext().getParameters().get(“custId”)[0];3.属性驱动来实现参数封装(params拦截器) Customer/customerAction_find?age=10;CustomerAction类中Private int age;Public void setAge(int age){ This.age =age;}Customer/customerAction_find?customer.age=10;private Customer customer;//生成它的setter与getter4.模型 驱动:(modelDriven拦截器)1.模型驱动要求实现一个接口:ModelDriven<Customer>,同时还要重写getModel(),这个方法要求返回一个已存在的对象。
5 值栈
1.什么是值栈?它是一个用于保存数据的容器,它本身只是一个叫做ValueStack接口,它的实现类是OgnlValueStack.2.如何得到ValueStack实例? ValueStack vs1 = ActionContext.getContext().getValueStack(); ValueStack vs2 = request.getAttribute(“struts.valueStack”);针对同一次请求,不管用上面的哪个方法,获取的都是同一个对象。每次请求时,valueStack都是一个新的对象,action对象也是一个新的对象3.ValueStack的内部结构root :类型 CompoundRoot 而CompoundRoot又继承了ArrayList父类context:类型 OgnlContext ,而OgnlContext又实现Map接口默认操作值栈都是在操作root4.为什么EL表达式也能访问值栈? 用到RequestWrapper对request进行包装,在包装类中可以找到一个getAttribute()而这个方法首先是在request域中找数据,如果没有就会找valueStack.request = prepare.wrapRequest(request);
0 0
- SSH框架学习总结
- SSH框架学习总结
- ssh框架总结
- SSH框架总结
- SSH框架搭建总结
- SSH框架总结
- SSH框架总结
- SSH框架总结
- 搭建SSH框架总结
- ssh框架学习总结
- SSH框架总结
- SSH框架总结
- ssh框架内容总结
- ssh框架个人总结
- SSH框架总结
- SSH框架总结
- SSH框架学习总结
- ssh框架面试总结
- [Python]用Python下载网络小说.23333
- C++ 实现太阳系行星系统
- soapui笔记5:项目导入
- js(二)——基础语法
- C++ 异常处理
- SSH框架总结
- 查询到的关于PDO的一点内容
- Rabbitmq+SimpleAmqpClient--之vs2010编译
- spring的事务管理有几种方式实现,如何实现
- 计算机学习速成法
- leetcode 345. Reverse Vowels of a String 解题报告
- 文章标题
- 图像局部特征(三)--FAST角点检测子
- 51nod 1417 天堂里的游戏