软件工程开发流程:1、瀑布模型 2、螺旋模型
RUP (Rational Unified Process,统一软件开发过程 ) 采用瀑布模型: 需求 --- 需求分析 --- 系统设计(概要、详细设计)---- 编码 --- 测试 --- 实施 --- 维护
* 瀑布模型 缺陷在编码结束之前,客户看不到最终软件产品 ,如果需求、设计出现明显错漏,导致软件后期无法维护,存在重大缺陷
* 瀑布模型对于 新型软件,需求不定软件 风险较大
敏捷开发理念:迭代开发模式 ,将系统功能分成若干批次 ,对每部分功能实施瀑布模型流程 ,系统随时看到开发结果,始终存在可用软件产品
* 增量开发 ,中途发现设计错误,很容易调整
1、需求 客户信息增删改查
2、系统设计
数据库设计 E-R图
创建数据库 create database customersystem;
* 每个软件都会为数据库创建单独用户并授权
创建用户:create user flower identified by ‘flower‘;
授权:grant all on customersystem.* to flower;
创建数据表
create table customer (
id varchar(40) primary key not null,
name varchar(20) unique not null,
gender varchar(10) not null,
birthday date not null,
cellphone varchar(20) not null,
email varchar(40) unique not null,
preference varchar(100),
type varchar(40),
description varchar(255)
);
----------------------------------------------------
启动navicat lite ---- 创建Connection(name随意写,填写用户名、密码)
双击打开连接
在连接上右键点击 new Database --- 创建数据库 customersystem
双击数据库 开发数据库
在数据库/Table右键 new Table ---- 创建数据表 customer
在工具上方点击manager users --- Add User 创建 flower用户
点击用户展开后 具体数据库 ---- select All 为用户flower 授予 customersystem 所有权限
----------------------------------------------------
系统功能设计
1) 技术选型 mysql + Servlet + JSP + EL +JSTL + BeanUtils + c3p0 + DBUtils
2) 搭建工程环境
创建customermanager 工程 ,将jar包复制 WEB-INF/lib
准备c3p0配置文件
3) 创建package 结构 (javaee三层结构)
cn.itcast.customer.web
cn.itcast.customer.service
cn.itcast.customer.dao
cn.itcast.customer.domain
cn.itcast.customer.utils
使用c3p0、DBUtils ---- 需要工具类
实体类 Customer
4) 发布客户管理系统 ----- 虚拟主机方式
配置tomcat/conf/server.xml 添加虚拟主机 www.customer.com ---- 路径指向工程根目录
<Host name="www.customer.com" appBase="D:\work\myclipse\work20120605\customermanager" ...>
修改本地hosts文件 添加域名解析 ---- 127.0.0.1 www.customer.com
将工程下发WebRoot 配置缺省虚拟目录 <Context path="" docBase="WebRoot" />
5) 设计 增加、查询、删除、修改 四个功能 --- UML Unified Modeling Language (UML)又称统一建模语言或标准建模语言
绘制UML工具 很多:Rantional Rose、Microsoft Visio、starUML 、jude(纯java开发)
* UML 做软件 建模(分析设计) : 用例图、类图、时序图
-----------------------------------------------------------------------------------------
企业开发中 UML 序列图 : 以时间顺序 描述系统功能流转
编码
1、客户信息添加
add.jsp(编写客户添加form表单 JS表单校验) ----- AddCustomerServlet(web层 封装form数据到JavaBean对象中;传递JavaBean给业务层处理) ---- CustomerService(业务层) --- CustomerDAO(数据层 完成表插入) ---- web层会根据业务层处理结果 选择跳转页面
2、查看(所有)客户信息
index.jsp (提交链接) ------ ListCustomersServlet(web层,直接调用业务层获得结果) ---- CustomerService(业务层) --- CustomerDAO(数据层 完成所有客户信息查询) ---
web层根据业务层结果选择跳转页面(list.jsp) ---- list.jsp(JSTL+EL 显示List结果)
3、客户信息删除
单行删除 (在每行数据后面 都可以提供删除按钮/链接) ---- 点击链接 删除该行显示数据
list.jsp(删除链接) ------ 提交客户编号DelCustomerServlet(获得编号,传递编号业务层) ---- CustomerService(业务层传递编号数据层) --- CustomerDAO(delete) --- web层决定跳转页面(list.jsp在显示list.jsp之前先查询所有数据 , 跳转ListCustomersServlet )
* 在删除功能上添加确认操作 (JavaScript)
方案一:阻止href默认事件
FF e.preventDefault()
IE window.event.returnValue = false;
方案二:链接没有提交,在js中判断用户确认删除,用js提交链接事件 location.href
批量删除 (在每行数据之前添加 checkbox )
* 全选JS操作,全部选中、全部取消
* 批量删除添加确认 onsubmit="return confirmBatchDel()"
* 批量删除过程中,添加事务管理
4、客户信息修改操作
流程一:客户信息查询
list.jsp(每行数据后面添加修改链接) ---- ShowCustomerServlet(接收编号传递编号业务层) --- CustomerService --- CustomerDAO ---- web层会接收 返回customer对象,传递customer对象到jsp (update.jsp 将数据回显form中)
流程二:客户信息修改
update.jsp (包含隐藏id所有客户信息) ---- UpdateCustomerServlet(封装form数据到javabean,传递javabean给业务层) ---- CustomerService --- CustomerDAO ---- web层跳转客户信息列表页面(/listCustomers)
-----------------------------------------------------------------------
为什么需要分页?数据过多,一页内无法显示,分页显示
分页技术实现:两种
物理分页:在数据库执行查询时(实现分页查询),查询需要的数据 ---- 依赖数据库SQL语句
逻辑分页:先查询所有数据到内存,再从内存截取需要数据 ------- 采用程序内部逻辑
物理分页:Mysql /SQLServer / Oracle 每种数据库写法不同的
mysql 使用limit ,SQLServer 使用top 、Oracle使用rowNum
limit语法 : select .... limit 开始记录索引,记录条数
select * from table limit 10,20; // 索引从0开始 10代表11条 ------ 从11查询30条
逻辑分页:查询所有数据 List, list.subList 截取你需要数据
例如:查询11-30条 list.subList(开始索引,结束索引); // 前取到,后取不到 ----- list.subList(10,30);
** 性能上 :物理分页好于逻辑分页 ---- 尽量使用物理分页
分页页面效果:
首页 上一页 1 2 3 4 5 6 7 下一页 尾页 跳转XX页
* 首页哪页 -- 1 尾页哪页 - ?
* 页码不能全部显示 (google以当前页页码为中心,前后各10页) ---- 左面显示最小页码(首页) 右面显示最大页码(尾页)
* 总页数
重构上午编写分页查询 :分页查询都会用单独类来封装查询结果 PageBean ----- 在业务层返回数据返回PageBean对象
------------------------------------------------------------------------------------------------------------------
条件查询 :单条件和复合条件
单条件查询,在页面内提供select框,用户选择查询字段,输入值
list.jsp ---- 提交查询条件 ConditionQueryServlet(获得条件 传递业务层) ---- CustomerService --- CustomerDAO --- web层获得结果,将结果传递list.jsp显示
* 因为很多字段选择,所有每个字段处理方式可能不一样 姓名模糊查询 手机等值查询,if判断处理
* 模糊查询时,不知道查询条件 like ‘%%‘;代表任意字符串 --- 查询所有数据
---------------------------------------------------------------------
系统功能:
1、客户信息添加
2、客户所有信息查询
3、客户信息删除(单行删除、批量删除)
4、客户信息修改
5、添加分页查询
6、单条件选择查询
import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Locale; import org.junit.Test; public class DateFormatTest { @Test public void demo3() { // 设置locale Locale locale = new Locale("ja", "JP", "JP"); Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL, locale); System.out.println(dateFormat.format(date)); } @Test public void demo2() { // 使用自带样式格式化日期 // 1 只要日期 Date date = new Date(); // 有四种显示模式 FULL, LONG, MEDIUM, SHORT DateFormat df1 = DateFormat.getDateInstance(DateFormat.SHORT); System.out.println(df1.format(date)); // 2 只要时间 DateFormat df2 = DateFormat.getTimeInstance(DateFormat.FULL); System.out.println(df2.format(date)); // 3 日期和时间都要 DateFormat df3 = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL); System.out.println(df3.format(date)); } @Test public void demo1() { // 对日期进行格式化 自定义格式 Date date = new Date(); DateFormat dateFormat = new SimpleDateFormat("yyyy年MM月dd日 HH时mm分ss秒"); System.out.println(dateFormat.format(date)); } }
import java.text.MessageFormat; import java.util.Calendar; import java.util.Date; import java.util.Locale; import org.junit.Test; public class MessageFormatTest { @Test public void demo2() { // 日期时间 国际化、货币数字国际化 String msg = "At {0,time,short} on {0,date,medium}, a hurricance destroyed {1} houses and caused {2,number,currency} of damage"; Calendar calendar = Calendar.getInstance(); calendar.set(1998, 6, 3, 12, 30, 0); Date date = calendar.getTime(); Object[] args = { date, 99, 1000000 }; // 默认国家 Locale String result = MessageFormat.format(msg, args); System.out.println(result); // 设置Locale MessageFormat format = new MessageFormat(msg, Locale.US); String result2 = format.format(args); System.out.println(result2); } @Test public void demo1() { // 动态文本消息 国际化 ,将内容用 {数字} 占位 String msg = "At {0} on {1}, a hurricance destroyed {2} houses and caused {3} of damage"; Object[] args = { "12:30 pm", "jul 3,1998", 99, "$1000000" }; System.out.println(MessageFormat.format(msg, args)); } }
import java.text.DateFormat; import java.text.NumberFormat; import java.text.ParseException; import java.util.Date; import java.util.Locale; import org.junit.Test; public class NumberFormatTest { @Test public void exec() throws ParseException { // 请创建一个date对象,并把date对象中表示日期部分的时间值,以及表示时间部分的时间值,分别以short、long模式进行格式化输出(国家设置为中国)。 Date date = new Date(); DateFormat dateFormat = DateFormat.getDateTimeInstance( DateFormat.SHORT, DateFormat.LONG, Locale.CHINA); System.out.println(dateFormat.format(date)); // 09-11-28 上午10时25分39秒 CST 还原Date ---- DateFormat parse String s = "09-11-28 上午10时25分39秒 CST"; Date date2 = dateFormat.parse(s); // 解析时,确认原来字符串显示模式 System.out.println(date2); // 请将整数198,输出为货币形式:$198,并将$198反向解析成整数198。 int n = 198; String m = "$198"; NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US); format.setMaximumFractionDigits(0); System.out.println(format.format(n)); System.out.println(format.parse(m)); // 请将0.78654321,输出百分比格式,保留两位小数 double d = 0.78654321; NumberFormat format2 = NumberFormat.getNumberInstance(); format2.setMaximumFractionDigits(2); format2.setMinimumFractionDigits(2); System.out.println(format2.format(d)); } @Test public void demo3() { // 显示百分比 double d = 0.78123; NumberFormat format = NumberFormat.getPercentInstance(); // 显示两位小数 format.setMaximumFractionDigits(2); format.setMinimumFractionDigits(2); System.out.println(format.format(d)); } @Test public void demo2() { // 货币格式化 int d = 100; // 显示 美元 NumberFormat format = NumberFormat.getCurrencyInstance(Locale.US); System.out.println(format.format(d)); } @Test public void demo1() { // 保留小数有效位数 double d = 1.235456674567546; // 保留两位小数 NumberFormat format = NumberFormat.getNumberInstance(); // 最大两位小数 format.setMaximumFractionDigits(2); // 最小两位小数 format.setMinimumFractionDigits(2); System.out.println(format.format(d)); } }
import java.util.Locale; import java.util.ResourceBundle; import org.junit.Test; public class ResourceBundleTest { @Test public void demo2() { // 读取文件时,设置我的国家 Locale locale = new Locale("en", "US"); ResourceBundle bundle = ResourceBundle .getBundle("myproperties", locale); // 读取en_US System.out.println(bundle.getString("name")); } @Test public void demo1() { // 使用ResourceBundle读取配置文件 ,不设置国家 ResourceBundle bundle = ResourceBundle.getBundle("myproperties"); // 默认选择哪个文件? 英国 --默认 ,中国 --- zh_CN // 系统国别 优先级 > 默认 System.out.println(bundle.getString("name")); } }