1 分层;
2 封装;
3 发现问题本质,方法解决转化
4 字符串的拼接
5 一张表一个dao类一个servlet
6 根据隐含参数判断数据来源
7 数据放在哪,从哪取
8 命名统一 规范问题
二 针对上述介绍中,部分一般性规律:
1 分层;常见为src中
com.example.dao //数据访问层
com.example.daoimpl
com.example.entity(或者com.example.bean) //实体层 域模型层
com.example.service //业务逻辑层
com.example.service.impl
com.example.util //工具类层
com.example.web.cotroller //表现层
com.example.web.filter
com.example.web.formbean
com.example.web.listener
com.example.web.ui
com.example.util.test //工具测试类层
webRoot 中
js css jsp html imgs 等等,要注意分门别类存放
2 封装 面向对象的思维方式,共同的部分要抽取出来
三 创建一个新的Javaweb 项目
利用eclipse hbuilder 等创建一个Java web 项目,其中需要注意的地方
1、项目中,在创建src里的包层时,需要注意包层的名称需要用小写字母
2、包层的命名是 com为二级域名 example为三级域名,这个一般是公司域名倒写+名称
3、导包 导库 将用到的的第三方包 、库导入相应的文件夹
比如需要将数据库驱动程序jar包导入 web-inf 下的lib文件夹中
4、注意各处的字符编码是否统一,建议为utf-8
5、需要在清单文件中配置的项目要记得配置
四 常见的问题及分析:
1 数据库的连接(此处以MyEclipse 连接本地Oracle数据库 为例):
(1)如何在MyEclipse 中连接Oracle数据库?
准备阶段:首先要在本地计算机上正确安装Oracle 数据库软件,数据库管理客户端管理软件
扩展:具体的安装过程中可能出现一些问题比如:
1 为何数据库提示无法安装?
如果你的电脑之前安装过Oracle 数据库,在清理过程中未彻底清理干净会出现此问题,这里需要特别注意的是,Oracle 数据库特别霸道 变态,只要电脑中目前无论任何的文件夹、注册表等各种地方有一个与Oracle数据库相关的文件,都意味着未清理干净,具体我百度到了一个地址,介绍还算不错可以根据上面提示保证完全清理干净
https://wenku.baidu.com/view/df5196f3ba0d4a7302763ac7.html
http://blog.csdn.net/oceanaut/article/details/3863222
2 开启数据库需要的服务
连接数据库之前,一定要确保Oracle数据库的相关服务开启,否则无法使用,因为Oracle数据库没有界面显示,来证明是否开启,所以要检查oracle数据库最基本的服务是否开启
2 在使用Oracle数据库管理软件时,要Oracle数据库的账号 密码,怎么填?是多少?
这个在你安装Oracle数据库时需要填写的,所以在安装Oracle数据库时,要特别注意让你填写的东西 账号和密码一定要记住,这里要填的账号 密码就是当时填写的
软件连接部分: 打开eclipse———>点击上方的window选项——>open perspective-->MyEclipse Database Explore在左侧单击右键,出现一个连接数据库的信息列表单,driverManager templates: 数据库驱动程序的类型,这个会有MySQL sqlserver oracle 等各版本选项
driver name:这个随便填写,作为数据库的名称
Connection URl: 连接数据库的地址 jdbc:axiondb:
user name;用户名 这个就是你使用数据库的账号
password:密码 也好理解
driver jars: 这个就是你使用的数据库驱动程序的jar包的路径,可以通过文件选择功能找到,(并且这个jar包是需要复制粘贴到web项目中——>web Root ——>WEB-INF——>lib文件夹内)driver className:这个在你完成上一步之后会自动生成
到此就填写可以了,直接下一步或者完成就可。左边会产生一个服务器样式的文件夹,双击,正常会在该图标下产生文件,不报错,应该就是连接成功了
3 当然每个项目中需要有一个dao方法,连接数据库,具体的Java代码写法,后面介绍
(2)在项目的dao层中,要写一个与数据库进行连接的具体方法BaseDao的单独的类或者一个方法具体代码参考如下。(为了在本文档书写自动有提示,让类的内容显示有层次感,于是写在script中,因为script中接
受Java代码)
2 对于项目的分析
(1)
3 数据库中表的设计
数据库一般的三范式是要遵循的。
字段的取值范围的考虑
4 在数据库中建立表的方法
因为不同的数据库,一些细节方面略有不同,但是都有一些共通的地方
(1)利用数据库管理软件工具直接按照分析好的表结构,进行建表
对于主键等的设置,一般命名格式为
主键名为 pk_表名_字段名,
外键名为 fk_参考的表名_字段名
(2)利用sql语句在Java代码中进行创建
5 如何在Oracle 数据库中设置字段自增(比如主键id int 类型 自增为例)
oracle 数据库中,没有直接设置字段自增的控件,如果涉及,需要利用序列的形式进行
设置,具体方法以pl/sql 软件为例,假如需要设置以student 表中主键id(int)自增为例
在左侧sequences ——>右键单击——>new 建立一张序列表,序列表表名的命名格式为
seq_原表表名_自增字段名 seq_student_id
而在dao层添加数据的方法中,id列则不需要从外界获取值,添加方法的sql语句格式为
sql="insert into 表名(主键id,字段名2,..,字段名n) value(序列表表名.nextval,?,?,...?)";
例如:
sql="insert into student(id,name,age,..,address) value(seq_student_id.nextVal,?,?,...,?)"
在创建序列表时,注意内容的填写,以原表中新建,还未添加数据,且以int类型自增为例,序列表的填写
owner system (表示数据库用户名) next number 1 (因为原表中没有数据,从1开始)
Name seq_student_id (此处为序列表表名) increatment by 1 (表示每次自动增加1)
min value 1 (表示id从1 开始) Cache size 20 (表示数字的位数)
max value (此处不填默认为某个最大数值)
该处填写完,即表示序列表已经创建完成,不需要其他操作
6 当软件连接完数据库后,一般会开始新建一个web项目,然后在其中开始写实体类 数据库基本的增删改查的方法
实体类对应于数据库中的实体 包括常见的set get方法。
完成访问数据库的方法,为了更显层次,会创建接口dao dao对应的实现类
实现类中有基本的增删改查方法,如果可能,还可能需要创建根据条件进行查询、模糊查询等方法,这些应该在项目分析中考虑到。
7 创建用户界面 html 或者jsp 文件
在webRoot 下面创建 文件夹 js css imgs 方便对各种资源文件进行管理
新创建html 或者jsp 文件时,注意更改字符集,
8 创建html(静态网页) jsp(动态网页)中需要注意的问题:
(1) 注意网页布局和样式、 代码的分层独立
(2) 注意网页中应该记得导入与该网页相关的css js jQuery 等相关的文件
9 创建好网页之后,即可开始书写业务逻辑层,完成前后台的逻辑对接
10 网页布局中 div css 浮动 定位 清除浮动之间有哪些规律?
11 书写服务层的一般逻辑:
(1) 从网页获取暗含的请求参数、判断逻辑需求,根据需求确定服务类别,因为一张表可能对应一个服务类,里面有多个服务
(2) 获取请求页面的请求参数(这里的请求参数和业务相关)reques.getParameter("");
(3) 调用相应的dao层的方法
(4) 根据dao方法返回的结果,进行业务处理
12 书写服务层是最常见的字符编码问题如何解决?
(1) 利用过滤器,直接将所有相关的配置进行字符过滤处理
(2) 将涉及到的所有可能出现乱码等问题的地方进行字符设置处理
常见的情景有:
a 服务类里,第一件事,加入 request.setCharsetEncording("utf-8");
b 每项服务中,如果涉及将数据库中的数据取出来,传到网页,则设置响应对象 response.setCharsetEncording("utf-8");
13 项目中,日期类的格式转换问题,怎么解决?
(一)如果bean 中实体类导入的包是Java.util 包,则以学生类 student 为例:
1、实体类中的日期set get方法各自的书写
2、dao 中,添加add 方法中,关于日期的项 语句书写
3、servlet中,
(1)完成添加含有日期的数据的功能时, 从网页html 或者jsp 时,获取请求参数
String time=request.getParameter("birthday_day");
//假设网页上生日是通过input标签 name="birthday_day"传入
//因为网页传过来的都是字符串,所以此句是一定的。
Student student=new Student();
student.setBirthday(?);
StudentDao dao=new StudentDao();
dao.add(student);
(2)完成根据条件查询数据,从数据库中查询到数据后的处理;
StudentDao dao=new StudentDao();
List
//如果此处是将查询到的list 作为结果返回到jsp界面
request.setAttribute("result",list);
request.getRequestDispatcher("index.jsp").forward(request,response);
4、网页中
(二)如果bean 中实体类导入的包是Java.sql 包,则以学生类 student 为例:
1、实体类中的日期set get 方法各自的书写
2、dao 中,添加add 方法中,关于日期的项 语句书写
3、servlet中,
(1)完成添加含有日期的数据的功能时, 从网页html 或者jsp 时,获取请求参数
String time=request.getParameter("birthday_day");
//假设网页上生日是通过input标签 name="birthday_day"传入
//因为网页传过来的都是字符串,所以此句是一定的。
Student student=new Student();
student.setBirthday(?);
StudentDao dao=new StudentDao();
dao.add(student);
(2)完成根据条件查询数据,从数据库中查询到数据后的处理;
StudentDao dao=new StudentDao();
List
//如果此处是将查询到的list 作为结果返回到jsp界面
request.setAttribute("result",list);
request.getRequestDispatcher("index.jsp").forward(request,response);
4、 网页中
14 请求转发与重定向有何区别?
请求转发:服务器行为,request.getRequsetDispatcher().forward(requset,response);是一次请求,转发后请求对象会保存,地址栏的URL地址不会改变。(服务器内部转发,所有客户端看不到地址栏的改变)
重定向:客户端行为,response.sendRedirect(),从本质上讲等同于两次请求,前一次的请求对象不会保持,地址栏的URL地址会改变。
(1) 地址栏中是否发生变化?
请求转发地址不改变
(2) 哪个可以携带请求参数?
请求转发可以携带
深入细解:
HTTP中的重定向和请求转发的区别
一、调用方式
我们知道,在servlet中调用转发、重定向的语句如下:
request.getRequestDispatcher("new.jsp").forward(request, response);
//转发到new.jsp
response.sendRedirect("new.jsp"); //重定向到new.jsp
在jsp页面中你也会看到通过下面的方式实现转发:
当然也可以在jsp页面中实现重定向:
<%response.sendRedirect("new.jsp"); %> //重定向到new.jsp
二、本质区别
解释一 一句话,转发是服务器行为,重定向是客户端行为。为什么这样说呢,这就要看两个动作的工作流程:
转发过程:客户浏览器发送http请求——》web服务器接受此请求——》调用内部的一个方法在容器内部完成请求处理和转发动作——》将目标资源发送给客户;在这里,转发的路径必须是同一个web容器下的url,其不能转向到其他的web路径上去,中间传递的是自己的容器内的request。在客户浏览器路径栏显示的仍然是其第一次访问的路径,也就是说客户是感觉不到服务器做了转发的。转发行为是浏览器只做了一次访问请求。
重定向过程:客户浏览器发送http请求——》web服务器接受后发送302状态码响应及对应新的location给客户浏览器——》客户浏览器发现是302响应,则自动再发送一个新的http请求,请求url是新的location地址——》服务器根据此请求寻找资源并发送给客户。在这里location可以重定向到任意URL,既然是浏览器重新发出了请求,则就没有什么request传递的概念了。在客户浏览器路径栏显示的是其重定向的路径,客户可以观察到地址的变化的。重定向行为是浏览器做了至少两次的访问请求的。
解释二
重定向,其实是两次request 第一次,客户端request A,服务器响应,并response回来,告诉浏览器,你应该去B。这个时候IE可以看到地址变了,而且历史的回退按钮也亮了。重定向可以访问自己web应用以外的资源。在重定向的过程中,传输的信息会被丢失。
例子:
response.sendRedirect("loginsuccess.jsp");
请求转发是服务器内部把对一个request/response的处理权,移交给另外一个对于客户端而言,它只知道自己最早请求的那个A,而不知道中间的B,甚至C、D。传输的信息不会丢失。
例子:
RequestDispatcher dis=request.getRequestDispatcher(“loginsuccess.jsp”);
Dis.forward(request,response);
解释三
假设你去办理某个执照
重定向:你先去了A局,A局的人说:“这个事情不归我们管,去B局”,然后,你就从A退了出来,自己乘车去了B局。
转发:你先去了A局,A局看了以后,知道这个事情其实应该B局来管,但是他没有把你退回来,而是让你坐一会儿,自己到后面办公室联系了B的人,让他们办好后,送了过来。
15 如何确定用请求转发还是重定向?
了解上述详细内容后,对于简单的问题,一般可遵循这个原则:
(1)在服务中,对于一般的查询性质的,用请求转发,其他的多数时候用重定向(到本服务,执行本servlet中的某个服务)
(2)如果需要传递参数,除了用户登录账号、密码等可以用cookie (response.sendRedirect();request.getSession())进行设置,其他一般的用请求转发;
(3) 不需要传递参数的,一般为重定向;
16 页面转换,如何准确使用绝对路径和相对路径?
"/" 表示根目录,也就是项目中
"../" 表示到上一级目录
在jsp页面中,为了防止因为绝对路径因文件移动等产生问题,一般都会使用相对路径,而不是绝对路径,基本上在所有的jsp的界面中都加入类似这种相对路径的引用语句,当然如下,还可以进行适当的修改
第一句利用请求对象request 获取当前路径的getContextPath();
第二句 request.getScheme() 返回当前链接使用的协议;比如,一般应用返回http;SSL返回https;
复习一下request 的常用方法:
request.getSchema()可以返回当前页面使用的协议,http 或是 https;
request.getServerName()可以返回当前页面所在的服务器的名字;
request.getServerPort()可以返回当前页面所在的服务器使用的端口,就是80;
request.getContextPath()可以返回当前页面所在的应用的名字;
<%
String path = request.getContextPath();
String basePath=request.getScheme()+"://"+request.getServerName()+":"+
request.getServerPort()+path+"/";
%>
而在
标签内部通过以下方式引用
17 如何修改tomcat配置,解决中文乱码问题?
在开发过程中,遇到中文乱码的问题。以前的解决办法是:用JAVA代码进行转换,今天请教了一下公司的高手,给出的解决方案是:修改Tomcat的配置文件也可以解决这个问题。
具体的解决方案是:
1.在Tomcat目录下找到server.xml文件,找到代码:
2. 把上面的代码注释掉,用下面的代码代替:
3. 注意Tomcat的端口号,我的Tomcat的端口品号是 80,所以 port="80"。请你修改成你自己的Tomcat的端口号。
18 如何修改eclipse 或者myeclipse 中的字符集问题?
打开windows——> preferences——>general——>workSpace
19 如何设置eclipse 或者myeclipse 中自动提示信息功能?
打开windows——> preferences——>Java——>editors
打开windows——> preferences——>xml——>editors
20 单元测试:
注意:测试用例是用来达到测试想要的预期结果,而不能测试出程序的逻辑错误。
①测试方法上必须使用@Test进行修饰
②测试方法必须使用public void 进行修饰,不能带任何的参数
③新建一个源代码目录来存放我们的测试代码,即将测试代码和项目业务代码分开
④测试类所在的包名应该和被测试类所在的包名保持一致
⑤测试单元中的每个方法必须可以独立测试,测试方法间不能有任何的依赖
⑥测试类使用Test作为类名的后缀(不是必须)
⑦测试方法使用test作为方法名的前缀(不是必须)
2.JUnit常用注解
* @Test:将一个普通的方法修饰成为一个测试方法
@Test(expected=XX.class)
@Test(timeout=毫秒)
* @BeforeClass:它会在所有的方法运行前被执行,static修饰
* @AfterClass:它会在所有的方法运行结束后被执行,static修饰
* @Before:会在每一个测试方法被运行前执行一次
* @After:会在每一个测试方法运行后被执行一次
* @Ignore:所修饰的测试方法会被测试运行器忽略
* @RunWith:可以更改测试运行器 org.junit.runner.Runner
1.1 测试代码和项目代码分开
结构应如下:包名要一致;最好以Test作为测试类后缀;最好以test作为测试方法前缀。
在Java中,一般是建立一个与src同层次的资源文件夹,命名为test 在其中建立和src中一样的包名,并且建立和src中相应包下相同的类,只是鉴于习惯,会将这里的类名命名为在原类名基础上加个Test而已
在测试类里,假设测试src文件夹下,com.examlple.dao 包下 StudentDao 类中的public int add(Student student),方法,则需要写的就是
在项目中与src同层,建立一个test 资源文件夹,其中建立一个com.example.dao 包,在包中建立一个StudentDaoTest类, 类中写入
@Test //注解,必须写
public void testadd(){ //方法必须以public void 修饰,加方法名其中,不得带任何参数
Student stu=new Student(); //因为被测试的方法需要一个参数
stu.setid="小明";
StudentDao dao=new StudentDao();
int abc=dao.add(stu);
Assert.assertEquals(3,abc); //调用该方法 断言 第一个参数是预期值,第二个参数是实际测验值
}
21 sql语句防注入如何做?
22 sql 基本语句:
原则:
---先在主表添加数据,再在子表添加数据
---先删除子表数据,再删除主表数据
查询语句:
-select<*|列名,...列名> from 表名 where 条件1 and 条件2......
例:
select t.*, t.rowid from student t
select *from student
select name,id from student
select name "姓名",id as 编号 from student
select * from student where id ='U003'--等值条件查询
select * from student where name like '孙%'--模糊查询,查询孙开头的
select * from student where name like '%悟%'
select * from student where name like '_悟_'
select * from student where name like '_悟_'and site like '222%'
select * from student where name like '_悟_'or phone like '%888%'
select * from student where id='U002'or ID='u005'or id='U004'
select * from student where id in('U002','u005','U004')
添加语句:
nsert into 表名(字段名1,字段名2,...,字段名n) values(参数值1,参数值2,...参数值n);
insert into student (id,name,age,phone,gender,email,site,address) values ('U010','李四',22,'44444','男','[email protected]','555.com','四海');
修改语句:
update 表名 set 字段名1=参数值,字段名2=参数值,..where 条件
update 表名 set 字段名1=参数值,字段名2=参数值,..where 字段名i=参数值i
update student set name='111',phone='110' where name like '_悟_'
删除语句:
delete from 表名 where 条件;
delete from score where student_id='U001';
23