admin管理员组文章数量:1794759
J2EE
目录
一、什么是MVC?
二、MVC结构及原理
三、项目布局
实现效果:
3.1 数据库表的构建
3.2 创建一个JavaWeb项目
3.2.1 我们先导入指定的jar包文件
3.2.2 导入完成jar包,我们开始编写src中的各类包中的类
tag包 路径:com.zking.mvcplus.tag
3.2.3 完成以上操作,我们开始编写前端JSP页面层的编写
3.2.3 完成页面编写,我们在WEB-INF开始需要配置MVC以及自定义分页标签的编写
一、什么是MVC?
MVC全名:Model View Controller,其中Model(模型层)、View(视图层)、Controller(控制层)
它是一种软件设计典范,用于业务逻辑处理、数据、界面显示分离,
常用模式:
model1:jsp+jdbc
model2:mvc
问:三层架构和MVC的区别?
答:三层架构是一个经典的分层思想,将开发模式分为三层,每个人专注自己擅长模块即可
MVC是一种设计模式,其目的是让html和业务逻辑分开
二、MVC结构及原理
V(视图层)
C(控制层)
M(模型层)
注:1)不能跨层调用;
2)只能由上往下进行调用;View -> Controller -> Model
2.1自定义MVC工作原理图:
*.action 调度 截取*(请求路径名) 处理具体业务逻辑
JSP -----------> Servlet(中央控制器)--------------------->Action(子控制器)--->Model(Dao、DB)
三、项目布局
我们使用MVC架构来搭建一个简单的图书管理系统
实现效果:
自定义MVC展示
3.1 数据库表的构建
①首先我们先编写MySQL中的SQL语句,就是创建表格,具体代码如下:
这里我使用的工具是navicat编写
/*Navicat Premium Data TransferSource Server : localhostSource Server Type : MySQLSource Server Version : 50723Source Host : localhost:3306Source Schema : ajfTarget Server Type : MySQLTarget Server Version : 50723File Encoding : 65001Date: 09/07/2022 09:31:19
*/SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;-- ----------------------------
-- Table structure for tb_book
-- ----------------------------
DROP TABLE IF EXISTS `tb_book`;
#创建数据库——使用数据库——创建表格——插入数据
#这里我使用的是AJF数据库
use ajf;CREATE TABLE `tb_book` (`bid` int(11) NOT NULL AUTO_INCREMENT COMMENT '书籍编号',`bname` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '书本名称',`bpinyin` varchar(30) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci DEFAULT NULL COMMENT '书本拼音',`bprice` float DEFAULT 0 COMMENT '书本价格',`btype` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL COMMENT '书本类型',PRIMARY KEY (`bid`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 104 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci COMMENT = '书本信息表' ROW_FORMAT = Dynamic;-- ----------------------------
-- Records of tb_book
-- ----------------------------
#数据是随便加的
INSERT INTO `tb_book` VALUES (1, '史记第1章', 'sjd1z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (2, '史记第2章', 'sjd2z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (3, '史记第3章', 'sjd3z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (4, '史记第4章', 'sjd4z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (5, '史记第5章', 'sjd5z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (6, '史记第6章', 'sjd6z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (7, '史记第7章', 'sjd7z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (8, '史记第8章', 'sjd8z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (9, '史记第9章', 'sjd9z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (10, '史记第10章', 'sjd10z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (11, '史记第11章', 'sjd11z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (12, '史记第12章', 'sjd12z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (13, '史记第13章', 'sjd13z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (14, '史记第14章', 'sjd14z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (15, '史记第15章', 'sjd15z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (16, '史记第16章', 'sjd16z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (17, '史记第17章', 'sjd17z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (18, '史记第18章', 'sjd18z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (19, '史记第19章', 'sjd19z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (20, '史记第20章', 'sjd20z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (21, '史记第21章', 'sjd21z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (22, '史记第22章', 'sjd22z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (23, '史记第23章', 'sjd23z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (24, '史记第24章', 'sjd24z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (25, '史记第25章', 'sjd25z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (26, '史记第26章', 'sjd26z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (27, '史记第27章', 'sjd27z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (28, '史记第28章', 'sjd28z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (29, '史记第29章', 'sjd29z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (30, '史记第30章', 'sjd30z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (31, '史记第31章', 'sjd31z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (32, '史记第32章', 'sjd32z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (33, '史记第33章', 'sjd33z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (34, '史记第34章', 'sjd34z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (35, '史记第35章', 'sjd35z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (36, '史记第36章', 'sjd36z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (37, '史记第37章', 'sjd37z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (38, '史记第38章', 'sjd38z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (39, '史记第39章', 'sjd39z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (40, '史记第40章', 'sjd40z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (41, '史记第41章', 'sjd41z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (42, '史记第42章', 'sjd42z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (43, '史记第43章', 'sjd43z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (44, '史记第44章', 'sjd44z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (45, '史记第45章', 'sjd45z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (46, '史记第46章', 'sjd46z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (47, '史记第47章', 'sjd47z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (48, '史记第48章', 'sjd48z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (50, '史记第50章', 'sjd50z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (52, '稀有', 'xy', 100, '哈哈');
INSERT INTO `tb_book` VALUES (53, '王者', 'wz', 100, '可以');
INSERT INTO `tb_book` VALUES (54, '史记第1章', 'sjd1z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (55, '史记第2章', 'sjd2z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (56, '史记第3章', 'sjd3z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (57, '史记第4章', 'sjd4z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (58, '史记第5章', 'sjd5z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (59, '史记第6章', 'sjd6z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (60, '史记第7章', 'sjd7z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (61, '史记第8章', 'sjd8z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (62, '史记第9章', 'sjd9z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (63, '史记第10章', 'sjd10z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (64, '史记第11章', 'sjd11z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (65, '史记第12章', 'sjd12z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (66, '史记第13章', 'sjd13z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (67, '史记第14章', 'sjd14z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (68, '史记第15章', 'sjd15z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (69, '史记第16章', 'sjd16z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (70, '史记第17章', 'sjd17z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (71, '史记第18章', 'sjd18z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (72, '史记第19章', 'sjd19z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (73, '史记第20章', 'sjd20z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (74, '史记第21章', 'sjd21z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (75, '史记第22章', 'sjd22z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (76, '史记第23章', 'sjd23z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (77, '史记第24章', 'sjd24z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (78, '史记第25章', 'sjd25z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (79, '史记第26章', 'sjd26z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (80, '史记第27章', 'sjd27z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (81, '史记第28章', 'sjd28z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (82, '史记第29章', 'sjd29z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (83, '史记第30章', 'sjd30z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (84, '史记第31章', 'sjd31z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (85, '史记第32章', 'sjd32z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (86, '史记第33章', 'sjd33z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (87, '史记第34章', 'sjd34z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (88, '史记第35章', 'sjd35z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (89, '史记第36章', 'sjd36z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (90, '史记第37章', 'sjd37z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (91, '史记第38章', 'sjd38z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (92, '史记第39章', 'sjd39z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (93, '史记第40章', 'sjd40z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (94, '史记第41章', 'sjd41z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (95, '史记第42章', 'sjd42z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (96, '史记第43章', 'sjd43z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (97, '史记第44章', 'sjd44z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (98, '史记第45章', 'sjd45z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (99, '史记第46章', 'sjd46z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (100, '史记第47章', 'sjd47z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (101, '史记第48章', 'sjd48z', 34.5, '神话');
INSERT INTO `tb_book` VALUES (102, '史记第49章', 'sjd49z', 34.5, '神话');SET FOREIGN_KEY_CHECKS = 1;
3.2 创建一个JavaWeb项目
由于为了提高编程效率,项目中还缺少方法接口定义以及业务逻辑层的处理,还请大家理解!
我们需要按照以上来构建我们的图书管理项目
3.2.1 我们先导入指定的jar包文件
commons-beanutils-1.8.0.jar ——JAVA BEAN的工具包,Java反射机制来完毕代码中所须要的功能
commons-logging.jar ——使用spring的必备包,用来记录程序运行时的活动的日志记录
dom4j-1.6.1.jar ——优秀的JavaXML API,用来读写XML文件
jaxen-1.1-beta-6.jar ——使用XPath以简化dom4j查找节点时必须导入jaxen-1.1-beta-6.jar,否则会出现异常
jstl-1.2.jar ——SP标准标签库(JSTL)是一个JSP标签集合,它封装了JSP应用的通用核心功能
mvc.jar ——自定义MVCjar包
mysql-connector-java-5.1.44-bin.jar ——连接MySQLjar包
pinyin4j-2.5.0.jar ——拼音转换jar包
standard-1.1.2.jar ——是jar包,于jstl-1.2版本合用
3.2.2 导入完成jar包,我们开始编写src中的各类包中的类
util包: 路径:com.zking.mvcplus.util
config.properties ——连接数据库的信息存放文件
#oracle9i
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@localhost:1521:orcl
#user=scott
#pwd=123#sql2005
#driver=com.microsoft.sqlserver.jdbc.SQLServerDriver
#url=jdbc:sqlserver://localhost:1433;DatabaseName=test1
#user=sa
#pwd=123#sql2000
#driver=com.microsoft.jdbc.sqlserver.SQLServerDriver
#url=jdbc:microsoft:sqlserver://localhost:1433;databaseName=unit6DB
#user=sa
#pwd=888888#这里我们使用的是Oracle,所以其它的可以不使用
#mysql
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/AJF?useUnicode=true&characterEncoding=UTF-8&useSSL=false
user=root
pwd=1234
CommonUtils.java ——反射遍历rs通用类
package com.zking.mvcplus.util;import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;public class CommonUtils {// 反射封装ResultSet结果集public static <T> List<T> toList(ResultSet rs, Class cla) {// 定义返回结果List<T> lst = new ArrayList<T>();try {// 获取ResultSet中的列信息ResultSetMetaData metaData = rs.getMetaData();// 获取对象中的所有属性数组Field[] fields = cla.getDeclaredFields();// 循环遍历结果集ResultSetwhile (rs.next()) {// 通过反射机制实例化对象T obj = (T) cla.newInstance();// 循环遍历metaDatafor (int i = 0; i < metaData.getColumnCount(); i++) {// 获取SQL语句中的列名String colName = metaData.getColumnLabel(i + 1);// 循环遍历Fields数组for (Field field : fields) {// 获取属性名String fName = field.getName();// 判断数据表中的列名与实体中的属性名是否一致if (fName.toUpperCase().equals(colName.toUpperCase())) {// 拼接set方法 set+属性名首字母大写String methodName = "set" + fName.substring(0, 1).toUpperCase() + fName.substring(1);// 反射调用方法Method method = cla.getDeclaredMethod(methodName, field.getType());// 设置访问权限method.setAccessible(true);// 执行方法method.invoke(obj, rs.getObject(colName));break;}}}lst.add(obj);}} catch (Exception e) {e.printStackTrace();}return lst;}public static List<Map<String, Object>> toList(ResultSet rs) {// 定义返回结果List<Map<String, Object>> lst = new ArrayList<Map<String, Object>>();try {// 获取ResultSet中的列信息ResultSetMetaData metaData = rs.getMetaData();// 循环遍历结果集ResultSetwhile (rs.next()) {Map<String,Object> obj=new HashMap<String,Object>();// 循环遍历metaDatafor (int i = 0; i < metaData.getColumnCount(); i++) {// 获取SQL语句中的列名String colName = metaData.getColumnLabel(i + 1);obj.put(colName,rs.getObject(colName));}lst.add(obj);}} catch (Exception e) {e.printStackTrace();}return lst;}
}
DBHelper.java ——数据库连接帮助实现类
package com.zking.mvcplus.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 DBHelper {private static String driver;private static String url;private static String user;private static String password;static {// 静态块执行一次,加载 驱动一次try {InputStream is = DBHelper.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 = DBHelper.getConnection();DBHelper.close(conn);System.out.println("isOracle:" + isOracle());System.out.println("isSQLServer:" + isSQLServer());System.out.println("isMysql:" + isMysql());System.out.println("数据库连接(关闭)成功");}
}
EncodingFilter.java ——中文乱码处理类
package com.zking.mvcplus.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 EncodingFilter implements Filter {private String encoding = "UTF-8";// 默认字符集public EncodingFilter() {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();}}
}
PageBean.java ——分页类
package com.zking.mvcplus.util;import java.io.Serializable;
import java.util.Map;import javax.servlet.http.HttpServletRequest;public class PageBean implements Serializable {//页码private int page=1;//每页显示条数private int rows=10;//总记录数private int total=0;//是否分页标记private boolean pagination=true;//上一次请求的路径private String url;//请求参数Map集合private Map<String,String[]> map;public String getUrl() {return url;}public void setUrl(String url) {this.url = url;}public Map<String, String[]> getMap() {return map;}public void setMap(Map<String, String[]> map) {this.map = map;}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 boolean isPagination() {return pagination;}public void setPagination(boolean pagination) {this.pagination = pagination;}//重载setPage/setRows/setPagination方法public void setPage(String page) {if(null!=page&&!"".equals(page))this.page=Integer.parseInt(page);}public void setRows(String rows) {if(null!=rows&&!"".equals(rows))this.rows=Integer.parseInt(rows);}public void setPagination(String pagination) {if(null!=pagination&&!"".equals(pagination))this.pagination=Boolean.parseBoolean(pagination);}public void setRequest(HttpServletRequest req) {//获取前端提交的page/rows/pagination参数String page=req.getParameter("page");String rows=req.getParameter("rows");String pagination=req.getParameter("pagination");//设置属性this.setPage(page);this.setPagination(pagination);this.setRows(rows);//设置上一次请求的路径//第一次请求://http://localhost:8080/项目名/请求路径.action?page=1//第二次请求:下一页 page=2//项目名+请求路径.action//req.getContextPath()+req.getServletPath()==req.getRequestURI()this.url=req.getRequestURI();//获取请求参数集合// checkbox name='hobby'// Map<String,String[]> hobby==key value==new String[]{"篮球","足球",..}this.map=req.getParameterMap();}/*** 获取分页的起始位置* @return*/public int getStartIndex() {//第1页:(1-1)*10 ==0 limit 0,10//第2页:(2-1)*10 ==10 limit 10,10//..return (this.page-1)*this.rows;}//获取末页、上一页、下一页/*** 获取末页* @return*/public int getMaxPager() {int maxPager=this.total/this.rows;if(this.total%this.rows!=0)maxPager++;return maxPager;}/*** 获取上一页* @return*/public int getPreviousPager() {int previousPager=this.page-1;if(previousPager<=1)previousPager=1;return previousPager;}/*** 获取下一页* @return*/public int getNextPager() {int nextPager=this.page+1;if(nextPager>getMaxPager())nextPager=getMaxPager();return nextPager;}@Overridepublic String toString() {return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination+ ", url=" + url + ", map=" + map + "]";}
}
PinYinUtil.java ——拼音转换类
package com.zking.mvcplus.util;import java.util.regex.Pattern;import net.sourceforge.pinyin4j.PinyinHelper;/*** 拼音工具类,能将汉字转换成拼音的首字母*/
public class PinYinUtil {/* 用于中文判断的正则表达式 */private static final String regexStr = "[\u4e00-\u9fa5]";/*** 将一个字符串中的汉字转换成拼音首字母、非汉字则不变* * @param cn* String* @return String*/public static String toPinyin(String cn) {String pinyin = null;if (null == cn || 0 == cn.trim().length()) {return pinyin;}/* 去掉字符串前后的空格 */cn = cn.trim();char[] chineseCharacterArr = cn.toCharArray(); // 转换成汉字字符数组char[] letteCharacterArr = new char[chineseCharacterArr.length]; // 字母字符数组for (int i = 0; i < chineseCharacterArr.length; i++) {// 得到汉字拼音的首字母letteCharacterArr[i] = getFirstLetterFromPinyin(chineseCharacterArr[i]);}if (0 != letteCharacterArr.length) {pinyin = new String(letteCharacterArr);pinyin = pinyin.toUpperCase();}return pinyin;}/* 得到一个汉字的拼音的首字母 */private static char getFirstLetterFromPinyin(char cn) {// 判断cn是否为一个合法的汉字,不是则直接返回cnif (!isChineseCharacters(cn)) {return cn;}String[] pyArr = PinyinHelper.toHanyuPinyinStringArray(cn);char py = pyArr[0].charAt(0);return py;}/*** 判断字符是否为一个汉字* * @param cn* char* @return boolean*/public static boolean isChineseCharacters(char cn) {boolean b = false;if (Pattern.matches(regexStr, String.valueOf(cn))) {b = true;}return b;}public static void main(String[] args) {String s = "任保存并加入题库";System.out.println(PinYinUtil.toPinyin(s).toLowerCase());}
}
StringUtils.java ——字符串非空判断类
package com.zking.mvcplus.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);}
}
entity包 路径:com.zking.mvcplus.entity
Book.java ——书籍实体类
package com.zking.mvcplus.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);}
}
dao包 路径:com.zking.mvcplus.dao
BaseDao.java ——简写增删改查方法实体类
package com.zking.mvcplus.dao;import java.sql.Connection;
import java.sql.ParameterMetaData;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;import com.zking.mvcplus.util.DBHelper;
import com.zking.mvcplus.util.PageBean;public class BaseDao<T> {public static interface CallBack<K>{//该方法只用于循环遍历ResultSet结果集,并返回List<T>结果public List<K> foreachRs(ResultSet rs) throws SQLException;}/*** 通过的增删改方法* @param sql sql语句* @param params sql语句的参数数组*/public void executeUpdate(String sql,Object[] params) {Connection conn=null;PreparedStatement stmt=null;try {conn=DBHelper.getConnection();stmt=conn.prepareStatement(sql);ParameterMetaData metaData = stmt.getParameterMetaData();for (int i = 0; i < metaData.getParameterCount(); i++) {stmt.setObject(i+1, params[i]);}int i = stmt.executeUpdate();if(i<1)throw new RuntimeException("执行失败,影响行数为0!");} catch (Exception e) {e.printStackTrace();throw new RuntimeException(e);} finally {DBHelper.close(conn, stmt, null);}}/*** 通用分页方法(既支持分页,也可以不分页)* @param sql 普通的SQL* @param pageBean 分页对象(包含分页三要素)* @return 返回查询结果集*/public List<T> executeQuery(String sql,PageBean pageBean,CallBack<T> callback){Connection conn=null;PreparedStatement stmt=null;ResultSet rs=null;try {//获取连接对象conn=DBHelper.getConnection();//判断是否分页if(null!=pageBean&&pageBean.isPagination()) {//1.分页(总记录数、分页查询)//1) 根据满足条件获取总记录数的SQLString countSQL = this.getCountSQL(sql);//创建执行对象stmt=conn.prepareStatement(countSQL);//执行SQL并返回总记录数rs=stmt.executeQuery();if(rs.next()) {int total = rs.getInt(1);pageBean.setTotal(total);}//2) 根据满足条件获取查询分页结果集的SQL limitsql=this.getPagerSQL(sql, pageBean);}//创建执行对象stmt=conn.prepareStatement(sql);//执行SQL并返回总记录数rs=stmt.executeQuery();//将rs结果集存入到foreachRs方法中return callback.foreachRs(rs);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();} finally {DBHelper.close(conn, stmt, rs);}return null;}/*** 将普通的SQL语句转换成查询总记录数的SQL语句* select * from t_book* select * from t_book where ...* select book_id,book_name from t_book* select book_id,book_name from t_book where ...* ------->* select count(0) from t_book where ...* @param sql 普通的SQL* @return 查询总记录数的SQL*/private String getCountSQL(String sql) {return "select count(0) from ("+sql+") temp";}/*** 将普通的SQL语句转换成查询分页结果集的SQL(说白了就是拼接limit)* select * from t_book* select * from t_book where ...* select book_id,book_name from t_book* select book_id,book_name from t_book where ...* ------->* select * from t_book limit * @param sql 普通的SQL* @param pageBean 分页对象* @return 分页查询的SQL*/private String getPagerSQL(String sql,PageBean pageBean) {return sql+" limit "+pageBean.getStartIndex()+","+pageBean.getRows();}
}
BookDao.java ——书籍方法实体类
package com.zking.mvcplus.dao;import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;import com.zking.mvcplus.entity.Book;
import com.zking.mvcplus.util.CommonUtils;
import com.zking.mvcplus.util.PageBean;
import com.zking.mvcplus.util.PinYinUtil;
import com.zking.mvcplus.util.StringUtils;public class BookDao extends BaseDao<Book> {/*** 1.书本新增* @param book*/public void addBook(Book book) {String sql="insert into tb_book(bname,bpinyin,"+ "bprice,btype) values(?,?,?,?)";super.executeUpdate(sql, new Object[] {book.getBname(),PinYinUtil.toPinyin(book.getBname()).toLowerCase(),book.getBprice(),book.getBtype()});}/*** 2.书本编辑* @param book*/public void editBook(Book book) {String sql="update tb_book set bname=?,bpinyin=?,"+ "bprice=?,btype=? where bid=?";super.executeUpdate(sql, new Object[] {book.getBname(),PinYinUtil.toPinyin(book.getBname()).toLowerCase(),book.getBprice(),book.getBtype(),book.getBid()});}/*** 3.书本删除* @param book*/public void delBook(Book book) {String sql="delete from tb_book where bid=?";super.executeUpdate(sql, new Object[] {book.getBid()});}/*** 4.根据书本ID查询单个书本信息* @param book* @return*/public Book queryBookById(Book book) {String sql="select bid,bname,bpinyin,"+ "bprice,btype from tb_book "+ "where bid="+book.getBid();System.out.println(sql);List<Book> lst = super.executeQuery(sql, null, new CallBack<Book>() {@Overridepublic List<Book> foreachRs(ResultSet rs) throws SQLException {return CommonUtils.toList(rs, Book.class);}});if(null!=lst&&lst.size()!=0)return lst.get(0);elsereturn null;}/*** 5.分页查询* @param book* @return*/public List<Book> queryBookPager(Book book,PageBean pageBean) {String sql="select bid,bname,bpinyin,"+ "bprice,btype from tb_book "+ "where 1=1";//按照书本名称模糊查询if(StringUtils.isNotBlank(book.getBname()))sql+=" and bname like '%"+book.getBname()+"%'";//按照书本编号降序排序sql+=" order by bid desc";System.out.println(sql);return super.executeQuery(sql, pageBean, new CallBack<Book>() {@Overridepublic List<Book> foreachRs(ResultSet rs) throws SQLException {return CommonUtils.toList(rs, Book.class);}});}
}
BookDaoTest.java ——方法测试类 junit
package com.zking.mvcplus.dao;import java.util.List;import org.junit.After;
import org.junit.Before;
import org.junit.Test;import com.zking.mvcplus.entity.Book;
import com.zking.mvcplus.util.PageBean;public class BookDaoTest {Book book=null;BookDao bookDao=new BookDao();@Beforepublic void setUp() throws Exception {book=new Book();}@Afterpublic void tearDown() throws Exception {}@Testpublic void testAddBook() {book.setBname("围城");book.setBprice(100f);book.setBtype("散文");bookDao.addBook(book);}@Testpublic void testEditBook() {book.setBid(81);book.setBname("凡人修仙传");book.setBprice(120f);book.setBtype("修仙");bookDao.editBook(book);}@Testpublic void testDelBook() {book.setBid(80);bookDao.delBook(book);}@Testpublic void testQueryBookById() {book.setBid(80);Book b = bookDao.queryBookById(book);System.out.println(b);}@Testpublic void testQueryBookPager() {PageBean pageBean=new PageBean();List<Book> books = bookDao.queryBookPager(book, pageBean);System.out.println("总记录数:"+pageBean.getTotal());books.forEach(System.out::println);}
}
action包 路径:com.zking.mvcplus.action
BookAction.java ——servlet后端处理
package com.zking.mvcplus.action;import java.io.IOException;
import java.util.List;import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;import com.zking.mvc.framework.DispatcherAction;
import com.zking.mvc.framework.DriverModel;
import com.zking.mvcplus.dao.BookDao;
import com.zking.mvcplus.entity.Book;
import com.zking.mvcplus.util.PageBean;/*** XxxAction extends Action -> execute 做一件事情* XxxAction extends DispatcherAction 做多件事情* 注意:* 1)该子控制器类Action中提供一组与execute方法相同的参数和返回值,只有方法名不相同的方法* 2)必须要传递methodName的参数,该参数表示方法名,用于反射调用方法* 3)每一次创建子控制器类Action,请先到mvc.xml配置文件中定义对应关系(重要!!)* @author Administrator**/
public class BookAction extends DispatcherAction implements DriverModel<Book> {private Book book=new Book();private BookDao bookDao=new BookDao();@Overridepublic Book getModel() {return book;}/*** 书本新增* @param req* @param resp* @return* @throws ServletException* @throws IOException*/public String addBook(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{bookDao.addBook(book);return "list";}/*** 书本编辑* @param req* @param resp* @return* @throws ServletException* @throws IOException*/public String editBook(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{bookDao.editBook(book);return "list";}/*** 书本删除* @param req* @param resp* @return* @throws ServletException* @throws IOException*/public String delBook(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{bookDao.delBook(book);return "list";}/*** 分页查询书本信息* @param req* @param resp* @return* @throws ServletException* @throws IOException*/public String queryBookPager(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{PageBean pageBean=new PageBean();pageBean.setRequest(req);List<Book> books = bookDao.queryBookPager(book, pageBean);//将查询的书本分页结果集和PageBean对象保存到request中req.setAttribute("books", books);req.setAttribute("pageBean", pageBean);return "success";}/*** 查询单个书本对象,跳转到编辑或者详情页面* @param req* @param resp* @return* @throws ServletException* @throws IOException*/public String selectOne(HttpServletRequest req,HttpServletResponse resp)throws ServletException,IOException{//根据书本ID查询单个书本信息Book b = bookDao.queryBookById(book);//将查询书本对象保存到request中req.setAttribute("book", b);//根据前端传入的参数type判断跳转到编辑还是详情页面String type = req.getParameter("type");//判断类型if("edit".equals(type))return "edit";elsereturn "detail";}
}
tag包 路径:com.zking.mvcplus.tag
PaginationTag.java ——分页实现类
package com.zking.mvcplus.tag;import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspWriter;
import javax.servlet.jsp.tagext.BodyTagSupport;import com.zking.mvcplus.util.PageBean;public class PaginationTag extends BodyTagSupport {private PageBean pageBean;@Overridepublic int doEndTag() throws JspException {return EVAL_PAGE;}@Overridepublic int doStartTag() throws JspException {JspWriter out = pageContext.getOut();try {out.write(toHtml());} catch (Exception e) {e.printStackTrace();}return SKIP_BODY;}private String toHtml() {//判断是否分页if(null==pageBean||!pageBean.isPagination())return "";else {StringBuilder sb=new StringBuilder();//TODOsb.append("<div style=\"float:right\">");//拼接Form表单sb.append("<form id=\"pageBeanForm\" action=\""+pageBean.getUrl()+"\" method=\"post\">");//设置page隐藏域sb.append("<input type=\"hidden\" name=\"page\"/>");//拼接请求参数集合Map<String, String[]> map = pageBean.getMap();//获取请求参数集合键值对Set<Entry<String,String[]>> entrySet = map.entrySet();//遍历请求参数键值对for (Entry<String, String[]> entry : entrySet) {//获取请求参数名,也就是来自于表单中的name属性名称String name=entry.getKey();//如果参数为page,则continue跳过if(name.equals("page"))continue;//获取请求参数对应的值,String[]String[] values=entry.getValue();//遍历value值for (String value : values) {//拼接请求参数sb.append("<input type='hidden' name='"+name+"' value='"+value+"'/>");}}sb.append("</form>");//拼接共几页/第几页sb.append("共"+pageBean.getMaxPager()+"页/第"+pageBean.getPage()+"页,");//拼接首页、上一页、下一页、末页if(pageBean.getPage()==1)sb.append("首页 上一页 ");else {sb.append("<a href=\"javascript:gotoPage(1)\">首页</a> ");sb.append("<a href=\"javascript:gotoPage("+pageBean.getPreviousPager()+")\">上一页</a> ");}if(pageBean.getPage()==pageBean.getMaxPager())sb.append("下一页 末页 ");else {sb.append("<a href=\"javascript:gotoPage("+pageBean.getNextPager()+")\">下一页</a> ");sb.append("<a href=\"javascript:gotoPage("+pageBean.getMaxPager()+")\">末页</a> ");}//拼接跳转页码sb.append("<input type=\"text\" id=\"p\" style=\"width:20px;\"/>");sb.append("<input type=\"button\" value=\"GO\" onclick=\"javascript:skipPage();\"/>");//拼接javascript跳转方法sb.append("<script type=\"text/javascript\">\r\n" + "function gotoPage(page){\r\n" + " document.getElementById(\"pageBeanForm\").page.value=page;\r\n" + " document.getElementById(\"pageBeanForm\").submit();\r\n" + "}");sb.append("function skipPage(){\r\n" + " var page=document.getElementById(\"p\").value;\r\n" + " if(isNaN(page)||page<1||page>="+pageBean.getMaxPager()+"){\r\n" + " alert('请输入1~"+pageBean.getMaxPager()+"之间数字!');\r\n" + " return false;\r\n" + " }\r\n" + " gotoPage(page);\r\n" + "}\r\n" + "</script>");sb.append("</div>");return sb.toString();}}public PageBean getPageBean() {return pageBean;}public void setPageBean(PageBean pageBean) {this.pageBean = pageBean;}
}
然后就是src根目录下的自定义标签的xml文件编写
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE config[<!ELEMENT config (action*)><!ELEMENT action (forward*)><!ELEMENT forward EMPTY><!ATTLIST action path CDATA #REQUIREDtype CDATA #REQUIRED><!ATTLIST forwardname CDATA #REQUIREDpath CDATA #REQUIREDredirect (true|false) "false">
]><!--config标签:可以包含0~N个action标签-->
<config><action type="com.zking.mvcplus.action.BookAction" path="/bookAction"><forward name="list" path="/bookAction.action?methodName=queryBookPager" redirect="true"/><forward name="success" path="/bookList.jsp"/><forward name="edit" path="/editBook.jsp"/><forward name="detail" path="/bookDetail.jsp"/></action>
</config>
3.2.3 完成以上操作,我们开始编写前端JSP页面层的编写
addBook.jsp ——增加书籍的界面
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ".dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>书本新增</h1>
<form action="bookAction.action?methodName=addBook" method="post"><label>书本名称:</label><input type="text" name="bname"/><br/><label>书本价格:</label><input type="text" name="bprice"/><br/><label>书本类型:</label><input type="text" name="btype"/><br/><input type="submit" value="新增"/>
</form>
</body>
</html>
bookDetail.jsp ——书本详情界面
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ".dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>书本详情</h1>
${book }
</body>
</html>
bookList.jsp ——书本主界面
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="" %>
<%@taglib prefix="z" uri="/zking" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ".dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<form action="bookAction.action?methodName=queryBookPager" method="post"><label>书本名称:</label><input type="text" name="bname"/><input type="submit" value="查询"/>
</form>
<a href="addBook.jsp">书本新增</a>
<table width="100%" border="1" cellpadding="0" cellspacing="0"><tr><th>书本编号</th><th>书本名称</th><th>书本拼音</th><th>书本价格</th><th>书本类型</th><th>操作</th></tr><c:forEach items="${books }" var="b"><tr><td>${b.bid }</td><td>${b.bname }</td><td>${b.bpinyin }</td><td>${b.bprice }</td><td>${b.btype }</td><td><a href="bookAction.action?methodName=selectOne&type=edit&bid=${b.bid }">编辑</a><a href="bookAction.action?methodName=selectOne&type=detail&bid=${b.bid }">详情</a><a onclick="return confirm('确认要删除吗?');" href="bookAction.action?methodName=delBook&bid=${b.bid }">删除</a></td></tr></c:forEach>
</table>
<z:pagination pageBean="${pageBean }"/>
</body>
</html>
editBook.jsp ——修改书本界面
<%@ page language="java" contentType="text/html; charset=UTF-8"pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" ".dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Insert title here</title>
</head>
<body>
<h1>书本编辑</h1>
<form action="bookAction.action?methodName=editBook" method="post"><input type="hidden" value="${book.bid }" name="bid"/><label>书本名称:</label><input type="text" name="bname" value="${book.bname }"/><br/><label>书本价格:</label><input type="text" name="bprice" value="${book.bprice }"/><br/><label>书本类型:</label><input type="text" name="btype" value="${book.btype }"/><br/><input type="submit" value="编辑"/>
</form>
</body>
</html>
3.2.3 完成页面编写,我们在WEB-INF开始需要配置MVC以及自定义分页标签的编写
web.xml ——系统文件,主要用于配置servlet、filter、listenner
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="" xmlns="" xsi:schemaLocation=" .xsd" id="WebApp_ID" version="3.1"><display-name>mvcPlus</display-name><!-- 配置中文乱码过滤器 --><filter><filter-name>encodingFilter</filter-name><filter-class>com.zking.mvcplus.util.EncodingFilter</filter-class></filter><filter-mapping><filter-name>encodingFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping><!-- 配置中央控制器ActionServlet --><servlet><servlet-name>actionServlet</servlet-name><servlet-class>com.zking.mvc.framework.ActionServlet</servlet-class><init-param><param-name>config</param-name><param-value>/mvc.xml</param-value></init-param></servlet><servlet-mapping><servlet-name>actionServlet</servlet-name><url-pattern>*.action</url-pattern></servlet-mapping><welcome-file-list><welcome-file>index.html</welcome-file><welcome-file>index.htm</welcome-file><welcome-file>index.jsp</welcome-file><welcome-file>default.html</welcome-file><welcome-file>default.htm</welcome-file><welcome-file>default.jsp</welcome-file></welcome-file-list>
</web-app>
z.tld ——分页自定义xml
<!DOCTYPE taglibPUBLIC "-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN"".dtd">
<!-- 标签库描述符 -->
<taglib xmlns=""><!-- 代表标签库的版本号 --><tlib-version>1.0</tlib-version><!-- 代表jsp的版本 --><jsp-version>1.2</jsp-version><!-- 你的标签库的简称 --><short-name>z</short-name><!-- 你标签库的引用uri --><uri>/zking</uri><tag><!-- 标签名 --><name>pagination</name><!-- 标签工具类 --><!-- 利用反射机制,通过Class.forName(类的全路径名/包名+类名)的方式反射机制实例化标签助手类 --><tag-class>com.zking.mvcplus.tag.PaginationTag</tag-class><!-- 标签的内容类型:empty表示空标签,jsp表示可以为任何合法的JSP元素 --><body-content>empty</body-content><!-- 自定义标签的属性定义,请注意一定要在标签类中提供对应的get/set方法 --><attribute><!-- 自定义标签的属性名称 --><name>pageBean</name><!-- true表示必填 --><required>true</required><!-- true支持动态值,可以向值里面填jsp表达式、EL表达式,false则不支持 --><rtexprvalue>true</rtexprvalue></attribute></tag>
</taglib>
以上就是本章所有内容,感谢观看!
本文标签: J2EE
版权声明:本文标题:J2EE 内容由林淑君副主任自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.xiehuijuan.com/baike/1697226376a339918.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论