4、 功能分为三大模块: 公共信息模块 、 取派(业务受理、货物调度、返货)、中转业务(货物进出库 )、 路由管理 (运输工具,进出港)
====================================================================================
二、 技术选型
初级工程师,刚入职 系统后期维护升级 (基于原有系统的功能追加 )
小公司项目经理 ===== 项目经理 + 技术经理 + 架构师
大公司
项目经理 : 管理项目 (人力、财务、项目进度、和客户沟通 偏销售) ---- 零技术 (团队管理)
架构师: 技术选型、难题攻关 , 保证技术方案在项目组可实施 (技术管理 )
技术经理 (组长): 带手下人干活的 ,确保手下的人任务能够完成
技术选型 :
项目三层结构: web层解决方案、业务层解决方案、数据层解决方案
任何公司: 长期开发,积累自定义组件
流程技术: struts2 + spring3 + hibernate3
运行平台: 版本管理 SVN + Linux (服务器环境部署 ) + tomcat7.0 + JDK7 + Oracle
开发环境: window + tomcat7.0 + JDK7 + mysql
UI设计 : jquery easy ui
服务器端 : 任务调度(定时器) quartz 、 表单HTML在线编辑器(所见即所得)、报表 Open Flash Chart 、 JBPM 、 excel解析 POI
三、技术预热阶段
1、 struts2 + spring3 + hibernate
便捷性 : 首选注解开发
熟练度 : 配置文件
struts2 框架使用 blank.war中所有jar包、 struts2-spring-plugin.jar 、 (使用注解 struts2-convetion-plugin.jar)
*** 非注解 web.xml struts.xml
*** 注解 web.xml @Action
在实际开发中为了位置文件 更好维护, 创建单独source folder ----------- config
在实际开发中经常需要单体测试 ,需要将测试代码 与功能代码分开,也可以采用创建 单独source forlder ------------- test
spring3 框架使用 core、aop、tx、jdbc、dao、test 、web 、log
** 在config下 导入log4j.properties
** 在config下 创建applicationContext.xml jdbc.properties
** Hibernate 实体类都是用注解 开发
配置数据源 、Hibernate实体类 通过packageToScan 自动扫描、 事务管理器TransactionManager、 使用注解管理事务
配置 web.xml ContextLoaderListener
Hibernate框架使用 hibernate3.jar 、required/*.jar、 jpa.jar 、log4j 、 二级缓存
*** 将Hibernate 配置写入Spring中 applicationContext
问题: struts2是直接与客户端交互,需要编写jsp文件,如何对jsp做权限控制 ?
* 方案一 : 如果jsp在WebRoot下,url直接访问到,通过Filter 进行权限控制
* 方案二 : 将jsp 放入WEB-INF下 ,页面url不能直接访问 ,通过struts2 的Action转发给 jsp (因为经过Action,通过拦截器进行权限控制)
使用方案二,该Action没有什么逻辑,只是单纯跳转 ------- 默认处理类
<default-class-ref class="com.opensymphony.xwork2.ActionSupport" />
<action name="page_*">
<result>/WEB-INF/pages/{1}.jsp</result>
</action>
问题: 客户端使用Ajax访问struts2 , struts2如何返回一个json数据
* 方案一: json-lib
* 方案二: flexjson
AJAX过程中,请使用火狐查看通信过程中数据,调试js ---- firebug 经常使用console.info(信息); (类似System.out )
json-lib
**** TODO : json-lib 序列化日期对象出现异常
如果两个对象互相关联,在序列化过程中 , net.sf.json.JSONException: There is a cycle in the hierarchy! ---- 解决 JsonConfig 设置某个属性不进行序列化
flexjson
导入 flexjson.jar
JSONSerializer jsonSerializer = new JSONSerializer();
String result = jsonSerializer.serialize(customers); ------ 默认只会序列化当前对象,关联Order没有被序列化
String result = jsonSerializer.deepSerialize(customers); ----- 深度序列化,将关联对象序列化
jsonSerializer.exclude("*.class"); // 不对getClass属性进行序列化
** 没有日期问题
问题: 业务层进行事务管理 ?
使用Hibernate, 将sessionFactory对象注入 HibernateTransactionManager , 有该对象进行事务控制
<tx:annotation-driven transaction-manager="transactionManager"/> 使用注解来管理事务 ------- 在需要管理事务类或者方法上 @Transactional
***** 进行事务管理 通常Service层
事务管理 @Transactional 属性 isolation 隔离级别 propagation 传播行为 read-only 设置事务只读 timeout 设置事务超时
问题: 通常锁编写代码会针对业务层进行测试
@RunWith(SpringJunit4LoaderRunner.class)
@ContextConfiguration("location: classpath:applicationContext.xml")
public XxxServiceTest {
@Autowired
private XxxService xxxService;
@Test
public void testRegist(){
}
}
问题: 架构系统时,是否使用接口 ?
在业务层、数据层都会定义接口 , 统一规范 ,分层开发
* 许多外包公司,按层划分任务
* 开发过程中 ,Action依赖Service、Service依赖DAO ,使用接口进行分层开发 , 例如:web层只需要调用接口编程, 业务层只需要考虑接口实现
* 便于维护
问题: 数据层 ,将使用 HibernateTemplate 进行操作 。 模板提供的很多方法都使用泛型
例如:
将一个数据对象,保存到数据库 this.getHibernateTemplate().save(Object); ------ 可以用来对各种数据类型进行保存
修改 update()
删除 delete
查询 get/load 根据id查询,查询所有 find , 条件查询 findByCriteria
将重复操作,抽取一个公共类 GenericDAO<T> extends HibernateDaoSupport
***** 接口和抽象类的区别 ???
// 增加
public void save(T obj);
// 删除
public void delete(T obj);
// 修改
public void update(T obj);
// 查询
public T findById(Class<T> domainClass ,Serializable id); // 如果id自增,定义为Integer 或者 Long
public List<T> findAll(); // 查询所有
public List<T> findByCriteria(DetachedCriteria criteria);// 各种各样条件查询, 添加排序
public List<T> findByCriteria(DetachedCriteria criteria, int firstResult , int maxResults); // 分页查询
public List<T> findByNamedQuery(String namedQuery); // 进行条件查询,使用hql, 在业务层调用NamedQuery名称就可以了
使用注解配置Customer和Order
@Table(name="orders")
public class Order {
@Id
@GenericGenerator(name="uuidGenerator", strategy="uuid")
@GeneratedValue(generator = "uuidGenerator")
private String id ;
private String addr;
@ManyToOne(targetEntity=Customer.class)
@JoinColumn(name="customer_id")
private Customer customer ;
@Entity
@Table(name="cutomers")
public class Customer {
@Id
@GeneratedValue(strategy=GenerationType.AUTO)
private Integer id ;
private String name;
// mappedBy 相当于 inverse,将外键权利交给对方
@OneToMany(targetEntity=Order.class,mappedBy="customer")
private Set<Order> orders = new HashSet<Order>();
====================================================================================
四、bos项目构建
分为三个资源包: src 源码、 config配置文件 、test测试用例
整合: 将action配置到struts.xml 、 applicationContext.xml 主要配置业务层和数据层 、数据源、 事务管理 ------ 将applicationContext.xml 分为service 、dao
编写代码时:将struts的action配置struts.xml , 将service配置到service.xml 将dao 配置到dao.xml
action、service、dao 都是使用xml配置, 实体类domain使用注解(省略hbm文件)
* 允许注入时,使用Autowired注解 (使用Autowired 需要 <context:annotation-config /> )
客户端前台页面 ------------------------- 使用jquery easyui 前端框架
为什么要使用easyui ? 很多团队,工程师主要是服务器端工程师,不熟悉页面开发 ------- CSS很差
** 很多前端UI框架,自带CSS模板,即使java工程师也可以写出非常漂亮的界面
为什么不用ExtJS? 要用EasyUI ?
因为ExtJS框架比较庞大,引入后,系统性能有问题,比较慢, EasyUI 轻量级js前端框架
你知道EasyUI 收费吗?
1.2.2 版本之前,使用 GPLv3 协议 , ,开源组织协议 ----- 免费
1.2.3 之后 GPL License Commercial License
使用版本1.3.2 --------- 去下载该版本easyui (是一套基于Jquery的前端UI框架,作用在于快速构建前端界面)
需要导入到工程的文件:
1、 locale 国际化信息文件
2、 plugin 所有插件 js文件
3、 theme 主题CSS
4、 jquery-1.8.0.min.js jquery核心包
5、 jquery.easyui.min.js 所有插件的合集 ====== plugins 里所有js
6、 easyloader.js 可以根据代码选择plugin中的插件
easyloader.js + plugin === jquery.easyui.min.js
学习曲线: 布局layout
<script type="text/javascript"
src="${pageContext.request.contextPath }/js/jquery-1.8.0.min.js"></script> ------------ jquery核心js
<script type="text/javascript"
src="${pageContext.request.contextPath }/js/easyui/jquery.easyui.min.js"></script> -------- easyui核心js
<script type="text/javascript"
src="${pageContext.request.contextPath }/js/easyui/locale/easyui-lang-zh_CN.js"></script> ----- 国际化信息
<link id="easyuiTheme" rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath }/js/easyui/themes/default/easyui.css"> ------ easyui核心css
<link rel="stylesheet" type="text/css"
href="${pageContext.request.contextPath }/js/easyui/themes/icon.css"> -------- 图标css
第一种 页面代码使用HTML编写,用easyui渲染,第二种 使用js 生成页面html
布局layout分为 东西南北中 ----- 中是必须的 ,东西南北都可以省略 。