相关资料网盘链接:
提取码 :0u04
P1——CRM阶段简介:
web项目开发:如何分析,设计,编码,测试。
形成编程思想和编程习惯。
P2——CRM的技术架构:
- 视图层(View):展示数据,跟用户交互,html,css,js,jquery(对js的封装的框架),bootstrap|ext|easyUI,jsp(封装html,css,js的框架)。
- 控制层(Controller):
- 业务层(Service):
- 持久层:(Dao/Mapper):
P3~P5——技术架构
crm技术架构:
视图层(View):
展示数据,跟用户交互(html、css、js)
(jquery(js框架)(bootstrap框架)—类似—(ext框架(Ajax框架))—类似—(easyUI框架),jsp
控制层(Controller):
控制业务处理流程(接受请求,接受参数,封装参数;根据不同的请求调用业务层处理业务;根据处理结果,返回响应信息)
(servlet)springMVC—类似(—webwordk—类似—struts1—类似—struts)
业务层(Service):
处理业务逻辑(处理业务的步骤以及操作的原子性)。
javase技术(工作流:实现复杂业务逻辑(activiti | JBPM框架)),
例:添加学生
1.添加学生
2.记录操作日志 (1.2必须同时成功,否则都会失败)
持久层(Dao/Mapper):
操作数据库。
(jdbc(加载、驱动、创建、连接),mybatis(封装jdbc)—类似—hibernate—类似—ibatis)
hibernate:tb1_table(数据表)—操作类—POJO
整合层:
维护类资源(IOC),维护数据库资源(AOP)
spring(IOC,AOP)—类似—(ejb,corba)
P6:阶段教学目的:
1.对软件公司和软件开发有一定了解
2.了解CRM项目的核心业务
3.能够独立完成CRM项目核心业务的开发
4.对前期所学技术进行回顾,熟练,加深和扩展
5.掌握互联网基础课:Linux,redis,git。
P7~P11:软件开发申明周期:
一、软件公司的组织结构
研发部(程序员,美工,DBA) ,测试部,产品部,实施部,运维部,市场部
二、软件开发的生命周期:
1.招标:
投标——————标书
甲方: 乙方:
2.可行性分析:——————可行性分析报告(技术、经济)
3.需求分析: ———————需求文档
产品经理 ,需求调研
项目原型:容易确定需求,开发项目时作为jsp网页。
4.分析与设计:
整体性问题:
架构设计:
物理架构设计:
应用服务器:tomcat(Apache),weblogic(bea–>oracle),websphere(ibm) ,jboss(redhat),resin(MS)
web javaee:13种协议 (servlet,jsp,xml,jdbc,mq…)
数据库服务器:mysql,oracle,DB2,sqlserver,达梦
逻辑架构设计:
代码分层:视图层——控制层——业务层——持久层——数据库
技术选型:java,.net
项目设计:
物理模型设计:哪些表,哪些字段,字段的类型和长度,以及表和表的关系
(powerdesigner)——————xxx.pdm
逻辑模型设计:哪些类,哪些属性和方法,方法的参数和返回值,以及类和类之间的关系。 (rational rose)——————.pdl
界面设计:企业级应用 互联网应用
算法设计:————————算法设计文档
5.搭建开发环境:——————技术架构文档
创建项目,添加jar包,添加配置文件,添加静态页面,添加公共类以及其他资源;能够正常启动运行
6.编码实现: ——————注释
7.测试:————测试用例
8.试运行:————使用手册
9.上线:——————实施文档
10.运维:——————运维手册
11.文档编写
P12~P13:CRM核心业务介绍:
(1)CRM项目简介:
Customer Relationship Management 客户关系管理系统 (企业级应用——传统应用)给销售或者贸易型公司使用,在市场,销售,服务等各个环节中维护用户关系。
CRM项目的宗旨:增加新客户,留住老客户,把已有客户转化为忠实客户。
(2)CRM是一类项目,此CRM项目给大型的进出口贸易公司来使用的,做大宗商品进出口贸易;商品受国家管制。
(3)CRM项目的核心业务:
系统管理功能:不是直接处理业务数据,为了保证业务管理的功能正常安全运行的而设计的功能——用户登录、安全退出,登录验证等——给超级管理员、开发和运维人员使用。
业务管理功能:处理业务数据
市场活动:市场部,设计市场活动,营销活动
线索:销售部(初级销售),增加线索
客户和联系人:销售部(高级销售),有效的区分和跟踪客户和联系人
交易:销售部(高级销售),更好的区分和统计交易的各个阶段
售后回访:客服部,妥善安排售后回访。主动提醒。
统计图表:管理层,统计交易表中各个阶段的数据
P14~P16:物理模型设计:
系统管理功能相关数据表:
tbl_user :用户表
tbl_dic_type:数据字典类型表
tbl_dic_value:数据字典值
业务管理功能数据表:
tbl_activity:市场活动表
tbl_activity_remark:市场活动备注表
tbl_clue:线索表
tbl_clue_remark:线索备注表
tbl_clue_activity_relationship:市场活动与线索关联关系表
tbl_customer:客户表
tbl_customer_remark:客户备注表
tbl_contacts:联系人表
tbl_contacts_remark:联系人备注表
tbl_contacts_customer_relationship:联系人与客户关联关系表
tbl_tran:交易表
tbl_tran_remark:交易备注表
tbl_tran_history:交易历史表
tbl_task:任务表
(1)主键字段:在数据库表中,如果有一组字段能够唯一去确定一条记录,则可以把它们设计成表的主键,推荐使用一个字段做主键,而且推荐使用没有业务含义的字段做主键,比如:id等。
主键字段的类型和长度由主键值的生成方式决定:
主键值的生成方式:
1.自增:借助数据库自身主键生成机制——数值型
长度由数据量决定 ——————运行效率低——开发效率高
2. assigned:程序员手动生成主键值,唯一非空,按照算法生成
生成主键值的算法:hi/low:数值型 长度由数据量决定
UUID:生成字符串的主键 长度为32位
3.共享主键:该主键由另一张表的类型和长度决定
4.联合主键:由多个字段的类型和长度决定
(2)外键字段:用来确定表和表之间的关系。
1.一对多:
一张表(A)中的一条记录可以对应另一张表中(B) 的多条记录,B中的一条记录只能对应A中的一条记录。
添加数据时,先添加父表记录,再添加子表记录
删除数据时,先删除子表记录,再删除父表记录
查询数据时,可能会进行关联查询(连接查询):
内连接:查询所有符合条件的数据,并且要求结果在两张表中都有相对应的数据
左外连接:查询左侧表中所有符合条件的数据,即使在右侧表中没有相对的数据——右外连接
如果外键不能为空,优先使用内连接;
如果外键可以为空,假如只需要查询那些在另一张表中有相应的数据,使用内连接。假如需要查询左侧表中所有符合条件的记录,使用左外连接
2.一对一:
(1.)共享主键(不推荐)
添加数据:先添加先产生的表,再添加后产生的表记录
删除数据:先删除后产生的表记录,再删除先 产生的表记录
查询数据:无需进行连接查询
(2.)唯一外键
一对一就是一种特殊的一对多。
操作与一对多完全一样
3.多对多:一张表(A)中的一条记录可以对应另一张表中(B) 的多条记录,B中的一条记录也能对应A中的多条记录。
添加数据时,先添加父表记录,再添加子表记录
删除数据时,先删除子表记录,再删除父表记录
查询数据时,可能会进行关联查询
(3)给关于日期和时间的字段:
1.
Date
date
time
datetime
或者都按照字符串处理:
char(10)yyyy-MM-dd
char(19) yyyy-MM-dd HH:mm:ss
2.创建crm数据库实例:
把sql脚本导入数据库实例
P17~P19:搭建开发环境
步骤
(1)创建项目:crm_project 设置JDK
创建工程:crm 补全目录结构 设置编码格式:UTF-8
(2)添加jar包:添加依赖——参考课件。
(3)添加配置文件:参考课件。
(4)添加静态页面资源
web应用根目录下(webapp)的内容都是不安全的,外界(无论谁)可以通过url直接访问;所以,一般为了数据安全,都会把页面放在WEB-INF下,因为WEB-INF目录下的资源是受保护的,外界不能直接访问。
css、js、img放在webapps下,访问时无需通过controller访问。
(5)把crm部署到服务器中
http://127.0.0.1:8080/crm/
用户访问项目首页,首先进入登录页面:
1.分析与需求:
2.分析与设计:
3.编码实现
4.测试
P20首页功能分析与设计
逻辑流程图:
P21首页功能实现Controller类
1.@Controller
2.RequestMapping(“/”):
理论上,给Controller方法分配url:http://127.0.0.1:8080/crm/, 为了简便,协议://ip:port/应用名称必须省去,用/代表应用根目录下的/。
com.bjpowernode.crm.web.controller.IndexController的代码:
package com.bjpowernode.crm.web.controller;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
@Controller
public class IndexController {
/*
理论上,给Controller方法分配url:http://127.0.0.1:8080/crm/
为了简便,协议://ip:port/应用名称必须省去,用/代表应用根目录下的/
*/
@RequestMapping("/")
public String index(){
//请求转发
return "index";
}
}
对应的mvc.xml的代码:
<!-- 配置视图解析器 -->
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"/>
<property name="suffix" value=".jsp"/>
</bean>
P22:首页功能实现页面层:
1.idea对html采用的默认编码格式为ISO…,对jsp采用的默认的编码格式为UTF-8。
2.将html—>jsp
(1)加入
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
(2)将文件后缀改为jsp
P23:首页功能测试以及由首地址跳转到登录页面的设计与分析:
1.一个资源目录一个Controller
P24:首页跳转到登录页面实现Controller层
同P21Controller编写原理相同
P25:首页跳转到登录页面实现页面层:
1.将login.html转换为jsp文件并更新地址——html中base标签的作用以及ctrl+R快捷键快速替换选中的代码
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
//对应url的值:http://127.0.0.1:8080/crm/
%>
<base href="<%=basePath%>">
P26:登录功能分析与设计:见项目说明文档
1.密码、账号不能为空。
2.密码、账号、账号过期(时限)、ip受限、用户状态(数据库的字段)、都不能登录成功。
3.登录成功后,所有业务页面显示当前用户的名称
4.十天内免登录。
5.登录失败,页面不跳转,提示错误信息。
6.登录成功后跳转到业务页面
逻辑流程图:
全局刷新:同步
局部刷新:异步
既全局又局部按情况定。
建立service类根据操作数据是否在同一张表中,在不同一张表中,新建service类
建立controller类根据操作数据是否在同一资源目录中,在不同中,新建controller类
P27:搭建Mybatis逆向工程运行环境:
1)简介:根据表生成mapper层三部分代码:实体类,mapp接口,映射环境。
2)使用mybatis逆向工程:
a)创建工程:crm-mybatis-generator
b)添加插件:
<build>
<plugins>
<!--myBatis逆向工程插件-->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
</plugin>
</plugins>
</build>
c)添加配置文件——generatorConfig.xml中:
数据库连接信息
代码保存的目录
表的信息
d)运行mybatis的逆向工程,根据指定的表生成java代码,并且保存在指定目录中。
P29:登录功能实现Mapper层和Service层:
1.在mapper中创建新的sql方法,完成对应xml。完成mapper的注解扫描测试
2.创建service方法,并完成包扫描配置。
P30:实现登录功能的controller层:
注意:验证登录是否成功的要求如何编写以及将json数据封装成实体类返回页面。
P31:登录功能实现页面层与优化登录实现代码:
1。防止js代码与html代码混乱,创建js文件
2.建立domain实体类封装登录信息
3.使用jquery获取指定 元素的指定属性的值:
选择器.attr(“属性名”); //用来获取那些值不是true/false的属性的值。
选择器.prop(“属性名”); //用来获取值是true/false的属性的值。 例如:checked,selected,readonly,disabled等
4.建立工具类,格式化时间
5.建立常量类
P32:登录成功之后显示业务主页面与名称:
1.把控制层(controller)代码中处理好的数据,传递到视图层(jsp),使用作用域传递:
pageContext:用来在同一个页面的不同标签之间传递数据。
request:在同一个请求过程中间传递数据。
session:同一个浏览器窗口的不同请求之间传递的数据
application:所有用户都共享的数据,并且长久频繁使用
的数据。
jstl语言,EL表达式
可自定义jstl样式的标签
P33:实现回车登录+模拟单击事件:
1.jquery事件函数的用法:
选择器.click(function({ //给指定的元素添加事件
//js代码
});
选择器.click(); //在指定的位置上发生单击事件
P.34:实现记住密码:
访问:login.jsp----->后台:.html:如果上次记住密码,则自动填上账号和密码;否则不填。
如何判断上次是否记住秘密?----上次登录成功,判断是否需要记住密码:如果需要记住密码,则往浏览器中写cookie;否则,删除cookie。
而且cookie的值必须是该用户的loginAct和loginPwd
----下次登录时,判断该用户有没有cookie:如果有,则自动填写账号和密码;否则,不写
而且填写的是cookie的值
------>浏览器显示
获取cookie:
P35:测试记住密码
P36:安全退出功能分析需求与设计:
P37:安全退出功能实现:
P38:登录验证功能需求分析:
防止仅通过网址就可以进入业务页面。
P39.登录验证功能实现技术分析:
1.登录验证
(1)过滤器:
(a)implements Filter{
--init
--post
--destroy
}
(b)配置过滤器:web.xml
(2)拦截器:
(a)提供拦截器类:implements HandlerInterceptor(
--pre
--post
--after
}
(b)配置拦截器:springmvc.xml
请求转发:直接写资源的名称
重定向:必须加项目的名字
P.40:实现登录验证功能
在springmvc.xml中分析那些页面应该拦截,哪些页面不应该拦截
P.41~P42:实现登录验证功能1
P.43:测试登录验证验证功能与分析页面分割技术:
页面切割技术:
(1).<frameset》和《frame》标签——html标签(重量级标签,占网速)。
《frameset》:用来切割页面。
《frameset cols=“20%,60%,20% rows=” 10%,80%,10%"》
《frame》:显示页面。
<frame src=“url”》
《frameset cols=“20%,60%,20% rows=” 10%,80%,10%"》
<frame src=“url1” name=“f1”》
<frame src=“url2” name=“f2”》
<frame src=“url3” name=“f3”》
《/frameset》
每一个《frame》标签就是一个独立的浏览器窗口。
<a href=“url” target=“f1” 》test</a》
(2).<div》和《iframe》——轻量级标签:
《div》:切割页面。
《div style="height:10% width="20% ”》
《iframe》:显示页面。
《div style="height:10% width="20% ”》
《iframe href=“url”》
《/div》
P44.分析工作台页面结构与显示工作台页面:
系统管理功能、业务管理功能
P45.实现点击工作台菜单显示工作台页面与市场活动需求分析:
创建市场活动
P36.介绍模态窗口以及使用:
模态窗口:widow.open(“url”,“_blank”);
本质是div,通过设置z-index的大小来实现的;
z-index初始参数为0,所以不显示;
需要显示时,将z-index改为>0即可。
bootstrap来控制z-index的大小。
控制模态窗口的显示与隐藏:
(1)方式一:通过data-toggle=“modal” data-target=“模态窗口的id”
(2)方式二:通过js函数控制:
选择器(选中div).modal(“show”);//显示
选择器(选中div).modal(“hide”);//隐藏
(3)方式三:通过标签的属性data-dismiss=" “属性的标签,自动关闭该标签所在的模态窗口
模态窗口的意义:
widow.open(“url”,”_blank");
模态窗口本质上只有一个页面,都是在原来的窗口上操作。
P47.设计显示市场活动主页面以及页面后台——P49.设计保存创建市场活动::
新建Activity的Sevice、mapper类,mapper类又mybatis的逆向工程创建,创建在对应的配置文件中配置——service(applicationContext.xml),mapper(applicationContext-dataSource.xml)。
P50.配置service和mapper层
根据返回值的知识点:方法的返回值定为父类的类型,真正返回的为子类的对象。
P51.实现保存创建市场活动Controller层:
根据java.util封装的UUID设置活动数据的主键。
activity.setId(UUID.randomUUID().toString().replaceAll("-",""));
并将其封装到工具类中。
活动数据表与用户表关系为多对一,根据create_by引入外键。
P52~P55.实现保存创建市场活动前台页面+测试:
根据需求编写js代码:
需求:
<script type="text/javascript">
$(function () {
//给”创建“按钮添加单击事件
$("#createActivityBtn").click(function () {
//弹出创建市场活动的模态窗口
$("#createActivityModal").modal("show");
});
//给保存按钮添加单击事件
$("#saveCreateActivityBtn").click(function () {
//收集参数
var owner = $("#create-marketActivityOwner").val();
var name = $.trim($("#create-marketActivityOwner").val());
var startDate = $("#create-marketActivityName").val();
var endDate = $("#edit-endDate").val();
var cost = $.trim($("#create-cost").val());
var description = $.trim(($("#create-description").val());
//表单验证
if (owner == "") {
alert("所有者不能为空");
return;
}
if (name == "") {
alert("名称不能为空");
return;
}
if (startDate != "" && endDate != "") {
//使用字符串的大小代替日期的大小
if(endDate<startDate){
alert("结束日期不能比开始日期小");
return;
}
}
/*
正则表达式:
1.语言,语法:定义字符串的匹配模式,可以用来判断指定的具体字符串是不是符合字符串的匹配模式。
2.语法通则(在js中使用):
(1)//:在js中定义一个正则表达式.var regExp=/...../;
(2)^:匹配字符串的开头位置
$:匹配字符串的结尾
(3) []:表示匹配指定字符集中的一位字符. var regExp=/^[abc]$/; var regExp=/^[a-z0-9]$/;
(4){}:匹配字数.var regExp=/^[abc]{5}$/;
{m}:匹配m次
{m,n}:匹配m~n次
{m,}:匹配m次或者更多次
(5)特殊符号:
\d:匹配一位数字,相当于[0-9]
\D:匹配一位非数字
\w:匹配所有的字符,包括字母、数字、下划线。
\W:匹配非字符,除了字母、数字、下划线之外的字符。
*:匹配0次或者多次,相当于{0,}
+:匹配1次或者多次,相当于{1,0}
?:匹配0次或者1次,相当于{0.1}
var regExp=/^(([1-9]\d*)|0)$/;
if(!regExp.test(cost)){
alert("成本只能为非负整数");
return;
}
//发送请求
$.ajax({
url:'/workbench/activity/saveCreateActivity.do',
data:{
owner:owner,
name:name,
startDate:startDate,
endDate:endDate,
cost:cost,
description:description
},
type:'post',
dataType:'json',
success:function(data){
if(data.code=="1")
{
//关闭模态窗口
$("#createActivityModal").modal("hide");
//
}else{
//提示信息
alert(data.message);
$("#createActivityModal").modal("show");
}
}
})
});
});
P56.创建市场活动时,清空上次创建填写的表单数据:
P57.介绍js日历插件及使用:
js日历:
一类问题:
(1)实现起来比较复杂。
(2)跟业务无关。
直接使用插件:
bootstrap-daetimpicker:
前端插件使用步骤:
(1)引入开发包: .js,.css
把开发包引入到jsp文件中:《link》《script》
(2)创建容器:《input type=“text”》《div》
(3)当容器加载完成之后,对容器调用工具函数.
p58~P59…演示bs_dateimepicker日历插件:
P60.给创建市场活动添加日历功能:
P61.分页查询市场活动需求分析
P62~P68.分页查询市场活动设计
返回json数据要么为实体类要么为map集合。
{}在json中表示的是对象。
在指定的标签中显示jsp页面片段:
选择器.html(jsp页面片段的字符串); ------>覆盖
选择器.append(jsp页面片段的字符串);------->追加
选择器.before(jsp页面片段的字符串);
选择器.after(jsp页面片段的字符串);
选择器.text(jsp页面片段的字符串);------->追加
例: $(“#tBody”).html(htmlStr);
$(“#tBody”).append(htmlStr);
P69.实现条件查询市场活动:
P71:改造分页查询函数:
P72~P76:分页翻页功能的实现
-
函数:如果一段用来完成特定功能的代码反复出现,可以封装成函数。
函数的参数:在编写函数的过程中,如果有一个或多个数据无法确定,则可以把这些数据定义成函数的参数(形参),将来由函数的调用者来传递参数的具体的值(实参)。
-
分页查询插件:bs_pagination
前端插件的使用步骤:
1.引入开发包
2.创建容器:
3.当容器加载完成之后,对容器调用工具函数
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%
String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
%>
<html>
<head>
<base href="<%=basePath%>">
<!-- JQUERY -->
<script type="text/javascript" src="jquery/jquery-1.11.1-min.js"></script>
<!-- BOOTSTRAP -->
<link rel="stylesheet" type="text/css" href="jquery/bootstrap_3.3.0/css/bootstrap.min.css">
<script type="text/javascript" src="jquery/bootstrap_3.3.0/js/bootstrap.min.js"></script>
<!-- PAGINATION plugin -->
<link rel="stylesheet" type="text/css" href="jquery/bs_pagination-master/css/jquery.bs_pagination.min.css">
<script type="text/javascript" src="jquery/bs_pagination-master/js/jquery.bs_pagination.min.js"></script>
<script type="text/javascript" src="jquery/bs_pagination-master/localization/en.js"></script>
<title>演示bs_pagination插件的使用</title>
<script type="text/javascript">
$(function() {
$("#demo_pag1").bs_pagination({
currentPage:1,//当前页号,相当于pageNo
rowsPerPage:10,//每页显示条数,相当于pageSize
totalRows:1000,//总条数
totalPages: 100, //总页数,必填参数.
visiblePageLinks:5,//最多可以显示的卡片数
showGoToPage:true,//是否显示"跳转到"部分,默认true--显示
showRowsPerPage:true,//是否显示"每页显示条数"部分。默认true--显示
showRowsInfo:true,//是否显示记录的信息,默认true--显示
//用户每次切换页号,都自动触发本函数;
//每次返回切换页号之后的pageNo和pageSize
onChangePage: function(event,pageObj) { // returns page_num and rows_per_page after a link has clicked
//js代码
alert(pageObj.currentPage);
alert(pageObj.rowsPerPage);
}
});
});
</script>
</head>
<body>
<!-- Just create a div and give it an ID -->
<div id="demo_pag1"></div>
</body>
</html>
页面元素:块元素、行元素
js的系统函数
1.eval() ——可直接执行js代码
var Str=" var a=100;";
eval(Str);
alert(a);
2.parseInt():将小数转换为整数 …
演示分页查询市场活动的过程:
- queryActivityByConditionForPage(1,10);
|->把pageNo,pageSize和查询条件一起发送到后台,查询数据
|->data
|->activityList:遍历List,显示列表
|->totalRows:调用工具函数,显示翻页信息
2.当用户切换页号或者每页显示条数时,pageNo,pageSize
|->翻页信息主动改变
|->手动刷新列表
|->把pageNo,pageSize和查询条件一起发送到后台,查询数据
|->data
|->activityLisst:遍历list,显示列表
|->totalRows:调用工具函数,显示翻页信息
P78.实现刷新市场活动列表时保存每页显示条数不变:
P79~P80.删除市场活动需求分析:
P81~P84.实现市场活动的全选和取消全选:
1.给元素添加事件语法:
(1)使用元素的事件属性:
onxxxxx=“funtion(){}”
(2)使用jquery对象:选择器.xxxx(function(){
//js代码
//this
});
只能给固有元素添加事件——固有元素当调用事件函数给元素添加事件时,如果元素已经生成,则这些元素为固有元素。
动态生成的元素:当调用事件函数给元素添加事件时,如果元素没有生成,叫动态元素。
(3)使用jquery的on函数给元素添加事件:父选择器.on(“事件类型”,子选择器,function(){
//js代码
//this
});
父元素:必须是固有元素,可以直接父元素,也可以是间接父元素。(原则固有父元素范围越小越好)
事件类型:跟事件属性和事件函数一一对应。
子选择器:目标元素,跟父选择器构成一个父子选择器
不但能给固有元素添加事件,还能够给动态生成的元素添加事件。
P86~P87.删除市场活动实现后端代码:
P88.删除市场活动实现前台页面:
1.js中截取字符串:
str.substr(startIndex,length);//从下标startIndex的字符开始截取,截取length给字符
str,substring(startIndex,endIndex)//从下标为startIndex的字符开始截取,截取到的下标为endIndex。
2.ajax向后台发送请求时,可以通过data提交参数,data的数据格式有三种格式:
(1)data:{
k1:v1,
k2:v2
…
}
劣势:只能向后台提交一个参数名对应一个参数值的数据,不能向后台提交一个参数名对应多个参数值的数据。只能向后台提交字符串数据
优势:操作简单。
(2)data:k1=v1&k2=v2&k3=v3…
优势:不但能够向后台提交一个参数名对应一个参数值的数据,还能向后台提交一个参数名对应的多个参数值的数据。
劣势:操作麻烦。只能向后台提交字符串数据。
(3)data:FormData对象
优势:不但能提交字符串数据,还能提交二进制数据。
劣势:操作更复杂。
P89.修改市场活动
P94:设计保存修改的市场活动:
——————————————保存修改后的市场活动无业务流程逻辑图
1.封装参数:
(1)如果做查询条件,或者参数之间不是属于一个实体类对象,封装成map。
(2)如果做写数据,并且参数本来就是属于一个实体类对象,封装成实体类对象。
2.使用jquery获取或者设置指定元素的value属性值:
获取:选择器.val();
设置:选择器.val(属性值);
P99~P101.分析导出市场活动的应用场景:
导出市场活动:
1)给批量导出按钮添加单击事件,发送导出请求
2)查询所有的市场活动
3)生成一个excel文件,并且把市场活动写到excel文件中
4)把生成的excel文件双输出到浏览器(文件下载)——Web技术
P102~P105.介绍apache-poi插件并演示使用:
技术准备:
1)使用java生成excel文件:
图形化API——操作有格式的文件:excel、ppt
iText(收费,操作办公文档的插件:office)、apache-poi(free)
关于办公文档插件使用的基本思想:把办公文档的所有元素都封装成普通Java类,程序员通过操作这些类达到操作办公文档目的。
其中基本的类
文件-------------HSSFWorkbook
页----------------HSSFSheet
行----------------HSSFRow
列----------------HSSFCell
样式-------------HSSFCellStyle
使用apache-poi生成excel:
a)添加依赖:
<dependency>
<groupId>org.apache.poi</groupId>
<artifactId>poi</artifactId>
<version>3.15</version>
</dependency>
b)使用封装类生成excel文件
P106演示文件下载:
2)文件下载:
filedownloadtest.jsp
ActivityController
|->fileDownload()
所有文件下载的请求只能发送同步请求(因为响应信息为文件,ajax解析不了)
发送同步请求的三种方式:
1.超链接
2.form表单
3.地址栏
根据content-type来决定中文乱码的类型:
response.setContentType("application/octet-stream;charset=utf-8");
P109.实现导出市场活动Mapping与Service
P111.实现导出市场活动Controller层
P115优化导出市场活动
因为先在磁盘上写入数据,然后再在磁盘中取数据,所以效率低。
wb.write(os);——效率低
FileInputStream is = new FileInputStream(“G:\桌面\Test\activityList.xls”);——效率低
还有访问数据库效率低,数据库中的数据存储在磁盘上,所以一般很少访问数据库。
wb.write(out); wb.close();
在内存建立管道,
P.118-P.123分析导入市场活动的实现
1).把用户计算机上的excel文件上传到服务器(文件上传)。
2).使用java来解析excel文件,获取文件中的数据。
3).把解析出来的数据添加到数据库中。
4).返回响应信息。
技术准备:
1)文件上传:fileuploadtest.jsp
ActivityController
|->fileUpload()
2)使用java解析上传的文件:(图形化API)用插件:iText,apache-poi
关于办公文档插件使用的基本思想:把办公文档的所有元素都封装成普通Java类,程序员通过操作这些类达到操作办公文档目的。
文件-------------HSSFWorkbook
页----------------HSSFSheet
行----------------HSSFRow
列----------------HSSFCell
文件上传到表单三个条件:
1.表单主键标签必须用:
<input type="text|password|radio|checkbox|hidden|button|submit|reset|file> <select》,《textarea>等
2.请求方式只能用:post
get:get可以使用缓存,传输数据较少,安全性较低,参数通过请求头提交到后台,参数放在url后边,只能向后台提交文本数据;对提交的参数长度有限制;数据不安全;效率相对较高
post:参数通过请求体提交到后台;既能提交文本数据,又能够提交二进制数据;理论上提交的参数长度无限制;数据相对安全;效率相对较低
3.form表单的编码格式只能用:multipart/form-data
根据Http协议的规定,浏览器每次向后台提交参数,都会对参数进行统一编码;默认采用的编码格式是urlencoded,这种编码格式只能对文本数据进行编码,
浏览器每次向后台提交参数,都会首先把所有的参数转换成字符串,然后对这些数据统一进行urlencoded编码;
文件上传的表单的编码格式只能用multipart/form-data。
P124.设计导入市场活动:
功能执行完,页面是否跳转——是,同步,反之异步。
P125.实现导入市场活动的Controller层
文件上传:上传的文件一定跟用户约定好了。
P126.实现导入市场活动的前台页面
根据需求设置判断条件
js截取字符串
str.substr(startIndex,length);
str.substr(startIndex)//从下标是startIndex字符开始截取,截取到字符串的最后
str.substring(startIndex,endIndex);
P127.优化导入市场活动:
查看市场活动明细:
弄清楚市场活动与市场活动备注表之间的联系,外键。
P129:实现查看市场活动明细前台页面
1.使用标签保存数据,以便在需要的时候能够获取到这些数据:
给标签添加属性:
如果是表单组件标签,优先使用value属性,只有value属性不方便使用时,使用自定义属性;
如果不是表单组件标签,不推荐使用value属性,推荐使用自定义属性。
获取属性值时:
如果获取表单组件标签的value属性值:动漫对象.value jquery对象.val()
如果是自定义属性,不管是什么标签,只能用 jquery对象.attr("属性名”);
实现市场活动备注的详细信息:
jsp的运行原理:
xxx.jsp:
(1)tomcat中运行
把xxx.jsp翻译成一个servlet,运行servlet,运行的结果是一个html网页,把html网页输出到浏览器.
(2)html网页在浏览器上运行:
先从上到下加载html网页到浏览器,在加载过程中,运行前端代码,当页面都加载完成,在运行入口代码.
2.把页面片段显示在动态显示在页面中:
3.给元素扩展页面:
符合标识符的命名规则即可
P133.修改市场活动备注设计:
135:分析数据字典表的分析与使用: