OA项目知识总结
struts文件配置
---------------------------------------------------------
配置c3po链接池
--------------------------------------------------
配置内部bean
<!-- 配置sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate5.LocalSessionFactoryBean">
<property name="configLocations" value="classpath:hibernate.cfg.xml"></property>
<!-- 配置c3p0链接池 因为该datasource只有该工厂使用 所以可以配置一个内部bean-->
<property name="dataSource">
<!-- 内部使用的bean 不需要id属性 -->
<bean class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 必要属性 引入外部的properties文件 使用其中配置的值-->
<property name="jdbcUrl" value="${jdbcUrl}"></property>
<property name="driverClass" value="${driverClass}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<!-- 其他属性配置 -->
<!-- 初始化时获取3个链接 取值应在minPoolSize和maxPoolSize之间 default=3 -->
<property name="initialPoolSize" value="3"></property>
<!-- 连接池中保留的最小链接数 default=3-->
<property name="minPoolSize" value="3"></property>
<!-- 连接池中保留的最大链接数 default=15-->
<property name="maxPoolSize" value="5"></property>
<!-- 当连接池中的连接耗尽的时候 c3p0一次同时获取的连接数 default=3-->
<property name="acquireIncrement" value="3"></property>
<!-- 控制数据源内加载的PreparedStatement数量。如果maxStatement与maxStetementsPerConnection均为0,则缓存关闭。default=0 -->
<property name="maxStatements" value="8"></property>
<!-- maxStatemPerConnection定义了连接池内单个链接所拥有的最大缓存statements数。default=0 -->
<property name="maxStatementsPerConnection" value="5"></property>
<!-- 最大空闲时间,1800秒内未使用则连接被丢弃。若为0则永不丢弃。default=0 -->
<property name="maxIdleTime" value="1800"></property>
</bean>
</property>
</bean>
-----------------------------------------------------------------------
使用注解的方式管理bean对象 注入或者装配
首先在spring核心中开启扫描(注意和不是事务扫描)
在类中的使用方式
package test; import javax.annotation.Resource; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Test;
import org.model.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
//如果想注入容器中的对象sessionFactory 当前的类必须在容器中 spring不能给 不在容器中的对象注入属性
//(例如配置方式中 先配置action 然后配置service action中才能注入配置的service 因为他们在一个容器中 spring配置文件中管理生成的对象都是在容器中的)
//所以声明一个bean对象在容器中 名字默认为对象的名称SaveTwoUser
//@Service("saveTwoUser")效果和@Service一样 注意类名的第一个字母是小写的
@Service
public class SaveTwoUser {
//sessionFactory已经配置好了 在容器中 使用时 采使用注解的方式进行注入 则不用在配置set方法了 如果采用配置的方式
//那么这里声明sessionFactory之后 创建set方法 在配置文件中进行注入<property name="sessionFactory" ref=""></property>
//注入bean资源使用@Resource 先按照"sessionFactory"去spring配置文件中去找 找不到 再按照类型去找
23 @Resource
24 private SessionFactory sessionFactory;
//private ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext.xml"); //加注解 开启事务
@Transactional
@Test
public void save(){
//这里只能使用getCurrentSession而不能使用opensession,opensession得到的是一个新的session 没有事务
//而getCurrentSession得到的是外边已经管理好事务的session
if(sessionFactory!=null){
Session session=sessionFactory.getCurrentSession();
if(session!=null){
session.save(new User());
//int i=10/0;
session.save(new User());
}
}else{
System.out.println("sessionfactory为空。。。。");
} } }
装配bean实例(action对象)到spring容器中 以及对该action注入其他类的对象 并且调用期中的方法
然后从容器中获取
-------------------------------------------------------------------------------
日志级别设置(设置为error时,只有出现错误或者出现严重错误的时候才会打印信息,否则不打印)
---------------------------------------------------
BaseDao的抽取思路
第一次抽取 因为实体对应的dao操作类 除了自己独有的方法外 基本的增删改查操作是相同的 不同的是对应的类型不同 例如保存操作 UserDao和RoleDao保存时 都是调用session.save()参数为user 和role
如下图
所以把这些公共的方法抽取出来(创建一个BaseDao接口 定义公共方法 UserDao和RoleDao继承BaseDao 那么UserDao和BaseDao中就相当于也定义了这些方法(方法未实现))
当然 存在接口 那么就必须有人来实现接口
创建UserDaoImpl以及RoleDaoImpl实现类
两个实现类实现了接口 当然要实现接口中的方法 不要忘记了 UserDao接口以及RoleDao接口中都继承了BaseDao接口(接口之间可以继承) 所以BaseDao接口中定义的未实现的六个方法 在UserDao和RoleDao中也是存在的
即在UserDao和RoleDao接口中存在继承来的6个未实现的方法 所以在它们对应的实现类实现该接口的时候 会提示实现没有实现的方法 出现了上面所示的提示
那么当然不能在各自的实现类中去实现它们 ,那样BaseDao的抽取就没有意义了,
如下图
我们思考,如果让这两个实现类 在继承一个类A(拥有类A中的方法) 而类A中把这些方法都给实现了 那么不就相当于这两个实现类中实现了父类中需要实现的方法吗
(方法的实现 自己定义的或者继承过来的 都叫做实现 比如 A类中存在一个未实现的方法save () 第一种实现 A类自己写出save()方法的实现代码 第二种 A类继承了B类 B类中有一个实现了的save()方法 那么A类自然就对未实现的方法进行了实现 因为A类中此时有从B类中继承过来的save()方法)
所以进行第二次抽取 定义BaseDaoImpl来实现BaseDao中未实现的方法 同样也指定泛型 泛型的类型由继承的类确定 即将来某个类继承了BaseDaoImpl 时需要指定泛型 class A extends BaseDaoImpl<A>
接下来,让那两个实现类继承该实现类
这样就完成了抽取工作,下面进行方法的实现(接下来就只用关注实现类BaseDaoImpl即可了,如果该类把增删改查的代码实现成功,那么其他继承该类的类中自然有这些已经实现的方法,直接调用即可)
对方法的实现需要通过sessionFactory得到session 然后调用其中的方法进行数据库操作
子类上边使用注解把该类对象设置进入容器中,那么父类对象即使不在容器内 依然可以注入容器中的sessionFactory对象(否则 一个类如果想要注入容器中的bean实例 前提是该类设置进容器中)
继承时只会继承非私有的属性和方法,子类当然有自己的方法 也需要获得session 那么子类也需要进行注入sessionFactory 所以修改如下
为子类提供一个方法,使其得到session ,设置为protected 子类也可访问该方法 所以可以得到session 子类就不需要在注入sessionFactory了
这样就为子类提供了便捷的方式 得到了session ,如果不嫌麻烦 在子类中注入sessionFactory当然也可以 。
接下来继续把重点放在方法的实现上
package org.base; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List; import javax.annotation.Resource; import org.hibernate.Session;
import org.hibernate.SessionFactory;
//子类放进容器中 这里父类不需要放进容器 依然能够完成sessionFactory的注入
public class BaseDaoImpl<T> implements BaseDao<T> {
//使用注解 把spring容器中的sessionFactory注入到该类中 但是这个类需设置进容器中
//但是问题又来了 为了代码的简洁性 思考:BaseDaoImpl这个bean实例有操作的实体吗 ?没有 那么注入进容器中似乎没有意义
//但是为了解决sessionFactory注入到该类中的问题 可以有另外一种解决办法
//那就是把继承该类的子实现类注入到容器中即可 子类注入到容器中很有必要 因为需要操作这些实现类完成对应实体的操作
@Resource
private SessionFactory sessionFactory;
//得到session 这个session必须是currentsession 只有这样才能进行事务管理
protected Session getSession(){
return this.sessionFactory.getCurrentSession();
}
private Class<T> clazz=null;
public BaseDaoImpl(){
//使用反射技术得到真实的类型
//获取当前new的对象的 泛型的父类 类型
ParameterizedType pz=(ParameterizedType) this.getClass().getGenericSuperclass();
this.clazz=(Class<T>) pz.getActualTypeArguments()[0];
} public void save(T entry) {
//通过sessionFactory得到session
getSession().save(entry);
} public void delete(Long id) {
//先得到
Object obj=getById(id);
//再删除
if(obj!=null){
getSession().delete(obj);
}
}
public void update(T entry) {
getSession().update(entry);
} public T getById(Long id) {
return getSession().get(clazz,id);
} public List<T> getByIds(Long[] ids) {
return getSession().createQuery("from "+clazz.getSimpleName()+" where ids in(:ids)")
.setParameterList("ids",ids)
.list();
}
public List<T> findAll() {
return getSession().createQuery("from "+clazz.getSimpleName())
.list();
}
}
到此就完成了抽取工作
------------------------------------------------
项目的资源分类
配置文件单独创建了一个包 与src同级 所以更放在src的根目录中是一样的 这样的目录设计使项目结构更加的清晰
jsp页面放在web-inf下
项目部署 服务器启动之后
放在webroot中的jsp页面 可以直接访问
放在web-INF文件夹下的jsp页面 不能直接访问到页面
最好的方式是 先访问action(准备数据) 然后转发给jsp(进行数据的显示)
所以把jsp页面都统一放在web-inf文件夹中 先访问action 然后转发给jsp页面
-----------------------------------------------------
超链接中使用onclick="return confirm('确定删除吗')"进行确认提交,单击确定 就根据href中的地址 进行提交 否则 什么也不做
<a href=" " onclick="return confirm('确定删除吗')">删除</a>
---------------------------------
动态的提交,执行action中的不同方法
添加页面和修改页面基本显示一样,提交执行action中的方法不同 通过jstl表达式判断内容是否为空(修改的时候先进行了数据查询,然后到修改页面,而添加的时候只是到添加页面)
当执行添加的时候,就执行action中 的add方法 否则执行edit方法
------------------------------------------------------------------------
基本操作配置
因为添加页面和修改页面通用一个页面 所以这里都返回saveUI 跳入同一个页面 如果页面有区别 不能共用 那么就按照上面的进行配置
//1.列表
public String list() throws Exception {
return "list";
}
//2.删除
public String delete() throws Exception {
return "toList";
}
//3.到添加页面
public String addUI() throws Exception {
return "saveUI";
}
//4.执行添加
public String add() throws Exception {
return "toList";
}
//5.到修改页面
public String editUI() throws Exception {
return "saveUI";
}
//6.执行修改
public String edit() throws Exception {
return "toList";
}
<!-- 部门管理 -->
<action name="department_*" class="departmentAction" method="{1}">
<result name="list">/WEB-INF/jsp/departmentAction/list.jsp</result>
<result name="toList" type="redirectAction">department_list.action</result>
<result name="saveUI">/WEB-INF/jsp/departmentAction/saveUI.jsp</result>
</action>
---------------------------------------------------------------------
---------------------------------------------------------
创建的model中使用set集合出现的问题
HashSet集合是无序集合,每次查询的内容放入到该集合中后,在前端页面显示的时候就会出现每次显示的内容顺序都不是固定的
例如 再检索所有部门信息的时候
刷新
内容是正确的 但是就是顺序每次刷新都会发生变化
最好的解决办法
在配置对应属性的set标签时 加入order-by属性 该属性指定的是sql的orderby子句内容
这里是按照id升序排列 查询的时候就按照这种方式进行查询 然后因为set集合还是无序的 所以 如果配置了该属性 那么框架自动会生成一个有序的集合实现类 并且把内容存入到其中
这样每次查询的时候 都可以保证每次输出的内容是一致的
-----
按照升序 排列 无论刷新多少次
-----
按照降序排列 无论刷新多少次
-------------------------------------------------------------------------------------------
创建公共文件(多数页面因为样式的代码基本一样 把他们放在一个文件中 然后 使用的时候 直接引入该文件)
创建一个单独的文件 存放这些共用代码 该文件后缀可以是.jsp
使用时 直接引入
------------------------------------------------------
OA项目知识总结的更多相关文章
- OA项目知识总结2
BaseAction的抽取 项目中的每个实体类都对应一个action 每个action都都要继承ActionSupport类 已以及实现ModelDriver接口 并且需要注入service 虽然 ...
- 【Java EE 学习 67 上】【OA项目练习】【JBPM工作流的使用】
OA项目中有极大可能性使用到JBPM框架解决流程控制问题,比如请假流程.报销流程等等. JBPM:JBoss Business Process Management,翻译过来就是业务流程管理.实际上就 ...
- [deviceone开发]-企业OA项目开源分享
一.简介 是一个真实的企业OA项目改造的开源项目,几乎涵盖了所有常用的组件,包括环信实现在线聊天等功能,类似微信的朋友圈功能,自定义的智能搜索等,而且这个是真实的通过Http链接后台web服务,里面很 ...
- 01传智_jbpm与OA项目_整体项目架构
oA项目: 项目结构如下:
- 基于SSH2的OA项目1.0_20161206_需求分析与框架搭建
1. SSH项目 OA项目,办公自动化,将公司的数据,文档,流程实现在系统中的管理. 降低人员交流过程中的成本.提高办公的效率. 2 .系统管理 主要实现系统权限的管理,不同的用户登陆后看到菜单项不一 ...
- OA项目实战(二) 开发准备
上次的博文OA系统实践(一) 概述中,我们已经了解了OA的相关概念.从本次博文开始,我们做一个简单的OA实例. 在OA开发之前,有几个工作们需要提前做.一个是对需求进行分析,另一个是对开发环境进行选择 ...
- 第一周博客之二---OA项目环境搭建及开发包部署
OA项目环境搭建 一个项目想要能够在开发人员打包好项目包之后进行测试,就必须进行项目测试环境的搭建,要根据开发工程师的开发环境采用不同的测试环境,以下只是浅谈下Java项目OA(办公自动化平台)的环境 ...
- OA项目_环境搭建
OA项目现在要做成微服务,用的框架是springboot,所用的编程工具是idea,maven,做为一个程序员最关心的就是我需要在那个架包中编写代码,我们只需关注domain,repository,s ...
- 修改struts2自定义标签的源代码,在原有基础上增加功能(用于OA项目权限判断,是否显示某个权限)
OA项目在做权限判断时 原始方式: 现在完成的功能 :通过改变struts2自定标签源代码 在原有的基础上 增加判断权限的功能 而页面上使用标签的方式 还是下图 步骤: 打开文件 搜索< ...
随机推荐
- Kafka集群部署及測试
题记 眼下我们对大数据进行研究方向以Spark为主,当中Spark Streaming是能够接收动态数据流并进行处理.那么Spark Streaming支持多源的数据发送端,比如TCP.ZeroMQ. ...
- Android的编译环境--Build系统【转】
本文转载自:http://blog.csdn.net/kitty_landon/article/details/60764232 Android是一个庞大的系统,包含太多的模块,各种模块的类型也有10 ...
- Linux Shell Scripting Cookbook 读书笔记 3
patch, tree, head ,tail 1. 创建不可修改文件 chattr +i file chattr -i file 移除不可修改属性 2. 能够启动闪存或硬盘的混合ISO isohyb ...
- 将实体类/匿名对象转换为SqlParameter列表
每次操作数据库参数化实在是太麻烦了,于是自己瞎琢磨,琢磨出下面扩展方式,能力有限,还有不足之处,请多多指教. /// <summary> /// <remarks> /// & ...
- 使用Android ADT最新开发工具后,新建项目出现appcompat v7 他是什么?
做Android开发的朋友最近会发现,更新ADT至22.6.0版本之后,创建新的安装项目,会出现appcompat_v7的内容.并且是创建一个新的内容就会出现.这到底是怎么回事呢?原来appcompa ...
- 利用JavaScript的%做隔行换色
<html> <head> <meta charset="utf-8"> <title>无标题文档</title> &l ...
- Javascript关于JSON集合的几种循环方法
/** * 根据json数据生成option树形控件 * 如果有children节点则自动生成树形数据 * @param {JSON} data * @param {int} n 节点深度 * @pa ...
- VHDL_LIB之DFF
1 D-Flip-Flop with async reset or set library IEEE; use ieee.std_logic_1164.all; entity FFD is gener ...
- C语言-重写strupr函数
一.重写函数 Action(){ //重写strupr,小写变大写 char *desc; char *str="123abcd*"; desc=(char *)malloc(10 ...
- 01--vim常用快捷键
Linux中vim编辑器的功能非常强大,许多常用快捷键用起来非常方便,这里将我学vim入门时学的一些常用的快捷键分享给大家一下,希望可以帮助你们. 这个是我将鸟哥书上的进行了一下整理的,希望不要涉 ...