Day1,2
DDL(数据定义语言)语法 alter drop最底层的数据库语言 直接联系到数据库的结构
DDL((Data Definition Language),用于定义/修改/删除数据对象(如表)的数据结构,或者说,DDL语言操作的对象是数据库中的对象而非对象所包含的数据。
DDL包含以下语句:
- CREATE : 在数据库中创建新的数据对象
- ALTER : 修改数据库中对象的数据结构
- DROP : 删除数据库中的对象
- DISABLE/ENABLE TRIGGER : 修改触发器的状态
- UPDATE STATISTIC : 更新表/视图统计信息
- TRUNCATE TABLE : 清空表中数据
- COMMENT : 给数据对象添加注释
- RENAME : 更改数据对象名称
DML数据操作语言
Delete和Trancat
Trancat table 表示删除表格中所有数据,表结构还存在,但不会计入数据库日志。
属于DDL (数据定义语言) 大刀阔斧的改的
DCL: 授权语句:grant 权限 to user 。 remove 权限 from
TCL(Transaction Control Language)用来对事务进行管理。
TCL包含以下语句:
- COMMIT : 保存已完成事务动作结果
- SAVEPOINT : 保存事务相关数据和状态用以可能的回滚操作
- ROLLBACK : 恢复事务相关数据至上一次COMMIT操作之后
- SET TRANSACTION : 设置事务选项
CREATE TABLE 表名字
列名 INT(20) NOT NULL,PRIMARY KEY
建议脱离图形化界面数据库建模
进行修改
修改部门编号为50的部门所在地为北京
SQL中when case 的使用方法
Select xxxxx(
Case when 条件 then ‘起的名字1’
Case when 条件 then ‘起的名字2’
Case when 条件 then ‘起的名字3’
ELSE ‘异常’ END)
AS 给起的名字的所有给一个列名字
From XXXX
Group BY 的作用
Where语句和having语句有什么区别
where 子句的作用是在对查询结果进行分组前,将不符合where条件的行去掉,即在分组之前过滤数据,条件中不能包含聚组函数,使用where条件显示特定的行。
having 子句的作用是筛选满足条件的组,即在分组之后过滤数据,条件中经常包含聚组函数,使用having 条件显示特定的组,也可以使用多个分组标准进行分组。一般来说where在having前面
Select from where group by having.
Mysql多表联查
内连接 select * from emp inner join dept on emp.deptno=dept.deptno
不符合条件的记录不会出现在结果集里面
外连接:主表的记录一定会出现在结果里 例如right join时 右边的表为主表
外连接:当出现“不符合什么条件时,需要显示出数据”这种语句,即用外连接
Join的用法
子查询
使用in 和 exists
Exists返回的是一个ture和false的Boolean型的数据 但是依然要和exists内部的条件进行匹配
按照顺序排列
查询出 教学部 年龄大于20岁,并且工资小于40000的员工,按工资倒序排列.(要求:分别使用多表联合查询和内连接查询)
SELECT * FROM person p1 INNER JOIN dept d2 ON p1.did= d2.did
and d2.dname='python'
and age>20
and salary <40000
ORDER BY salary DESC; //排序按照倒序排列 大到小
ORDER BY salary ASC; //排序按照升序排列 小到大
列出所有员工的姓名及其直接上级的姓名,将没有上级的员工的上级处写为boss
Select e.name//员工的字段,if null(m.ename//上级的字段,’BOSS’) from emp e//主表为员工 left join emp m on e.mgr=m.empno;
补充:IFNULL(expr1,’eeee’)
如果expr1不是NULL,返回expr1,否则它返回expr2。
IF(expr1,expr2,expr3)
如果expr1是TRUE(expr1<>0且expr1<>NULL),那么IF()返回expr2,否则它返回expr3。
SQL中distinct的用法
在表中,可能会包含重复值。这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值。关键词 distinct用于返回唯一不同的值。
若想要查询多列比如说 select distinct name,nickname,department from photos
是将三列完全相同的内容过滤掉,但凡是有一列有所不同,均会列出来,而且只是列出不同的。
但是不能把distinct放在后面,如select nickname,department,distinct name from photos;报错,distinct必须放在开头。将distinct放到where里,也是报错。
Day3
在数据库设计中 的概念设计阶段中 这里的ER图中没有必要把root管理员和实体的联系都全部写出来
数据设计的详细步骤:
1、需求分析:分析系统功能,画出系统用例图和模块图。
2、找到每个功能的实体、属性及关系(要按照数据库范式去划分实体属性范围,同时按照数据完整性要求使用各种约束条件)
3、绘制出E-R图
4、根据E-R图画出关系表图(遵循的规则:一个实体就是一个表格,关系的转换:一对一关系,把其中任何一方主键放到另一方作为外键,一对多关系,把一方主键放到多方做外键,多对多关系:重新创建第三张表格,把两方的主键放到多方作为外键)
5、根据关系表图写sql指令创建出表格 。
Oracle数据库 没有自增的选项
面试题:什么是第一二三范式
范式:英文名称是 Normal Form,它是英国人 E.F.Codd(关系数据库的老祖宗)在上个世纪70年代提出关系数据库模型后总结出来的,范式是关系数据库理论的基础,也是我们在设计数据库结构过程中所要遵循的规则和指导方法。目前有迹可寻的共有8种范式,依次是:1NF,2NF,3NF,BCNF,4NF,5NF,DKNF,6NF。通常所用到的只是前三个范式,即:第一范式(1NF),第二范式(2NF),第三范式(3NF)。下面就简单介绍下这三个范式。
◆ 第一范式(1NF):强调的是列的原子性,即列不能够再分成其他几列。
考虑这样一个表:【联系人】(姓名,性别,电话)
如果在实际场景中,一个联系人有家庭电话和公司电话,那么这种表结构设计就没有达到 1NF。要符合 1NF 我们只需把列(电话)拆分,即:【联系人】(姓名,性别,家庭电话,公司电话)。1NF 很好辨别,但是 2NF 和 3NF 就容易搞混淆。
◆ 第二范式(2NF):首先是 1NF,另外包含两部分内容,一是表必须有一个主键;二是没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
考虑一个订单明细表:【OrderDetail】(OrderID,ProductID,UnitPrice,Discount,Quantity,ProductName)。
因为我们知道在一个订单中可以订购多种产品,所以单单一个 OrderID 是不足以成为主键的,主键应该是(OrderID,ProductID)。显而易见 Discount(折扣),Quantity(数量)完全依赖(取决)于主键(OderID,ProductID),而 UnitPrice,ProductName 只依赖于 ProductID。所以 OrderDetail 表不符合 2NF。不符合 2NF 的设计容易产生冗余数据。
可以把【OrderDetail】表拆分为【OrderDetail】(OrderID,ProductID,Discount,Quantity)和【Product】(ProductID,UnitPrice,ProductName)来消除原订单表中UnitPrice,ProductName多次重复的情况。
◆ 第三范式(3NF):首先是 2NF,另外非主键列必须直接依赖于主键,不能存在传递依赖。即不能存在:非主键列 A 依赖于非主键列 B,非主键列 B 依赖于主键的情况。
考虑一个订单表【Order】(OrderID,OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity)主键是(OrderID)。
其中 OrderDate,CustomerID,CustomerName,CustomerAddr,CustomerCity 等非主键列都完全依赖于主键(OrderID),所以符合 2NF。不过问题是 CustomerName,CustomerAddr,CustomerCity 直接依赖的是 CustomerID(非主键列),而不是直接依赖于主键,它是通过传递才依赖于主键,所以不符合 3NF。
通过拆分【Order】为【Order】(OrderID,OrderDate,CustomerID)和【Customer】(CustomerID,CustomerName,CustomerAddr,CustomerCity)从而达到 3NF。
第二范式(2NF)和第三范式(3NF)的概念很容易混淆,区分它们的关键点在于,2NF:非主键列是否完全依赖于主键,还是依赖于主键的一部分;3NF:非主键列是直接依赖于主键,还是直接依赖于非主键列。
保证数据的完整性
数据的完整性有四种分类
实体完整性
域完整性
参照完整性(引用完整性)
自定义完整性
约束的类型 格式的约束
在sql语句中进行check 约束 在sql的5.7版本无效
外键约束 两个表由外键统一管理非满足外键要求的是无法添加的
Mysql中日期操作
MySQL 为日期增加一个时间间隔:date_add():select date_add(@dt, interval 1 day);
MySQL 为日期减去一个时间间隔:date_sub():select date_sub('1998-01-01 00:00:00', interval '1 1:1:1' day_second);
MySQL 日期、时间相减函数:datediff(date1,date2), timediff(time1,time2):MySQL datediff(date1,date2):两个日期相减 date1 - date2,返回天数。
select datediff('2008-08-08', '2008-08-01');
select timediff('2008-08-08 08:08:08', '2008-08-08 00:00:00');
Day4
服务器tomcat可以随时接受来自于外部的请求HttpServletRequest 所有的外部的请求都要这样做
BS架构:浏览器与服务器架构 浏览器发出请求向服务器在服务器中找到servlet(在本次的项目中不涉及使用框架)进行处理数据
CS架构:客户端与服务器架构
传递method为post 能传输大量数据且不在地址栏里显示出
传递method为get 传递的数据会在地址栏显示出
css中的选择器通过id进行选择
#id的名字{
更改的样式
}
Css中的就近原则,哪个css选择器离被修改的主体越近就哪个管用
Id选择器>标签选择器(比如*)>
伪类选择器: a:active{
Color:red;
}
jQuery的选择器$(“#myimg”).click(function(){})
这一段的注解的意思是选择到id为myimg的div,触发click事件,并且在事件内部调用函数(内部功能没有写)
DOM模型
一、文档对象模型
DOM( Document Object Model)文档对象模型,它提供了访问、动态修改文档的借口,W3C指定了DOM规范,主流浏览器都支持。DOM由3部分组成,分别是CoreDom、XML DOM和HTML DOM。
1、Core DOM:也称核心DOM变成,定义了一套标准的针对任何结构化文档的对象,包括HTML、XHTML和XML。
2、XML DOM:定义了一套标准的针对XML文档的对象。
3、HTML DOM:定义了一套标准的针对HTML文档的对象。
二、认识DOM节点树。
三、访问DOM结点
1.使用getElement系列方法访问指定节点。
(1)getElementById():返回对拥有指定id的对一个对象的引用。
(2).getElementsByName():返回带有指定名称的对象的集合。
(3)getElementsByTagName():返回带有指定标签名的对象的集合
- 使用层次关系访问结点
(1)访问根节点:
有两种特殊的文档属性可用来访问根节点:
document.documentElement:第一个属性可返回存在于 XML 以及 HTML 文档中的文档根节点。
document.body:第二个属性是对 HTML 页面的特殊扩展,提供了对 <body> 标签的直接访问。
(2)访问父节点
parentNode:返回节点的父节点。
(3)访问兄弟节点
firstChild:返回节点的首个子节点。如果元素没有子节点则返回null。文本和属性节点没有子节点。如果是firefox浏览器会将空标签算在内。IE浏览器不计算空标签。
lastChild:返回节点的最后一个字节点,同 firstChild。 如果是firefox浏览器会将空标签算在内。IE浏览器不计算空标签。
通过dom模型使用js代码控制html页面
添加子节点是
Document.body.appendChild
p.appendChild();
appendChild是添加子节点的意思,前面的相当于路径
Day5
Js代码中的执行顺序是自上而下的 没有逻辑规则
jQuery中
$(‘’) 这个的意思是选择符和ajax是一样的
#btn5 找id为btn5的
.mini 找类class为mini的
Body>div 找body里的直接子元素div
.one+class 找class为one的下一个div元素
.one~class 找class为one的所有div兄弟元素
jQuery的还是写在script中 在head内部
一个js的表单验证(加粗部分)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head> <title>表单提交</title> </head>
<body>
<p align="center"><b>表单提交</b><br></p>
<center>
<div align="left">
<table height="60" border="0" align="left">
<tr>
<td> <form name="channelform" action="addChannel.jsp" onsubmit="return validate_channel_info(this);" method="post"> 名字:
<input type="text" name="channelname" /> <br /> ID: <input type="text" name="channelid" /> <br /> <input type="submit" value="提交"> </form> </td> </tr> </table>
<script type="text/javascript"> function validate_channel_info(channelform) { if(channelform.channelname.value=="") { alert("请输入正确的名字"); return false; } else if(!isNumber(channelform.channelid.value)) { alert("请输入合法ID"); return false; } return true; } function isNumber(str) // 判断是否为非负整数 { var rx = /^[0-9]+$/; return rx.test(str); } </script> </div> </center> </body> </html>
Servlet的入门
Servlet是一个在服务器上运行的小程序,是一个java的类,通过“请求-响应”的编程模式来访问服务器上的servlet
Servlet的运行步骤:第一步servlet的init初始化;第二步加载servlet的service;第三步加载别的方法例如doget dopost 但是init只有一次,没有第二次;第四步直接destory摧毁这个servlet
编写 servlet
A.继承 HTTPServlet,在创建时,直接指定父类
B.重写 doGet() 或者 doPost() 方法,右击 ->source->override
C.在 web.xml 中注册 Servlet
注意: 在使用 myeclipse2017 时,新建的 web 项目没有 web.xml 文件,
解决:在新建项目之后,填写完项目名,不要点 finish 要点 next,然后选中创建 web.xml 文件
使用 myeclipse 编写 servlet
1.src->new->servlet
2.重写 doGet()doPost()
3.部署运行
这个里面得web.xml需要重新在里面添加代码,因为servlet启动时候会自动加载某些servlet
代码如下:<servlet>
<description>This is the description of my J2EE component</description>
<display-name>This is the display name of my J2EE component</display-name>
<servlet-name>HelloServlet</servlet-name>
<servlet-class>servlet.HelloServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HelloServlet</servlet-name>
<url-pattern>/servlet/HelloServlet</url-pattern>
</servlet-mapping>
Dopost和doget是一样的 都是相同的注解文档
Day6(week2)
项目名字一般为小写
bootstrap移动端优先
Bootstrap通过栅格系统进行提供了一套流式栅格系统
Bootstrap 提供了一套响应式、移动设备优先的流式栅格系统,随着屏幕或视口(viewport)尺寸的增加,系统会自动分为最多12列。它包含了易于使用的预定义类,还有强大的mixin 用于生成更具语义的布局。
栅格的参数信息
Bootstrap主要运用在跨平台上,响应式布局,随着设备的变化而变化
每次在使用前都需要将bootstrap的核心文件进行下载
可使用以下代码下载核心css文件:
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
要在<body>最后使用上jQuery的功能,那就要加上:
<script
src="https://cdn.jsdelivr.net/npm/jquery@1.12.4/dist/jquery.min.js"></script>
<!-- 加载 Bootstrap 的所有 JavaScript 插件。你也可以根据需要只加载单个插件。 -->
<script
src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js"></script>
Bootstrap的head中要加成——> <head lang=”en”>
对于这个bootstrap不明白的 就在这个网去找,bootstrap的全局CSS样式
https://v3.bootcss.com/css/#grid-example-fluid
出现404的原因有哪些
HTTP Status 404(The requested resource is not available)异常主要是路径错误或拼写错误造成的,可按以下步骤逐一排查:
1.未部署Web应用
2.URL输入错误 a.查看URL的IP地址和端口号是否书写正确。 b.查看上下文路径是否正确 Project--------Properties------MyElipse-----Web----- Web Context-root检查这个路径名称是否书写正确。 c.检查一下文件名称是否书写正确。
3.目录不能被引用 在 Eclipse的“包资源管理器(Package Explorer)”检查文件存放的位置。由于META-INF WEB-INF文件夹下的内容无法对外发布,所以,如果你引用了带这两个目录的文件,肯定是不允许。 例如: http://localhost:8080/guestbook/WEB-INF/index.html就是错误的,文件位置存放错误
4. Tomcat服务器中web.xml中的问题 如果你的web应用程序有多个jsp页面的话,当你点击你web应用程序的虚拟根目录时可能会出现404错 误,只是你只需要修改Tomcat服务器中web.xml listings false(将其该为true)
举例:
Xml中默认的是
修改后的为
5.WEB-INF下面必须要有几个固定的文件夹和文件 web.xml 该web app的配置文件 lib 该web app用到的库文件 classes存放编译好的servlet 请注意他们的名字,我曾经就由于把classes写成class,查错查了半宿还没解决,所以写这些的时候千万要仔细,否则浪费更多的精力去查错。
6. 如果要运行的不是.jsp文件,而是servlet(.class)文件,要配置web.xml(当然是WEB-INF下面的),加上以下字段: HelloWorldServlet HelloWorldServlet HelloWorldServlet /HelloWorldServlet 其中的“HelloWorldServlet”改为你要运行的文件名
7.其他解决思路 以上方法无果,介于"HTTP Status 404(The requested resource is not available"异常发生情况的多样性,采用替换大法: 步骤: a.找一份正常的相同环境(找同学同事相同开发环境机子或者网上下载的正常demo等) b.依次替换问题项目文件,进行排除,定位.直到解决.
外置传入的Jar包放置在webcontent的WEB-INF的lib中
然而,xml的配置文件直接放在WEB-INF中
编写一个验证码小程序的思路大致
生成N位纯文字,将所有文字包含入数组内部,从而形成一个随机码,循环6次得到一个随机文字,保存在session内部,把字符串按照图片的形式显示出
请求转发://请求转发
/*if(result) {
request.getRequestDispatcher("index.jsp").forward(request, response);
}*/
重定向:response.sendRedirect("/dcp2019/index.jsp");
请求转发和重定向区别总结
l 请求转发是一次请求一次响应,而重定向是两次请求两次响应。
l 请求转发地址栏不会变化的,重定向地址栏发生变化。
l 请求转发路径不带工程名,重定向需要带工程名路径。
l 请求转发只能在本网站内部,重定向可以定向到任何网站。
使用kapkaptcha 介绍
kaptcha 是一个非常实用的验证码生成工具。有了它,你可以生成各种样式的验证码,因它是可配置的。kaptcha工作的原理是调用 com.google.code.kaptcha.servlet.KaptchaServlet,生成一个图片。同时将生成的验证码字符串放到 HttpSession中。
使用kaptcha可以方便的配置:验证码的字体、验证码字体的大小、验证码字体的字体颜色、验证码内容的范围(数字,字母,中文汉字!)、验证码图片的大小,边框,边框粗细,边框颜色、验证码的干扰线(可以自己继承com.google.code.kaptcha.NoiseProducer写一个自定义的干扰线)、验证码的样式(鱼眼样式、3D、普通模糊……当然也可以继承com.google.code.kaptcha.GimpyEngine自定义样式)、……
servlet使用方式
1建立一个web项目,导入 kaptcha-2.3.2.jar到环境变量中;
2.配置web.xml增加servlet
<servlet> <servlet-name>Kaptcha</servlet-name> <servlet-class> com.google.code.kaptcha.servlet.KaptchaServlet </servlet-class> </servlet> <servlet-mapping> <servlet-name>Kaptcha</servlet-name> <url-pattern>/kaptcha.jpg</url-pattern> </servlet-mapping> |
3在jsp页面中
<form action="submit.action" method="post"> <img src="kaptcha.jpg" id="kaptchaImage" /> <input type="text" name="kaptcha" value="" /> <input type="submit" name="submit" value="submit" /> </form> |
其中src="kaptcha.jpg"会被定位到servlet上
4、KaptchaServlet会把验证码设置到session中,可以如下方式获取
String kaptchaExpected = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); |
5、如果想设置点击图片更换验证码,可以加上如下js,需要jquery
<script type="text/javascript"> $(function(){ $('#kaptchaImage').click(function () { $(this).attr('src', '/kaptcha.jpg?' + Math.floor(Math.random()*100) ); }) }); </script> |
其他
如果想更改验证码的其他特性,具体使用方式请自行查找资料。这里不做过多介绍。
Spring MVC 整合 Kaptcha:https://www.jianshu.com/p/a3525990cd82
Day7
Servlet中不要在类中定义全局变量
session的整个过程
在session中存贮数据
在session中提取数据(session属性的类型为string类型不需要双引号)
创建session对话
HttpSession session = request.getSession(ture);//ture的含义是如果session创建了就拿来用,没有创建的话,就创建一手
session的销毁
Session超时失效
Jsp的简介
<%int a=2; %>这里的a是局部变量
<%! int a=2; %>这里的a是全局变量
Jsp开发的效率并不比servlet的开发效率低
JSTL:是一些标签,实质性是java代码的标签,尽可能的减少java语句和html语句的嵌套,可以使用类似于html的标签去代替一定的代码
比如这个<aa>可代表
JSTL使用步骤:1.使用taglib指令指定标记库的URI和前缀
out.jsp 和system.out.println 相同的效果
Value=”${useName}”的$符号直接获得username的值
If的jstl的语法
Choose when的语法规范
Foreach的语法规范,一般来说遍历数组用来
JSP的九个内置对象:
这九个内置对象
- request:请求(封装客户端请求信息,页面刷新一次就是一次新的请求)
Request.getParameter()//获取客户端参数
Request.setAttribute() //设置request的范围属性,数据传递,设置值
Request.getCookies() //设置自动登录使用,需要用到cookies
Request.getSession() //获取session的对象
- Session:会话(每个用户有自己的session)
session.setAttribute(“name”,value)//session赋值
Session.getAttribute()//取值
与Request.setAttribute()的区别
Request请求的开始与结束,一次请求
setMaxInactiveIntereval() //设置session的最大生命时间
默认的session生命周期为30min,30min内无反应,则关闭
- Application
服务器级别的,而且全局有且仅有一个,
生命周期与tomcat的相同,类似于集合,多应用。使用情形:统计在线人数(上线+1,下线-1)
- Response
服务器对客户端的响应
Response.sendRedirect(“url”) //重定向
Response.addcookies() //添加cookies
- Config
config 对象的主要作用是取得服务器的配置信息。通过 pageConext对象的 getServletConfig() 方法可以获取一个config对象。当一个Servlet 初始化时,容器把某些信息通过 config对象传递给这个 Servlet。 开发者可以在web.xml 文件中为应用程序环境中的Servlet程序和JSP页面提供初始化参数。
- Exception
在Java程序中,可以使用try/catch关键字来处理异常情况; 如果在JSP页面中出现没有捕获到的异常,就会生成 exception 对象,并把 exception 对象传送到在page指令中设定的错误页面中,然后在错误页面中处理相应的 exception 对象。
要先设定好错误页的引用<%@page errorPage=”xxxx.jsp”%>
在错误页中要设定好这个<%@ page isErrorPage=”ture”%>之后exception才起作用
- Out
out对象对象,对象类型是JspWriter类,相当于带缓存的PrintWriter(不带缓存)
PrintWriter:write(“内容”) 直接向浏览器输出内容
JspWriter:writer(“内容”) 向jsp缓冲区写出内容
- Page
page 对象代表JSP本身,只有在JSP页面内才是合法的。 page隐含对象本质上包含当前 Servlet接口引用的变量,类似于Java编程中的 this 指针。
- Pagecontext
可以获取其他内置对象
pageContext的对象类型是PageContext,叫jsp的上下文对象.
pageContext作用:可以获取其他八个内置对象
pageContext.getOut();
pageContext.getServletConfig()
Day8
今天使用到了MVC开发模式,总结下MVC开发模式
简单介绍这个项目是一个登录校验的一个项目
首先来说
整个src内的Java文件的摆放的位置
Controller层内部放置的是servlet,属于顶层的,是最早接收到来自于客户端的数据,并且控制层只负责接收数据,起到一个调度的作用,并不处理数据
Service层内部接收到数据后,处理该数据,将数据处理直至能与数据库里的数据为同一类型之后,即可跳转dao层
Dao层接收到由service层来的数据后,在内部发送并执行sql指令,得到处理结果集。Dao层是唯一一个和数据库打交道的层。
Po层里有着按照数据库里的类型进行封装的类,比如将customer封装
Util层里有着所需要用到多次的方法,顾将这些方法封装到类里,比如MD5加密,所以能够方便的多次去引用,按照类名.方法的形式。
整体逻辑:1.首先点击提交按钮——>把账号和密码,验证码都提交上到servlet中
- servlet验证验证码是否属实,属实就进行下一步
- 将数据组合成对象,交由给service层处理数据
- 将处理好的数据交付给dao层进行数据比对,若不为null就将获取的值全部返回,若为null,则就返回一个null
在dao层和service层内部都有着一个实现接口的类和一个接口
将整个功能全部封装在Java类中,接口调用这个类,但客户只能看到接口,而无法看到底层所实现的类,起到了隐私保护的作用
整个完整过程四个步骤
在最顶层的service层中不允许抛异常,所以在里面只能用try{}catch(){}语句
Day9,10
这两天一共实现了一个项目的一个添加司机信息的一个功能
下面是整个的业务逻辑:
在调试程序时候遇到的问题:
- 一直都显示不出来driver的信息表在main.jsp的位置:问题在于driver_form.jsp的这个的请求格式是method=”post”,但是之前的所有调用requestdispatcherServlet的方法都写在了get中
- 连接好之后,数据库里的数据调取不出来,sql语句中存在问题
- 连接好之后遇到的问题是乱码格式问题:乱码解决问题是在数据库和页面之间的格式转换有问题,解决方法在jdbc中加入设置utf8的属性
使得数据库和页面的数据可以完美匹配,智能进行转换,但不会影响之前的数据格式
String dburl = "jdbc:mysql://localhost:3306/dc?characterEncoding=utf-8";
Day11,12
- 过滤器的调用Fliter
面向切面编程的编程AOP 在annotation中定义其路径,与servlet相同,一样可以从web.xml中定义,如果定义的是/*则其含义是过滤所有web资源,他的优先级比同层次的servlet都高,放行的代码是chaindoFilter(req,resp);
定义filter中的encoding全局是req.setCharacterEncoding(UTF-8)
res.setCharacterEncoding(UTF-8)
注解时是按照谁先初始化谁就先执行,过滤器可多个存在
Webxml谁先配置,谁先执行
EL表达式中不能有任何一个空格要紧挨着
- 这两天实现了司机的编辑功能,还有更改乱码的一个过滤器,还有一个删除的功能:
Day13-15
- 在dao层中执行完sql语句有一个setStationName(getString(“station_name”));标蓝色区域要和数据库里的字段相同
- 在抛出异常之后有一个问题报错Exception class NotfoundException is not compatible with throws in XXXXDaoInterface.方法名 其解决方案是检查接口和实现层是否都有抛异常
- If语句的嵌套
if(语句1){
//语句块1
if(条件2){
//语句块2
}else{
//语句块3
}
}else{
//语句块4
}
- 解决if语句的嵌套
把所需要判断的部分加持在if的括号内部,用||和&&解决这个问题
&&且门 要满足两边都为真才能为真 ||与门有一边是为真那就为真
- Int和integer的区别
Integer是int的包装类 integer要实例化才能使用 而int不用
Integer i = new Integer();
- Js中有herf的出现的时候,在实现的过程中要使用post方式请求页面
- 编辑站点信息时出现的问题:在dolist中没有问题,在doadd中一开始使用了cs中的checkname方法,而且有多个checkname方法,在代码使用时就很容易引起误会。下次在写后端代码的时候,要首先先到zy.js中找自己要实现的功能 ;在.list中是显示在页面的,.form是是负责提交的,和一些检验的;一定要看清楚servlet中的注解到url里是否名字匹配;onlick时间是否跳转成功,到底是post还是get方法;而且在dao层里有一个是setsStationName(rs.getString(“Station_Name”));双引号中间的必然要和数据库里的字段重合
- 在地址栏中,若想要提价多项数据,以&为中间间隔号,比如id=1&name=sdfas&...
- 成员方法不能被类名.方法名访问,在方法前面加上static可用类名.方法名访问
- 修改js中的一系列东西很可能需要使用清理缓存
Day15~20
JDBC的事务
- con.setAutoCommit(false);默认为true,自动提交事务为false即手动提交
- 提交事务con.commit();
- 回滚事务con.rollback();取消在当前事务中进行的所有修改
Java的多线程的实现
- 继承Thread类创建线程
Thread类本质上是实现了Runnable接口的一个实例,代表一个线程的实例。启动线程的唯一方法就是通过Thread类的start()实例方法。start()方法是一个native方法,它将启动一个新线程,并执行run()方法。这种方式实现多线程很简单,通过自己的类直接extend Thread,并复写run()方法,就可以启动新线程并执行自己定义的run()方法。
- 实现Runnable接口创建线程
- 实现Callable接口通过FutureTask包装器来创建Thread线程
- 使用ExecutorService、Callable、Future实现有返回结果的线程
- 3和4的实现在https://www.cnblogs.com/felixzh/p/6036074.html
共享锁和排它锁
共享锁(S锁):共享 (S) 用于不更改或不更新数据的操作(只读操作),如 SELECT 语句。
如果事务T对数据A加上共享锁后,则其他事务只能对A再加共享锁,不能加排他锁。获准共享锁的事务只能读数据,不能修改数据。
排他锁(X锁):用于数据修改操作,例如 INSERT、UPDATE 或 DELETE。确保不会同时同一资源进行多重更新。
如果事务T对数据A加上排他锁后,则其他事务不能再对A加任任何类型的封锁。获准排他锁的事务既能读数据,又能修改数据。
我们在操作数据库的时候,可能会由于并发问题而引起的数据的不一致性(数据冲突)
产生共享锁产生共享锁的SQL:select * from ad_plan lock in share mode;
产生排他锁的SQL:select * from table for update --增删改自动加了排他锁
Next()和nextline()的区别
Next()遇到空格就停下来了 就输出了
Nextline()是遇到换行才会停下来 空格是可以读出来的
For循环中的for(x:y)的含义是x属于y的,并且会遍历y中所有元素
信鸽推送的实现
1.
设置推送消息,推送消息请求,设置title和内容
2.
XingeApp XingeApp = new XingeApp(2200257637L, "78d2a1972ebdb77bcd0f69504d2a326b");
括号里的第一个是ACCESSID 第二个是SERECTKEY
类似于一个信鸽的登录
3
以json字符串的形式返回,进行推送
Postman的使用方法:
进入主页面之后,我们会发现有我们刚刚建的Test1文件夹,我们点击进入。
然后我们找点get这个按钮,这里面有一些协议的选择,我们选项post请求。
选择之后我们在authotization这个选项选择No Auth这个选项。
然后Headers里面添加我们的以写token等信息。
页面的Body体我们填写我们的post请求接口参数即可。
最后我们需要我们访问的地址,然后点击send这个按钮,就可以正常发送post请求了。
实训的考试题中的陌生的
- 年龄BETWEEN 20 AND 30 表示包括20岁但不包括30岁
- 公司中有多个部门和多名职员,每个职员只能属于一个部门,一个部门可以有多名职员,从职员到部门的联系类型是
- sql的模糊查询
1、%:表示任意0个或多个字符。可匹配任意类型和长度的字符,有些情况下若是中文,请使用两个百分号(%%)表示。
比如 SELECT * FROM [user] WHERE u_name LIKE ‘%三%’
将会把u_name为“张三”,“张猫三”、“三脚猫”,“唐三藏”等等有“三”的记录全找出来。
2、_: 表示任意单个字符。匹配单个任意字符,它常用来限制表达式的字符长度语句:
比如 SELECT * FROM [user] WHERE u_name LIKE ‘三’
只找出“唐三藏”这样u_name为三个字且中间一个字是“三”的;
3、[ ]:表示括号内所列字符中的一个(类似正则表达式)。指定一个字符、字符串或范围,要求所匹配对象为它们中的任一个。
比如 SELECT * FROM [user] WHERE u_name LIKE ‘[张李王]三’
将找出“张三”、“李三”、“王三”(而不是“张李王三”);
4、[^ ] :表示不在括号所列之内的单个字符。其取值和 [] 相同,但它要求所匹配对象为指定字符以外的任一个字符。
比如 SELECT * FROM [user] WHERE u_name LIKE ‘[^张李王]三’
将找出不姓“张”、“李”、“王”的“赵三”、“孙三”等;
Substring
request_uri.substring(ctx_path.length()).equals("/kaptcha.jpg")
前面的减去后面的的长度是否和/kaptcha相同;
截取字符串,在java语言中的用法
1、 public String substring(int beginIndex)
返回一个新字符串,它是此字符串的一个子字符串。该子字符串始于指定索引处的字符,一直到此字符串末尾。
参数:beginIndex - 开始处的索引(包括),
返回:指定的子字符串,
异常:如果 beginIndex 为负或大于此 String 对象的长度,则抛出IndexOutOfBoundsException
例 :"unhappy".substring(2) returns"happy"
"mybaby".substring(3) returns"aby"
2、public String substring(int beginIndex, int endIndex)
返回一个新字符串,它是此字符串的一个子字符串。该子字符串从指定的 beginIndex 处开始, endIndex:到指定的 endIndex-1处结束。
参数:beginIndex - 开始处的索引(包括)
endindex 结尾处索引(不包括)。
返回:指定的子字符串。
抛出:如果 beginIndex 为负,或length大于字符串长度,则抛出IndexOutOfBoundsException
例:"hamburger".substring(3,8) returns "burge"
"smiles".substring(0,5) returns "smile"
数据库里的next()是什么意思
While(rs.next()){
Rs.getInt(1)//获取到查询结果集中的第一列的值
}
信鸽的管理平台
流程
[Push_Token] Push_Token是由信鸽生成的,对一个设备的标识(下文简称Token),用于对设备进行推送,是推送的最小单位。类似于uuid
答辩出现了一个问题
首先是ajax的异步请求的问题,为什么先出现的是js页面中的头名字,再出现的是数据库里的东西 是因为ajax的异步请求模式,ajax不设置async就是默认的true 即async:true;
在司机的dolist的地方,dolist中的时间没有显示出来,首先去dao层发现自己没有写createTime里的setTimestamp,但是还是在页面中显示的19700101,在driver_list中的createtime(在jsp中的翻页信息中去找这个值)必须和dao层中的driverSetCreateTime一样(标红的地方一样),但是还是出不来
项目总结
今天是最后一天答辩结束,老师问的问题其实很简单,一个是ajax异步调取数据,另一个是我出现的一个bug,现场调试,刚好这个问题涉及到了我可能是在这个项目中掌握的最不好的页面信息。 想想最开始的时候,刚刚开始写项目涉及到的关于dao层 service层 controller层的编写,当时很迷惑的一点是这些数据是从哪里传来的,是谁在做一个定向,每一次在web的annotation中写注释的时候也写的数据格式很混乱;到最后的时候还是在这个地方出错,每一处的数据都有着规范jsp中有着数据的名字规范(分页中的),数据库中的名字的规范,都要和这三个层相匹配;
除此之外,讲一讲整个的项目,一开始页面的编写和bootstrap的使用都是第一次用到,接着开始了MVC的开发模式,了解到了controller层是做调度的,接收请求、分发任务、响应信息;dao层是做和数据库打交道的;service层是做一系列的逻辑判断的;封装了jdbc连接(DBUtil类)数据库使得整个代码的复用率降低,做了几套关于司机和客服还有车站的增删改查,也发现了servlet写项目的弊端,需要大量的重复代码,很容易出现差错。在后期为了将项目的代码重复率降低使用了过滤器和一些自己定义的公共的类,并且使用的腾讯的信鸽系统来做信息的推送,学习了Redis高速缓存的使用方法,为了能让后期的手机端或者是微信小程序端进行调用,我们还编写了一些借口,在这里使用到了postman这个借口管理工具,但是代码的重复率依然很高。