开发说明
使用自定义的数据表(member),包含:编号(用户自己输入,不能重复)、姓名、生日、个人的收入、个人的信息介绍。要求完成如下的功能:
范例:数据库创建脚本
drop table if exists member;
create table member(
mid varchar(50) primary key,
name varchar(50),
birthday DATE,
salary float,
note BLOB,
del int
);
del描述的是一个逻辑的删除信息字段项,该字段有两个取值:0表示没有删除,1表示被删除;
随后为了方便进行项目的维护,需要对项目的组成进行说明:
- WEBROOT → WEB项目(虚拟目录配置到此路径)
|- css: 保存所需要的样式文件;
|- js: 保存所有的*.js文件,但是这些文件需要同jsp的路径保存;
|- images: 保存所有图片
|- pages:保存所有的页面信息,对于程序本身会分为前台和后台两类程序
|- back:保存所有的后台用户信息;
|- admin:保存所有的模块页面的目录;
|- member: 保存所有用户操作的相关页面;
|- front:保存所有的前台页面信息;
WEB项目中的CLASSPATH
在Java编程里面,用户要想使用一些第三方的程序类,直接配置环境属性就可以进行类加载了,而这个环境属性就是简单的CLASSPATH,但是到了WEB阶段,对于CLASSPATH会很多:
- TOMCAT_HOM/lib:将所有的*.jar文件直接设置在Tomcat之中,这些所有Tomcat发布的项目都能使用到这些程序类;
-
WEB项目/WEB-INF/lib:该目录可以直接保存*.jar文件,但是这些*.jar只允许该用户访问,通过buildpath导入会自动加载到这里;
- WEB项目/WEB-INF/classes:保存所有的"包.类",这也是CLASSPATH,会将src中的直接输出到build/classes中
相当于在src中建立的类可以在Tomcat启动后直接使用。
范例:定义一个DatabaseConnection程序类
package cn.ren.util.dbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
public class DataBaseConnection {
private static final String DRIVER = "com.mysql.jdbc.Driver"; // 驱动程序
private static final String URL = "jdbc:mysql://127.0.0.1:3306/bjpowernode" ;
private static final String USER = "root";
private static final String PASSWORD = "3530553606" ;
private static ThreadLocal<Connection> threadLocal = new ThreadLocal<Connection>() ;
public static Connection getConnection() {
Connection conn = threadLocal.get() ;
if(conn==null) {
conn = rebuildConnection() ;
threadLocal.set(conn);
}
return conn ;
}
public static Connection rebuildConnection() {
try {
Class.forName(DRIVER);
return DriverManager.getConnection(URL,USER,PASSWORD) ;
} catch (Exception e) {
return null;
}
}
public static void close() {
Connection conn = threadLocal.get() ;
if(conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
threadLocal.remove();
}
}
}
当项目执行之后该文件类会自动编译为*.class文件保存在“WEB-INF/classes”目录里面,那么就意味着可以直接在pages指令文件里面使用import导入程序类。
范例:在页面之中导入程序类
<%@ page language="java" contentType="text/html; charset=UTF-8"%>
<%@ page import="cn.ren.util.dbc.*" %>
<html>
<head>
<title>测试数据库连接</title>
</head>
<body>
<%=DataBaseConnection.getConnection() %>
<%DataBaseConnection.close(); %>
</body>
</html>
项目开发准备
首先将一些准备的程序类文件创建完成,随后将一些样式表或者js公用的一些文件配置上:
1、配置资源文件的读取类
package cn.ren.util;
import java.util.ResourceBundle;
public class MessageUtil {
private ResourceBundle resource = null;
public MessageUtil(String baseName) {
this.resource = ResourceBundle.getBundle(baseName) ;
}
public String getText(String key) {
return this.resource.getString(key) ;
}
}
2、建立好相应的资源文件:cn.ren.util.message.dao.properties、cn.ren.util.message.service.properties
3、建立业务层的动态代理类,负责数据库的打开与关闭以及相应的事务控制
package cn.ren.util.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import cn.ren.util.dbc.DataBaseConnection;
public class ServiceProxy implements InvocationHandler{
private Object target = null ;
public Object bind(Object target) {
this.target = target;
return Proxy.newProxyInstance(target.getClass().getClassLoader(), target.getClass().getInterfaces(), this) ;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object retObject = null ; // 接收返回对象
if(method.getName().startsWith("add")
|| method.getName().startsWith("edit")
|| method.getName().startsWith("delete")) {
DataBaseConnection.getConnection().setAutoCommit(false);
try {
retObject = method.invoke(this.target, args) ;
DataBaseConnection.getConnection().commit();
} catch (Exception e) {
DataBaseConnection.getConnection().rollback();
} finally {
DataBaseConnection.close();
}
} else {
try {
retObject = method.invoke(this.target, args) ;
} catch (Exception e) {
e.printStackTrace();
} finally {
DataBaseConnection.close();
}
}
return retObject;
}
}
还不完整,这里只定义了三个,随后再改。
4、创建程序的工厂类
package cn.ren.util.factory;
import cn.ren.util.MessageUtil;
import cn.ren.util.proxy.ServiceProxy;
public class Factory {
private final static MessageUtil DAO_MESSAGE = new MessageUtil("cn.ren.util.message.dao");
private final static MessageUtil SERVICE_MESSAGE = new MessageUtil("cn.ren.util.message.service");
@SuppressWarnings("unchecked")
public static <T> T getDAOInstance(String daoName) {
String className = DAO_MESSAGE.getText(daoName);
T t = null ;
try {
t = (T) Class.forName(className).getDeclaredConstructor().newInstance() ;
} catch (Exception e) {
e.printStackTrace();
}
return t ;
}
@SuppressWarnings("unchecked")
public static <T> T getServiceInstance(String serviceName) {
String className = SERVICE_MESSAGE.getText(serviceName);
T t = null ;
try {
t = (T) new ServiceProxy().bind(Class.forName(className).getDeclaredConstructor().newInstance()) ;
} catch (Exception e) {
e.printStackTrace();
}
return t ;
}
}
5、创建VO类
package cn.ren.util.vo;
import java.io.Serializable;
import java.util.Date;
public class Member implements Serializable {
private String mid;
private String name ;
private Date birthday ;
private Double salary ;
private String note ;
private Integer del ;
// 略
}
6、 定义公共的DAO接口:IBaseDAO,建立所有可能使用到的公共方法
package cn.ren.util.dao;
import java.sql.SQLException;
import java.util.List;
public interface IBaseDAO<K,V> {
public boolean doCreate(V vo) throws SQLException ;
public boolean doUpdate(V vo) throws SQLException ;
public boolean doRemove(V vo) throws SQLException ;
public V findById(K id) throws SQLException;
public List<V> findAll() throws SQLException;
public List<V> findAll(Integer currentPage, Integer lineSize) throws SQLException;
public List<V> findAllSplit(Integer currentPage, Integer lineSize, String colunm, String keyword) throws SQLException;
public Integer getAllCount() throws SQLException;
public Integer getAllCountSplit(String colunm, String keyword) throws SQLException;
}
这些公共操作的代码部分,只写这一次,以后将复制粘贴使用;
7、将公共的js、css拷贝过来
8、考虑到以后会进行一些代码的重用配置,所以最好的做法是建立一些文件,而后将这些文件在需要的地方导入到一起,按照如下模式拆分(经验)(拆分后的页面保存在pages/plugins目录中):
- include_script.jsp:这个页面负责导入公共的*.js。
<link rel="stylesheet" type="text/css" herf="css/style.css">
<script type="text/javascript" src="js/comm/ren_util.js"></script>
- include_basepath.jsp文件:该文件主要负责base标签的设置
<%
String basePath = request.getScheme() + "://" + request.getServerName() + ":"
+ request.getServerPort() + request.getContextPath() ;
%>
<base herf="<%=basePath%>"/>
- include_head.jsp:保存所有的头部信息
<%@ page language="java" pageEncoding="UTF-8"%>
<html>
<head>
<title>request资源定位</title>
<jsp:include page="/pages/plugins/include_script.jsp"/>
<jsp:include page="/pages/plugins/include_basepath.jsp"/>
</head>
<body>
- include_foot.jsp:保存所有的尾部信息
<%@ page language="java" pageEncoding="UTF-8"%>
</body>
</html>
对于页面显示乱码的jsp指令设置,必须每个页面都要提供。
实现用户增加
1、需要创建IMemberDAO 接口,该接口直接继承IBaseDAO接口,并实现该类的子类MemberDAOImpl
2、修改dao.propertie追加相应的配置项
3、创建IMemberService操作接口,主要完成增加用户的处理,实现子类MemberServiceImpl
package cn.ren.service;
import cn.ren.util.vo.Member;
public interface IMemberService {
/**
* 本业务需要进行以下操作:<br>
* 1、通过IMemberDAO.findById()判断用户ID是否存在;<br>
* 2、如果不存在使用IMemberDAO.doCreate()进行追加处理;<br>
* @param vo
* @return
* @throws Exception
*/
public boolean addd(Member vo) throws Exception;
}
6、配置service.properties
7、从实际开发来讲一定要编写junit的测试程序;
8、建立member_add.jsp的前端页面,需要放在指定目录下
同时创建member_add.js 文件
9、建立member_add_do.jsp 页面,该页面主要负责业务层的调用
后面更新