"易班"——项目总结
1. 项目概述
"易班"项目是基于Java语言的一个Web项目,是一个学生和班级信息管理平台,它可以对学生或者班级信息进行增加,删除,改正,查询的一个信息平台,通过网页访问管理人员可以了解到实时的学生信息和班级信息,最直接的适用场景是适用于各个学校,对字段进行修改后也可以适用于公司,组织等等一切需要对人力资源信息进行管理的场景下,因此这个项目具有相当的实用性和必要性。
2.项目背景
总的来说,易班项目是我在学习了数据库和servlet、请求响应处理后、第一次尝试正式写一个项目,虽然来说项目并不算很复杂,但是重在学习实际应用中项目开发流程,也是为以后的学习和工作打下更牢固的基础。只学习没有实践会让知识掌握的不牢固,更何况对于我来说,一个项目的完成更能查找我在学习中忽略的漏洞和鉴定我的信心。
3. 项目应用到的技术
1.Maven
Maven是Apche下的一个纯java开发的开源项目,基于项目对象模型(POM),Maven是一个项目管理工具,可以对java项目进行构建,依赖管理。使用Maven像使用其他的构建工具一样,可以极大的提高工作效率。
使用Maven首先我们要创建一个项目对象模型(POM),POM的默认配置是pom.xml文件,它描述了程序及其相关性。简而言之就是我们在开发一个项目时需要一些特定的我们没有实现的类,这个时侯需要导入外部别人写好这个类并已经打成的jar包,导入到我们的Library中后我们就可以调用这些jar包中已经实现好的类。有了Maven之后我们可以省去繁琐的手动导入的步骤,直接通过pom.xml中的配置来获取jar包。
说到这里,我一直有一个误解就是Maven项目是独立于java项目和web项目的一种特有的项目类型,后来学习了大佬的解释才发现,其实在java学习中主要有两种项目,一个是普通java项目还有一个就是基于java的web项目,而所谓的Maven项目就是在上述的两个项目上套一个Maven框架,,其实就是加上之后我们可以在项目开发过程中使用一些Maven为我们提供的功能,方便我们进行开发,这也是为什么我们叫它项目管理工具的原因。
配置一个pom.xml大致就分为三个部分(个人总结可能不准确):
一、设置自己的信息
<groupId>iron-man</groupId>//项目作者的标识
<artifactId>yiban</artifactId>//项目的名字
<version>1.0-SNAPSHOT</version>//项目的版本
<packaging>war</packaging>//最终打包的格式
上面三个可能还很好理解,第四个打包形式可能有点疑惑,我们打包格式往往有两种形式一个是jar包就是我们普通的java项目,还有一种就是Web项目打包形成的war包,拿着这个war包布置到容器中,本项目来说就是Tomcat,将war包放在Tomcat目录下的\webapps\下,Tomcat会自动帮我们解压,相当于发布成功。
二、需要的别人的信息
<dependencies>//所有的依赖包
<dependency>//依赖包
<groupId>mysql</groupId>//项目名字
<artifactId>mysql-connector-java</artifactId>//一般是包名,也就是域名的反写
<version>5.1.48</version>//需要的jar的版本
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.10.3</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.8.2</version>
<scope>compile</scope>
</dependency>
</dependencies>
这个部分即是我这个项目开发时用到的那些依赖包,这些依赖包都有的三个属性是 groupId、artifactId、version 根据这三个信息,我们可以唯一确定一个我们需要的jar包。 scope这个的意思是,这个jar包只会在测试的时候用到。
三、编写完成后构建项目时的信息
<build>//构建项目时需要的配置
<finalName>sis</finalName>//最终打成包的名字比如这里就是sis.war
<plugins>//使用的所有插件列表
<plugin>//使用的某一个插件
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>//作为DOM对象的配置
<source>1.8</source>//配置源代码使用的开发版本
<target>1.8</target>//配置需要生成的目标class文件的编译版本
<encoding>UTF-8</encoding>//编码格式
</configuration>
</plugin>
</plugins>
</build>
Mawen项目目录结构:
2.JDBC
JDBC是基于java操作Mysql数据库的常用驱动包,同样编程语言和使用数据库的不同,所需要的驱动包也就不同,例如java语言操作Oracle数据库时需要的驱动包名字叫ojdbc。
JDBC的全称JAVA Database Connectivity,翻译过来就是java数据库连接。是一种用于执行SQL语句的java API(应用程序接口或者应用编程接口),说白了就是程序开发者通过编程软件直接访问数据库,直接面向已经抽象好的接口编程,在我们实际操作和数据库之间架起了一道桥梁。不仅仅是提高了工作效率,JDBC操作往往有其固定的步骤,最大的好处是程序的可移植性大大增强。
JDBC的连接往往分为六步,但是我想强调的是初学者比如我,往往忽略了导入数据库驱动包的过程,也就是导入jar包作为依赖,虽然在开发过程中往往不需要这一步,对于初学者有这种概念固然是没错的。
第一步:建立数据库链接
本项目中采用一个单例模式创建一个数据源DataSource,通过getDatasource().getConnection()的方式获取了一个数据库的连接,使用这种方式的好处是我们可以设置getDatasource()方法为私有属性,封装了连接数据库参数,并且只需要创建一次,以后返回的都是这个对象。只是外部提供了一个获取数据库连接的接口。
private static DataSource getDatasource() {
if (DS == null) {
//懒汉模式的单例
synchronized (DBUtil.class) {
if (DS == null) {
DS = new MysqlDataSource();
((MysqlDataSource) DS).setURL(URL);
((MysqlDataSource) DS).setUser(USERNAME);
((MysqlDataSource) DS).setPassword(PASSWORD);
}
}
}
return DS;
}
public static Connection getConnection() {
try {
return getDatasource().getConnection();
} catch (SQLException e) {
throw new RuntimeException("获取数据库连接失败", e);
}
}
第二步:需要执行的sql语句要进行预编译,也就是针对要对数据库完成的操作,写一条String类型的sql语句。
第三步:创建操作命令对象,这个对象包含了要查询的sql语言。
ps=c.prepareStatement(sql);
第四步:执行查询操作,拿到这个对象执行后返回的结果。
rs=ps.executeQuery();
第五步:对返回的查询结果集进行处理
第六步:释放资源,由于获取连接和释放资源在本项目中都应用了多次,所以写成了一个固定的DBUtil类提供了获取连接和释放资源的方法,使代码看起来更清爽。
public static void close(Connection c, Statement s){
//更新操作调用的是两个参数的重载方法
close(c,s,null);
}
public static void close(Connection c, Statement s, ResultSet r) {
//查询操作调用的是三个参数的方法
try {
if (c != null) {
c.close();
}
if (s != null) {
s.close();
}
if (r != null) {
r.close();
}
} catch (SQLException e) {
throw new RuntimeException("释放数据库资源失败", e);
}
}
3.Servlet
还是先说什么是Servlet,“Servlet是运行在Web服务器或应用服务器上的程序,它是作为来自Web浏览器或者其他Htpp客户端的请求和HTTP客户端的请求和HTTP服务器上的数据库或者应用数据之间的中间层”。如何理解这句话呢?
打开java源码就能发现,其实我们说的servlet就是一个接口,接口肯定是实现了某个功能,功能就是处理客户端和服务器端之间的请求和响应,它是处理这些的一套规范的流程。只不过这个流程需要处理请求的不同,所以他是一个接口,具体的处理步骤交给我们开发人员去实现。
至于servlet是怎么工作的?我们就可以大致理解为两个步骤:
第一个:处理来的请求比如,一个HTTP类型的请求过来,容器会把这个请求封装成servlet中的request对象,然后可以拿着这个对象获取你以可得到的所有的HTTP信息。
第二个:把数据封装成servlet中的response对象,容器再将这个response对象解析之后封装成一个HTTP响应再返回。就是一个完整的过程。
再来讨论一下servlet的生命周期:
不论java中什么谈到生命周期,其实都是一个创建到毁灭的过程。servlet也遵循这个过程,它的生命周期是。
*Servlet通过调用init()方法进行初始化。
*Servlet通过service()方法处理客户端请求。
*Servlet通过destroy()方法终止。最后被JVM垃圾回收期进行垃圾回收。结束工具人的一生。
多次提到servlet容器,目前我们常用的容器是tomcat,在下文也有介绍。
再回到项目中,因为本项目有多个servlet类而且除了调用dopost和doget的区别,其他过程都类似,因此我们采用模板方法的设计思想,模板方法就是提供一个统一的处理逻辑,在不同条件调用不同的方法。设计了一个抽象类继承了HttpServlet,重写了doget方法和dopost方法。这两种方法的执行流程我们已经确定,唯一的改变在于返回值是Object 的process抽象方法,这个方法里边才根据业务的不同,重写这抽象个方法达到我们设计一个模板方法的目的,采用这种方法好处是增加代码的复用性。
public abstract class AbstractBaseServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("UTF-8");
resp.setCharacterEncoding("UTF-8")<