这是一个高级 MVC 的例子,我是以大家最熟悉的学生表而编码的 。
数据库:mySql
开发工具:eclipse
基本的表:tb_stu(学生表),tb_class(班级表),tb_teacher(教员表)
tb_stu : sid(学生学号),sname(学生姓名),sex(学生性别),shobby(学生爱好),cid(班级id)
tb_class :cid(班级id),cname(班级名称),tid(教师id)
tb_teacher :tid(教师id),tname(教师姓名)
package com.dj.pageBean.entity;
public class Student {
private int sid;
private int cid;
private String sname;
private String sex;
private String shobby;
private String tname;
private String cname;
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getShobby() {
return shobby;
}
public void setShobby(String shobby) {
this.shobby = shobby;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public Student(int sid, String sname, String sex, String shobby, String tname, String cname) {
super();
this.sid = sid;
this.sname = sname;
this.sex = sex;
this.shobby = shobby;
this.tname = tname;
this.cname = cname;
}
public Student(int sid, int cid, String sname, String sex, String shobby, String tname, String cname) {
super();
this.sid = sid;
this.cid = cid;
this.sname = sname;
this.sex = sex;
this.shobby = shobby;
this.tname = tname;
this.cname = cname;
}
public Student(int sid, String sname, String sex, String shobby) {
super();
this.sid = sid;
this.sname = sname;
this.sex = sex;
this.shobby = shobby;
}
public Student() {
super();
}
@Override
public String toString() {
return this.sid+this.sname+this.sex+this.shobby+this.tname+this.cname;
}
}
package com.dj.pageBean.entity;
public class Classs {
private int cid;
private String cname;
private Teacher teacher;
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public Teacher getTeacher() {
return teacher;
}
public void setTeacher(Teacher teacher) {
this.teacher = teacher;
}
public Classs(int cid, String cname, Teacher teacher) {
super();
this.cid = cid;
this.cname = cname;
this.teacher = teacher;
}
public Classs() {
super();
}
}
package com.dj.pageBean.entity;
public class Teacher {
private int tid;
private String tname;
public int getTid() {
return tid;
}
public void setTid(int tid) {
this.tid = tid;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
public Teacher(int tid, String tname) {
super();
this.tid = tid;
this.tname = tname;
}
public Teacher() {
super();
}
}
package com.dj.pageBean.util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* 提供了一组获得或关闭数据库对象的方法
*
*/
public class DBAccess {
private static String driver;
private static String url;
private static String user;
private static String password;
static {// 静态块执行一次,加载 驱动一次
try {
InputStream is = DBAccess.class.getResourceAsStream("config.properties");
Properties properties = new Properties();
properties.load(is);
driver = properties.getProperty("driver");
url = properties.getProperty("url");
user = properties.getProperty("user");
password = properties.getProperty("pwd");
Class.forName(driver);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 获得数据连接对象
*
* @return
*/
public static Connection getConnection() {
try {
Connection conn = DriverManager.getConnection(url, user, password);
return conn;
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
public static void close(ResultSet rs) {
if (null != rs) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Statement stmt) {
if (null != stmt) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Connection conn) {
if (null != conn) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
}
public static void close(Connection conn, Statement stmt, ResultSet rs) {
close(rs);
close(stmt);
close(conn);
}
public static boolean isOracle() {
return "oracle.jdbc.driver.OracleDriver".equals(driver);
}
public static boolean isSQLServer() {
return "com.microsoft.sqlserver.jdbc.SQLServerDriver".equals(driver);
}
public static boolean isMysql() {
return "com.mysql.jdbc.Driver".equals(driver);
}
public static void main(String[] args) {
Connection conn = DBAccess.getConnection();
DBAccess.close(conn);
System.out.println("isOracle:" + isOracle());
System.out.println("isSQLServer:" + isSQLServer());
System.out.println("isMysql:" + isMysql());
System.out.println("数据库连接(关闭)成功");
}
}
package com.dj.pageBean.util;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 中文乱码处理
*
*/
public class EncodingFiter implements Filter {
private String encoding = "UTF-8";// 默认字符集
public EncodingFiter() {
super();
}
public void destroy() {
}
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse res = (HttpServletResponse) response;
// 中文处理必须放到 chain.doFilter(request, response)方法前面
res.setContentType("text/html;charset=" + this.encoding);
if (req.getMethod().equalsIgnoreCase("post")) {
req.setCharacterEncoding(this.encoding);
} else {
Map map = req.getParameterMap();// 保存所有参数名=参数值(数组)的Map集合
Set set = map.keySet();// 取出所有参数名
Iterator it = set.iterator();
while (it.hasNext()) {
String name = (String) it.next();
String[] values = (String[]) map.get(name);// 取出参数值[注:参数值为一个数组]
for (int i = 0; i < values.length; i++) {
values[i] = new String(values[i].getBytes("ISO-8859-1"),
this.encoding);
}
}
}
chain.doFilter(request, response);
}
public void init(FilterConfig filterConfig) throws ServletException {
String s = filterConfig.getInitParameter("encoding");// 读取web.xml文件中配置的字符集
if (null != s && !s.trim().equals("")) {
this.encoding = s.trim();
}
}
}
package com.dj.pageBean.util;
public class StringUtils {
// 私有的构造方法,保护此类不能在外部实例化
private StringUtils() {
}
/**
* 如果字符串等于null或去空格后等于"",则返回true,否则返回false
*
* @param s
* @return
*/
public static boolean isBlank(String s) {
boolean b = false;
if (null == s || s.trim().equals("")) {
b = true;
}
return b;
}
/**
* 如果字符串不等于null或去空格后不等于"",则返回true,否则返回false
*
* @param s
* @return
*/
public static boolean isNotBlank(String s) {
return !isBlank(s);
}
}
package com.dj.framework;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
/**
* 主控制器
* @author 86182
*
*/
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ConfigModel configModel = null;
public void init() {
try {
//将原有的读取框架的默认配置文件 转变成 可配置路径的配置文件
String xmlPath = this.getInitParameter("xmlPath");
if(xmlPath == null || "".equals(xmlPath)) {
configModel = ConfigModelFactory.build();
}else {
configModel = ConfigModelFactory.build(xmlPath);
}
//主控制器有哪些子控制器由configModel决定
configModel = ConfigModelFactory.build();
} catch (Exception e) {
e.printStackTrace();
}
}
@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 {
init();
String url = req.getRequestURI();//路径
url = url.substring(url.lastIndexOf("/"),url.lastIndexOf("."));
//通过 path 拿到 type
ActionModel actionModel = configModel.pop(url);
//如果没有配置子控制器
if(actionModel == null) {
throw new RuntimeException("没有配置对应的子控制器 Action");
}
/**
* 将Action的信息配置到xml(反射实例化)
*
* 原来子控制器的来源是map集合,如此,子控制器就被写死在map容器中,代码不灵活
* 现将子控制器以配置的方式存在config.xml中,即通过改变config.xml中的内容给中央控制器添加子控制器
*/
try {
Action action = (Action)Class.forName(actionModel.getType()).newInstance();//反射实例化
/**
* 调用模型驱动接口,获取所要操作的实体类,然后将jsp传递过来的参数封装到实体类中
*/
if(action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;//CalAction向上提升为ModelDriven
Object model = modelDriven.getModel();//要操作的实体类
/*//String-属性 String[]-属性值
Map map = req.getParameterMap();
for (Map.Entry entry : map.entrySet()) {//遍历
//可以获取到类对应的属性、属性值
}*/ //底层源码
//设置属性、属性值 将所有的参数自动封装到实体类T中
BeanUtils.populate(model, req.getParameterMap());
}
/**
* 通过结果码控制页面跳转
*
* 每个子控制器都要对结果进行处理(重定向/转发),代码重复量较大
* 针对这一现象,将其交给配置文件处理。
*/
//调用增强版的子控制器处理业务逻辑
String code = action.execut(req, resp); //要跳转的路径
ForwardModel forwardModel = actionModel.pop(code);
//如果没有配置子控制器
if(forwardModel == null) {
throw new RuntimeException("没有配置对应的子控制器Action的处理方式forwardModel");
}
String jspPath = forwardModel.getPath();
if(forwardModel.isRedirect()) {
resp.sendRedirect(req.getContextPath()+jspPath);//重定向
}else {
req.getRequestDispatcher(jspPath).forward(req, resp);//转发
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
BaseDao
package com.dj.pageBean.util;
import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* T = Student.class
* @author 86182
*
* @param
*/
public class BaseDao<T> {
/**
* @param sql 决定查询哪张表的数据
* @param clz 查询出来的数据封装到哪个实体类中
* @param pageBean 决定是否分页
* @return list 集合
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public List<T> executeQuery(String sql,Class clz,PageBean pageBean) throws SQLException, InstantiationException, IllegalAccessException{
List<T> list = new ArrayList<>();
//扩大作用域
java.sql.Connection con = null;
java.sql.PreparedStatement ps = null;
ResultSet rs = null;
try {
//连接
con = DBAccess.getConnection();
if(pageBean != null && pageBean.isPagination()) {//分页
String countSql = getCountSql(sql);//行数
ps = con.prepareStatement(countSql);
rs = ps.executeQuery();
if(rs.next()) {
pageBean.setTotal(rs.getLong(1)+"");
}
String pageSql = getPageSql(sql,pageBean);//某一页
ps = con.prepareStatement(pageSql);
rs = ps.executeQuery();
}else {//不分页
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
}
while(rs.next()) {
/**
* 1、创建一个Student对象
* 2、从 ResultSet 结果集中获取值给对象赋值
* 2.1 获取到Student的属性对象
* 2.2 给属性对象赋值
* 3、将已经有值的对象加入集合中
*/
//1、创建一个Student对象
T t = (T) clz.newInstance();
//2、从 ResultSet 结果集中获取值给对象赋值
Field[] fs = clz.getDeclaredFields();
for (Field f : fs) {
f.setAccessible(true);
f.set(t, rs.getObject(f.getName()));
}
//3、将已经有值的对象加入集合中
list.add(t);
}
} finally {
// shift+alt+z
DBAccess.close(con);
}
return (List<T>) list;
}
/**
* 将原生sql拼接出符合条件的某一页的数据查询sql
* @param sql 原生sql
* @param pageBean
* @return
*/
private String getPageSql(String sql, PageBean pageBean) {
return sql + "limit "+pageBean.getStartIndex()+","+pageBean.getRows();
}
/**
* 用原生sql拼接出符合条件的总行数
* @param sql 原生sql
* @return
*/
private String getCountSql(String sql) {
return "select count(1) from ("+sql+") t";
}
}
package com.dj.pageBean.util;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
/**
* 分页工具类
*/
public class PageBean {
private int page = 1;// 页码
private int rows = 8;// 页大小
private int total = 0;// 总记录数
private boolean pagination = true;// 是否分页
private String url;//存放上一次请求
private Map<String, String[]> paramMap = new HashMap<>();//键值对 存放查询参数
/**
* 存放 参数、键值对
* @param req
*/
public void setRequest(HttpServletRequest req) {
this.setPage(req.getParameter("page"));//设置第几页
this.setRows(req.getParameter("rows"));//设置每页的记录数
this.setPagination(req.getParameter("pagination"));//设置是否分页
this.setUrl(req.getRequestURL().toString());//getRequestURL获取到浏览器请求的全路径
this.setParamMap(req.getParameterMap());//getParameterMap可以获取到一次url请求所携带的所有参数
}
/**
* 设置是否分页
* @param pagination
*/
public void setPagination(String pagination) {
if (StringUtils.isNotBlank(pagination)) {
this.setPagination(!"false".equals(pagination));//是否分页 默认
}
}
/**
* 设置每一页的记录数
* @param rows
*/
public void setRows(String rows) {
if (StringUtils.isNotBlank(rows)) {
this.setRows(Integer.valueOf(rows));//几条数据
}
}
/**
* 设置第几页
* @param page
*/
public void setPage(String page) {
if (StringUtils.isNotBlank(page)) {
this.setPage(Integer.valueOf(page));//第几页
}
}
public PageBean() {
super();
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
public Map<String, String[]> getParamMap() {
return paramMap;
}
public void setParamMap(Map<String, String[]> paramMap) {
this.paramMap = paramMap;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public void setTotal(String total) {
this.total = Integer.parseInt(total);
}
public boolean isPagination() {
return pagination;
}
public void setPagination(boolean pagination) {
this.pagination = pagination;
}
/**
* 获得起始记录的下标
* @return
*/
public int getStartIndex() {
return (this.page - 1) * this.rows;
}
@Override
public String toString() {
return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination + "]";
}
/**
* 获取到总页数
* @return
*/
public int getMaxPage() {
return this.total % this.rows == 0 ? this.total / this.rows : (this.total / this.rows) + 1;
}
/**
* 获取下一页页码
* @return
*/
public int getNextPage() {
return this.page < this.getMaxPage() ? this.page+1 : this.page;
}
/**
* 获取上一页页码
* @return
*/
public int getPreviousPage() {
return this.page > 1 ? this.page-1 : this.page;
}
}
#oracle9i
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:ora9
#user=test
#pwd=test
#sql2005
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#url=jdbc:sqlserver://localhost:1423;DatabaseName=test
#user=sa
#pwd=sa
#sql2000
#driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
#url=jdbc:microsoft:sqlserver://localhost:1433;databaseName=unit6DB
#user=sa
#pwd=888888
#mysql5
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/dj?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT
user=root
pwd=123
package com.dj.framework;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 子控制器
* 专门用来处理业务逻辑
* @author 86182
*
*/
public interface Action {
String execut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException;
}
package com.dj.framework;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 用来描述action标签
* @author Administrator
*
*/
public class ActionModel implements Serializable{
private static final long serialVersionUID = 6145949994701469663L;
private String path;
private String type;
private Map<String, ForwardModel> fMap = new HashMap<>();
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public void push(ForwardModel forwardModel) {
fMap.put(forwardModel.getName(), forwardModel);
}
public ForwardModel pop(String name) {
return fMap.get(name);
}
}
package com.dj.framework;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
* 之前的Action只能处理一个实体类的一个业务
*
* 这个是增强版的子控制器,凡是这个实体类的操作,对应的方法都可以写在当前增强版的子控制器
* @author 86182
*
*/
public class ActionSupport implements Action{
@Override
public final String execut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String methodName = req.getParameter("methodName");
String code = null;
try {
Method method = this.getClass().getDeclaredMethod(methodName, HttpServletRequest.class,HttpServletResponse.class);
method.setAccessible(true);//打开访问权限
method.invoke(this, req, resp);
//具体调用了自己所写子控制器中的方法来处理浏览器的请求
code = (String)method.invoke(this, req, resp);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
return code;
}
}
package com.dj.framework;
import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
/**
* 用来描述config标签
* @author Administrator
*
*/
public class ConfigModel implements Serializable{
private static final long serialVersionUID = -2334963138078250952L;
private Map<String, ActionModel> acMap = new HashMap<>();
public Map<String, ActionModel> getAcMap() {
return acMap;
}
public void setAcMap(Map<String, ActionModel> acMap) {
this.acMap = acMap;
}
public void push(ActionModel actionModel) {
acMap.put(actionModel.getPath(), actionModel);
}
public ActionModel pop(String path) {
return acMap.get(path);
}
}
package com.dj.framework;
import java.io.InputStream;
import java.util.List;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
public class ConfigModelFactory {
public static ConfigModel build() throws Exception {
return build("config.xml");
}
//为了方便 我将configModel 为 1节点 actionModel 为2节点 forwardModel 为3节点
public static ConfigModel build(String xmlPath) throws Exception {
ConfigModel configModel = new ConfigModel(); //一个大的1节点
InputStream in = ConfigModelFactory.class.getResourceAsStream(xmlPath); //获取config.xml文件的读取流
SAXReader sax = new SAXReader();//用到了dom4j解析方法
Document doc = sax.read(in);//解析
ActionModel actionModel = null; //实例化2节点
ForwardModel forwardModel = null; //实列化3节点
List<Element> actionNodes = doc.selectNodes("/config/action"); //找到在1节点下的2节点
for (Element actionNode : actionNodes) { //便利
actionModel = new ActionModel(); //如果有的话就创建一个
actionModel.setPath(actionNode.attributeValue("path")); //给2节点里的属性path赋值
actionModel.setType(actionNode.attributeValue("type")); //给2节点里的属性type赋值
List<Element> forwardNodes = actionNode.selectNodes("forward"); //查找2节点下有多少个3节点
for (Element forwardNode : forwardNodes) {
forwardModel = new ForwardModel(); //如果有的话就创建一个
forwardModel.setName(forwardNode.attributeValue("name")); //给3节点里的属性name赋值
forwardModel.setPath(forwardNode.attributeValue("path")); //给3节点里的属性path赋值
forwardModel.setRedirect(!"false".equals(forwardNode.attributeValue("redirect"))); //给3节点里的属性redirect赋值
actionModel.push(forwardModel); //加入到action属性中
}
configModel.push(actionModel);//加入到集合属性中
}
return configModel;
}
public static void main(String[] args) throws Exception {
ConfigModel configModel = build();
ActionModel actionModel = configModel.pop("/add");
System.out.println("type的值"+actionModel.getType());
ForwardModel forwardModel = actionModel.pop("calres");
System.out.println(forwardModel.getPath() +" "+forwardModel.isRedirect());
}
}
package com.dj.framework;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.beanutils.BeanUtils;
/**
* 主控制器
* @author 86182
*
*/
public class DispatcherServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
private ConfigModel configModel = null;
public void init() {
try {
//将原有的读取框架的默认配置文件 转变成 可配置路径的配置文件
String xmlPath = this.getInitParameter("xmlPath");
if(xmlPath == null || "".equals(xmlPath)) {
configModel = ConfigModelFactory.build();
}else {
configModel = ConfigModelFactory.build(xmlPath);
}
//主控制器有哪些子控制器由configModel决定
configModel = ConfigModelFactory.build();
} catch (Exception e) {
e.printStackTrace();
}
}
@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 {
init();
String url = req.getRequestURI();//路径
url = url.substring(url.lastIndexOf("/"),url.lastIndexOf("."));
//通过 path 拿到 type
ActionModel actionModel = configModel.pop(url);
//如果没有配置子控制器
if(actionModel == null) {
throw new RuntimeException("没有配置对应的子控制器 Action");
}
/**
* 将Action的信息配置到xml(反射实例化)
*
* 原来子控制器的来源是map集合,如此,子控制器就被写死在map容器中,代码不灵活
* 现将子控制器以配置的方式存在config.xml中,即通过改变config.xml中的内容给中央控制器添加子控制器
*/
try {
Action action = (Action)Class.forName(actionModel.getType()).newInstance();//反射实例化
/**
* 调用模型驱动接口,获取所要操作的实体类,然后将jsp传递过来的参数封装到实体类中
*/
if(action instanceof ModelDriven) {
ModelDriven modelDriven = (ModelDriven) action;//CalAction向上提升为ModelDriven
Object model = modelDriven.getModel();//要操作的实体类
/*//String-属性 String[]-属性值
Map map = req.getParameterMap();
for (Map.Entry entry : map.entrySet()) {//遍历
//可以获取到类对应的属性、属性值
}*/ //底层源码
//设置属性、属性值 将所有的参数自动封装到实体类T中
BeanUtils.populate(model, req.getParameterMap());
}
/**
* 通过结果码控制页面跳转
*
* 每个子控制器都要对结果进行处理(重定向/转发),代码重复量较大
* 针对这一现象,将其交给配置文件处理。
*/
//调用增强版的子控制器处理业务逻辑
String code = action.execut(req, resp); //要跳转的路径
ForwardModel forwardModel = actionModel.pop(code);
//如果没有配置子控制器
if(forwardModel == null) {
throw new RuntimeException("没有配置对应的子控制器Action的处理方式forwardModel");
}
String jspPath = forwardModel.getPath();
if(forwardModel.isRedirect()) {
resp.sendRedirect(req.getContextPath()+jspPath);//重定向
}else {
req.getRequestDispatcher(jspPath).forward(req, resp);//转发
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
package com.dj.framework;
import java.io.Serializable;
/**
* 用来描述forward标签
* @author Administrator
*
*/
public class ForwardModel implements Serializable {
private static final long serialVersionUID = -8587690587750366756L;
private String name;
private String path;
private boolean redirect;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPath() {
return path;
}
public void setPath(String path) {
this.path = path;
}
public boolean isRedirect() {
return redirect;
}
public void setRedirect(boolean redirect) {
this.redirect = redirect;
}
}
package com.dj.framework;
/**
* 模型驱动接口
*
* 用来处理jsp页面传递过来的参数,将所有参数自动封装到实体类T中
*
* @author 86182
*
* @param
*/
public interface ModelDriven {
T getModel();
}
package com.dj.pageBean.dao;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.List;
import com.dj.pageBean.entity.Student;
import com.dj.pageBean.util.BaseDao;
import com.dj.pageBean.util.DBAccess;
import com.dj.pageBean.util.PageBean;
import com.dj.pageBean.util.StringUtils;
import com.mysql.jdbc.PreparedStatement;
/**
* 操作数据库中的tb_stu表
*
* 步骤:
* 1、加载驱动
* 2、创建连接
* 3、获得预定义处理对象
* 4、执行sql语句
* 5、处理结果集
* 6、关闭连接
*
* @author 86182
*
*/
public class StudentDao extends BaseDao<Student>{
/**
* 查询所有
* @param student 是从jsp传递过来的参数,封装成对象做为参数查询并执行sql
* @param pageBean 决定是否分页
* @return list 集合
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public List<Student> list(Student student,PageBean pageBean) throws SQLException, InstantiationException, IllegalAccessException{
//原始sql
String sql = "select a.sid,a.sname,a.sex,a.shobby,b.cname,c.tname from tb_stu a,tb_class b,tb_teacher c where a.cid=b.cid and b.tid=c.tid order by a.sid ";
//StringUtils.isNotBlank(student.getSname()) 判断是否为null
if(StringUtils.isNotBlank(student.getSname())) {
//拼接sql 模糊查询
sql += " and a.sname like '%"+student.getSname()+"%' ";
}
return super.executeQuery(sql, Student.class, pageBean);
}
/**
* 根据学生id查询学生信息
* @param student
* @return
*/
public Student querySingleStudent (Student student) {
//原始sql
String sql = "select a.sid,a.sname,a.sex,a.shobby,b.cname,c.tname from tb_stu a,tb_class b,tb_teacher c where a.cid=b.cid and b.tid=c.tid and a.sid="+student.getSid();
List<Student> lst;
try {
lst = super.executeQuery(sql, Student.class, null);
if(lst != null || lst.size() != 0) {//集合为空
return lst.get(0);
}
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
/**
* 增加学生
* @param stu
*/
public void addStu (Student student) {
String sql = "insert into tb_stu(sname,sex,shobby,cid) values(?,?,?,?)";
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DBAccess.getConnection();
stmt = (PreparedStatement) conn.prepareStatement(sql);
stmt.setString(1, student.getSname());
stmt.setString(2, student.getSex());
stmt.setString(3, student.getShobby());
stmt.setInt(4, student.getCid());
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
DBAccess.close(conn, stmt, null);
}
}
/**
* 根据学生id删除学生
* @param student
*/
public void delStu (Student student) {
String sql = "delete from tb_stu where sid=? ";
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DBAccess.getConnection();
stmt = (PreparedStatement) conn.prepareStatement(sql);
stmt.setInt(1, student.getSid());
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
DBAccess.close(conn, stmt, null);
}
}
/**
* 根据学生id修改学生
* @param stu
*/
public void updateStu (Student student) {
String sql = "update tb_stu set sname=?,sex=?,shobby=?,cid=? where sid=?";
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DBAccess.getConnection();
stmt = (PreparedStatement) conn.prepareStatement(sql);
stmt.setString(1, student.getSname());
stmt.setString(2, student.getSex());
stmt.setString(3, student.getShobby());
stmt.setInt(4, student.getCid());
stmt.setInt(5, student.getSid());
stmt.executeUpdate();
} catch (Exception e) {
e.printStackTrace();
}finally {
DBAccess.close(conn, stmt, null);
}
}
}
(增加学生信息时,需要查询到所有的班级名称)
package com.dj.pageBean.dao;
import java.sql.SQLException;
import java.util.List;
import com.dj.pageBean.entity.Classs;
import com.dj.pageBean.util.BaseDao;
import com.dj.pageBean.util.PageBean;
/**
* 操作数据库中的tb_class表
*
* 步骤:
* 1、加载驱动
* 2、创建连接
* 3、获得预定义处理对象
* 4、执行sql语句
* 5、处理结果集
* 6、关闭连接
*
* @author 86182
*
*/
public class ClasssDao extends BaseDao<Classs>{
/**
* 查询所有班级
* @param student 是从jsp传递过来的参数,封装成对象做为参数查询并执行sql
* @param pageBean 决定是否分页
* @return list 集合
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public List<Classs> classList(Classs classs,PageBean pageBean) throws InstantiationException, IllegalAccessException, SQLException {
String sql = "select cid,cname from tb_class where 1=1 ";
return super.executeQuery(sql, Classs.class, null);
}
}
这个是 主控制器
package com.dj.mvcplus.action;
import java.io.IOException;
import java.sql.DriverAction;
import java.sql.SQLException;
import java.util.List;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.sql.rowset.serial.SerialException;
import com.dj.framework.DispatcherServlet;
import com.dj.pageBean.dao.ClasssDao;
import com.dj.pageBean.dao.StudentDao;
import com.dj.pageBean.entity.Classs;
import com.dj.pageBean.entity.Student;
import com.dj.pageBean.util.PageBean;
public class StudentAction extends DispatcherServlet implements DriverAction{
/**
* 主控制 servlet
*/
private static final long serialVersionUID = 1L;
private Student student = new Student();
private StudentDao studentDao = new StudentDao();
private Classs classs = new Classs();
private ClasssDao classsDao = new ClasssDao();
@Override
public void deregister() {
// TODO Auto-generated method stub
}
/**
* 增加学生
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String addStudent(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
studentDao.addStu(student);
req.getSession().setAttribute("message", "新增学生信息成功");
return "success";
}
/**
* 删除学生
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String delStudent(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
studentDao.delStu(student);
req.getSession().setAttribute("message", "删除学生信息成功");
return "success";
}
/**
* 修改学生
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
*/
public String updateStudent(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException{
studentDao.updateStu(student);
req.getSession().setAttribute("message", "修改学生信息成功");
return "success";
}
/**
* 查询所有学生信息
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public String list(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException, InstantiationException, IllegalAccessException, SQLException{
PageBean pageBean = new PageBean();
pageBean.setRequest(req);
//查询所有符合条件的学生信息
List<Student> ls = studentDao.list(student, pageBean);
//保存 集合 和 分页信息
req.setAttribute("myls", ls);
req.setAttribute("pageBean", pageBean);
return "list";
}
/**
* 查询学生单个信息
* @param req
* @param resp
* @return
* @throws SerialException
* @throws IOException
*/
public String querySingleStudent(HttpServletRequest req,HttpServletResponse resp) {
//根据学生id查询单个学生信息
Student stu=studentDao.querySingleStudent(student);
//保存学生信息
req.setAttribute("student", stu);
return "update";
}
/**
* 查询所有班级信息
* @param req
* @param resp
* @return
* @throws ServletException
* @throws IOException
* @throws SQLException
* @throws IllegalAccessException
* @throws InstantiationException
*/
public String classList(HttpServletRequest req,HttpServletResponse resp)
throws ServletException,IOException, InstantiationException, IllegalAccessException, SQLException{
//查询所有班级名称
List<Classs> cls = classsDao.classList(classs, null);
//保存 集合
req.setAttribute("cls", cls);
return "success";
}
}
checkbox 标签助手类
package com.dj.tags;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
public class CheckBoxTag extends BodyTagSupport {
/**
* CheckBox 自定义标签助手类
*/
private static final long serialVersionUID = 1L;
private List<Object> items=new ArrayList<>();
private String name;
private List<Object> selected = new ArrayList<>();
public List<Object> getItems() {
return items;
}
public void setItems(List<Object> items) {
this.items = items;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Object> getSelected() {
return selected;
}
public void setSelected(List<Object> selected) {
this.selected = selected;
}
public CheckBoxTag(List<Object> items, String name, List<Object> selected) {
super();
this.items = items;
this.name = name;
this.selected = selected;
}
public CheckBoxTag() {
super();
}
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.write(toHtml());
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
return SKIP_BODY;
}
private String toHtml() throws IllegalArgumentException, IllegalAccessException, InstantiationException, NoSuchFieldException, SecurityException {
StringBuffer sb = new StringBuffer();
for (Object it : items) {
if(selected.contains(it)) {
sb.append(""+it+" ");
}else {
sb.append(""+it+" ");
}
}
return sb.toString();
}
}
pageTag 标签助手类
package com.dj.tags;
import java.io.IOException;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;
import com.dj.pageBean.util.PageBean;
public class PageTag extends BodyTagSupport {
/**
* 自定义标签助手类
*/
private static final long serialVersionUID = 1L;
private PageBean pageBean;
@Override
public int doStartTag() throws JspException {
JspWriter out = pageContext.getOut();
try {
out.write(toHTML());
} catch (IOException e) {
e.printStackTrace();
}
return super.doStartTag();
}
public String toHTML() {
StringBuffer sb = new StringBuffer();
// 下一次请求提交到后台的表单html代码拼接
sb.append(");
Map<String, String[]> paramMap = pageBean.getParamMap();//获取参数
if (paramMap != null && paramMap.size() > 0) {//参数不为空
for (Entry<String, String[]> entry : paramMap.entrySet()) {//遍历
if (!"page".equals(entry.getKey())) {//页数与上一次不一样
for(String val : entry.getValue()) {//遍历
sb.append("");
}
}
}
}
sb.append("");
sb.append("");
// 分页条html代码拼接
sb.append("
");
sb.append(" 每页 "+pageBean.getRows()+" 条,共 "+pageBean.getTotal()+" 条,第 "+pageBean.getPage()+" 页,共 "+pageBean.getMaxPage()+" 页 );
sb.append(" href='javascript:gotoPage(1)'>首页 );
sb.append(" href='javascript:gotoPage("+pageBean.getPreviousPage()+")'>上一页 );
sb.append(" href='javascript:gotoPage("+pageBean.getNextPage()+")'>下一页 );
sb.append(" href='javascript:gotoPage("+pageBean.getMaxPage()+")'>尾页 );
sb.append(" id='skipPage'");
sb.append(" style='text-align: center; font-size: 12px; width: 50px;'> );
sb.append(" href='javascript:skipPage()'>Go");
sb.append("");
// 分页所需要调用的js代码
sb.append("");
return sb.toString();
}
public PageBean getPageBean() {
return pageBean;
}
public void setPageBean(PageBean pageBean) {
this.pageBean = pageBean;
}
}
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="d" uri="/dj" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>本校学生</h2><br>
<div align="center">
<!-- 模糊查询 -->
<form action="studentAction.action" method="post">
<input type="hidden" name="pagination" value="false">
姓 名:<input type="text" name="sname">
<input type="submit" value="查 询" name="methodName:list">
</form><br><br>
<!-- 增加学生 -->
<a href="addStudent.jsp">点 我,快 速 增 加 学 生!</a><br><br>
<!-- 信息展示 -->
<!-- 为空去SelectServlet界面 -->
<c:if test="${empty myls }">
<jsp:forward page="studentAction.action?methodName=list"></jsp:forward>
</c:if>
<table border="1" width="90%">
<tr align="center">
<td>学 号</td>
<td>姓 名</td>
<td>性 别</td>
<td>班 级</td>
<td>教 员</td>
<td>爱 好</td>
<td>操 作</td>
</tr>
<c:forEach items="${myls }" var="s">
<tr align="center">
<td>${s.sid }</td>
<td>${s.sname }</td>
<td>${s.sex }</td>
<td>${s.cname }</td>
<td>${s.tname }</td>
<td>${s.shobby }</td>
<td>
<a href="studentAction.action?methodName=delStudent&sid=${s.sid }">删 除</a>
<a href="studentAction.action?methodName=querySingleStudent&sid=${s.sid }">修 改</a>
</td>
</tr>
</c:forEach>
</table>
<d:page pageBean="${pageBean }"></d:page>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="d" uri="/dj" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h2>新 增 学 生</h2><br>
<div align="center"><br><br><br><br>
<h2>增加学生信息</h2><br><br>
<!-- 班级信息为空去SelectServlet界面 -->
<c:if test="${empty cls }">
<jsp:forward page="studentAction.action?methodName=classList"></jsp:forward>
</c:if>
<!-- 新增学生 -->
<form action="studentAction.action" method="post">
<input type="hidden" name="sid" />
学生姓名:<input type="text" name="sname" /><br/><br/>
学生性别:
<input type="radio" name="sex" value="男"/> 男
<input type="radio" name="sex" value="女"/> 女<br/><br/>
学生班级:
<select name="cname">
<!-- 所有班级展示 -->
<c:forEach items="${cls }" var="c">
<option value="${c.cid }">${c.cname }</option>
</c:forEach>
</select><br/><br/>
学生爱好:<input type="checkbox" name="shobby" value="阅读"/>阅读
<input type="checkbox" name="shobby" value="唱跳"/>唱跳
<input type="checkbox" name="shobby" value="rap"/>rap<br/><br/>
<input type="hidden" name="methodName" value="addStudent" />
<input type="submit" value="增 加" />
</form>
</div>
</body>
</html>
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="d" uri="/dj" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<div align="center"><br><br><br><br>
<h2>修改学生信息</h2><br><br>
<!-- 班级信息为空去SelectServlet界面 -->
<c:if test="${empty cls }">
<jsp:forward page="studentAction.action?methodName=classList"></jsp:forward>
</c:if>
<!-- 修改学生信息 -->
<form action="studentAction.action" method="post">
<input type="hidden" name="sid" />
学生学号:<input type="text" name="sid" readonly="readonly" /><br/><br/>
学生姓名:<input type="text" name="sname" /><br/><br/>
学生性别:
<!-- 性别为男 -->
<c:if test="${student.sex=='男' }">
<input type="radio" name="sex" checked="checked" value="男"/> 男
<input type="radio" name="sex" value="女"/> 女<br/><br/>
</c:if>
<!-- 性别为女 -->
<c:if test="${student.sex=='女' }">
<input type="radio" name="sex" value="男"/> 男
<input type="radio" name="sex" checked="checked" value="女"/> 女<br/><br/>
</c:if>
学生班级:
<select name="cname">
<!-- 所有班级展示 -->
<c:forEach items="${cls }" var="c">
<option value="${c.cid }">${c.cname }</option>
</c:forEach>
</select><br/><br/>
学生爱好:<input type="checkbox" name="shobby" value="阅读"/>阅读
<input type="checkbox" name="shobby" value="唱跳"/>唱跳
<input type="checkbox" name="shobby" value="rap"/>rap<br/><br/>
<input type="hidden" name="methodName" value="updateStudent" />
<input type="submit" value="修 改" />
</form>
</div>
</body>
</html>