裸系统封装
封装过程:
1、建立一个web工程
新建一个index.jsp;
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <% 3 String path = request.getContextPath(); 4 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 5 %> 6 7 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 8 <html> 9 <head> 10 <base href="<%=basePath%>"> 11 12 <title>My JSP 'index.jsp' starting page</title> 13 <meta http-equiv="pragma" content="no-cache"> 14 <meta http-equiv="cache-control" content="no-cache"> 15 <meta http-equiv="expires" content="0"> 16 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 17 <meta http-equiv="description" content="This is my page"> 18 <!-- 19 <link rel="stylesheet" type="text/css" href="styles.css"> 20 --> 21 </head> 22 23 <body> 24 This is my mmzs JSP page. <br> 25 </body> 26 </html>
部署工程,测试是否可以部署成功。若成功访问请进入下一步:
2、接下来写一个登陆:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> </head> <body> <span style="font-size: 22px;font-weight: bolder;color: red">用户登陆</span> <hr color="green" size="2" width="100%" /> <form id="loginForm" action="/BigData6-1/userAction" method="post"> <input type="hidden" name="method" value="login"> <input name="userName" ><br><br> <input name="passWord" type="password" ><br><br> <input type="submit" value="登录"> </form> </body> </html>
建立一个action基础类:
1 package com.mmzs.bigdata.action; 2 3 import java.io.IOException; 4 import java.lang.reflect.InvocationTargetException; 5 import java.lang.reflect.Method; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServlet; 9 import javax.servlet.http.HttpServletRequest; 10 import javax.servlet.http.HttpServletResponse; 11 12 public class BaseAction extends HttpServlet{ 13 14 @Override 15 protected void doGet(HttpServletRequest req, HttpServletResponse resp) 16 throws ServletException, IOException { 17 this.doPost(req, resp); 18 } 19 20 @Override 21 protected void doPost(HttpServletRequest request, HttpServletResponse response) 22 throws ServletException, IOException { 23 //获取当前客户端需要调用的逻辑控制方法 24 String methodName = request.getParameter("method"); 25 if (null == methodName || methodName.trim().isEmpty()) return; 26 //获取当前客户端正在调用的Servlet类 27 Class actionClass = this.getClass(); 28 try { 29 //从当前正在调用的Servlet类中查找需要调用的方法 30 Method method = actionClass.getDeclaredMethod(methodName, HttpServletRequest.class, HttpServletResponse.class); 31 32 //打破方法的封装权限 33 method.setAccessible(true); 34 35 //调用控制器方法 36 method.invoke(this, request, response); 37 } catch (NoSuchMethodException e) { 38 e.printStackTrace(); 39 } catch (SecurityException e) { 40 e.printStackTrace(); 41 } catch (IllegalAccessException e) { 42 e.printStackTrace(); 43 } catch (IllegalArgumentException e) { 44 e.printStackTrace(); 45 } catch (InvocationTargetException e) { 46 e.printStackTrace(); 47 } 48 49 } 50 51 }
CREATE TABLE t_user( userId INT(11) PRIMARY KEY auto_increment, userName VARCHAR(30) not NULL, `passWord` VARCHAR(30) not NULL, realName VARCHAR(30) default null, weight DOUBLE(6,2) default null, height INT(3) default null, birthday DATE default null )ENGINE=INNODB CHARSET=utf8; SELECT * FROM t_user; INSERT INTO t_user VALUES (1,'ligang','123456','李刚',65.55,176,'1997-6-6'),
在工程中导入jar包:mysql-connector-java-3.0.17-ga-bin.jar
在工程中建立与数据库对应的po类:
package com.mmzs.bigdata.po; import java.io.Serializable; import java.sql.Date; public class User implements Serializable { //支持序列化才能在磁盘之间转化为二进制进行传输 private Integer userId; private String userName; private String passWord; private String realName; private Double weight; private Integer height; private Date birthday; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getPassWord() { return passWord; } public void setPassWord(String passWord) { this.passWord = passWord; } public String getRealName() { return realName; } public void setRealName(String realName) { this.realName = realName; } public Double getWeight() { return weight; } public void setWeight(Double weight) { this.weight = weight; } public Integer getHeight() { return height; } public void setHeight(Integer height) { this.height = height; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "User [userId=" + userId + ", userName=" + userName + ", passWord=" + passWord + ", realName=" + realName + ", weight=" + weight + ", height=" + height + ", birthday=" + birthday + "]"; } }
1 package com.mmzs.bigdata.dao; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 import java.sql.Connection; 6 import java.sql.DriverManager; 7 import java.sql.PreparedStatement; 8 import java.sql.ResultSet; 9 import java.sql.ResultSetMetaData; 10 import java.sql.SQLException; 11 import java.util.ArrayList; 12 import java.util.Date; 13 import java.util.List; 14 import java.util.Map; 15 16 import com.mysql.jdbc.Field; 17 18 public class BaseDao { 19 20 private static String url; 21 22 private static String driver; 23 24 private static String userName; 25 26 private static String passWord; 27 28 static { 29 url = "jdbc:mysql://127.0.0.1:3306/test?useUnique=true&characterEncoding=utf8"; 30 driver="com.mysql.jdbc.Driver"; 31 userName = "root"; 32 passWord = "123456"; 33 34 try { 35 Class.forName(driver); 36 } catch (ClassNotFoundException e) { 37 e.printStackTrace(); 38 } 39 } 40 41 /** 42 * 返回数据库链接 43 * @return 44 */ 45 public Connection getConnection() { 46 Connection conn = null; 47 try { 48 conn = DriverManager.getConnection(url, userName, passWord); 49 } catch (SQLException e) { 50 e.printStackTrace(); 51 } 52 53 return conn; 54 } 55 56 public <T> List<T> getEntityList(Class<T> entityClass, String sql, Object... params) { 57 //获取数据库连接 58 Connection conn = getConnection(); 59 if (null == conn) { 60 return null; 61 } 62 // 63 ResultSet res = null; 64 //对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的 65 PreparedStatement pstat = null;//import java.sql.PreparedStatement; 66 List<T> list = new ArrayList<>(); 67 try { 68 //预编译SQL语句 69 pstat = conn.prepareStatement(sql); 70 //为预编译好的SQL语句传递参数 71 for (int i = 0; i < params.length; i++) { 72 pstat.setObject(i+1, params[i]); 73 } 74 //执行SQL语句并返回结果集 75 res = pstat.executeQuery(); 76 //获取结果集元数据 77 ResultSetMetaData rsmd = res.getMetaData(); 78 //获取结果集中列的数量(字段的数量) 79 Integer columnNum = rsmd.getColumnCount(); 80 81 //简单类型包括数字类型、字符串类型和日期类型 82 if (String.class.isAssignableFrom(entityClass) || 83 Number.class.isAssignableFrom(entityClass) || 84 Date.class.isAssignableFrom(entityClass)) {//简单类型 85 T t = null; 86 //遍历每一条记录 87 while (res.next()) { 88 //类型转换必须类型兼容;低类型向高类型自动转换,反之强制转换; 89 t = (T)res.getObject(1);//返回单例,索引只能去1 90 list.add(t); 91 } 92 }else if(Map.class.isAssignableFrom(entityClass)) {//字典类型,Map是顶层接口 93 T t = null; 94 //获取的是类自身声明的所有方法 95 Method putMethod = entityClass.getDeclaredMethod("put", Object.class, Object.class); 96 while (res.next()) { 97 //调用反射调用Map实现累的无参数构造创建Map实例对象 98 t = entityClass.newInstance(); 99 //循环每条记录中的各个字段 100 for (int i = 0; i < columnNum; i++) { 101 //获取列名(它对应于Map中的Key) 102 String fieldName = rsmd.getColumnLabel(i+1); 103 //获取列值(它对应于Map中的Value) 104 Object fieldValue = res.getObject(fieldName); 105 //调用put方法往Map中添加键值对 106 putMethod.invoke(t, fieldName, fieldValue); 107 } 108 list.add(t); 109 } 110 }else { //实体类型 111 T t = null; 112 while (res.next()) { 113 //使用反射调用实体类的无参数构造创建实体对象 114 t = entityClass.newInstance(); 115 for (int i = 0; i < columnNum; i++) { 116 //获取结果集中的字段名(或别名) 117 String fieldName = rsmd.getColumnLabel(i+1); 118 //1.根据字段名获取字段值 119 Object fieldValue = res.getObject(fieldName); 120 //2.根据索引获取字段值 121 //Object fieldValue = res.getObject(i+1); 122 //getDeclaredField是可以获取一个类的所有字段. 123 //通过反射根据字段名查找实体类(User类)中的属性 124 java.lang.reflect.Field field = entityClass.getDeclaredField(fieldName); 125 //打开访问权限 126 field.setAccessible(true); 127 field.set(t, fieldValue); 128 } 129 list.add(t); 130 } 131 } 132 return list; 133 } catch (SQLException e) { 134 e.printStackTrace(); 135 } catch (NoSuchMethodException e) { 136 e.printStackTrace(); 137 } catch (SecurityException e) { 138 e.printStackTrace(); 139 } catch (InstantiationException e) { 140 e.printStackTrace(); 141 } catch (IllegalAccessException e) { 142 e.printStackTrace(); 143 } catch (IllegalArgumentException e) { 144 e.printStackTrace(); 145 } catch (InvocationTargetException e) { 146 e.printStackTrace(); 147 } catch (NoSuchFieldException e) { 148 e.printStackTrace(); 149 }finally { 150 try { 151 if (null != res) { 152 res.close(); 153 } 154 if (null != pstat) { 155 pstat.close(); 156 } 157 if (null != conn) { 158 conn.close(); 159 } 160 } catch (SQLException e) { 161 e.printStackTrace(); 162 } 163 } 164 return null; 165 } 166 167 168 169 170 171 172 // public static void main(String[] args) { 173 // Connection conn = new BaseDao().getConnection(); 174 // System.err.println(conn); 175 // } 176 }
1 package com.mmzs.bigdata.dao; 2 3 import com.mmzs.bigdata.po.User; 4 5 public interface UserDao { 6 public User selectUser(String userName, String passWord); 7 }
1 package com.mmzs.bigdata.dao; 2 3 import java.util.List; 4 5 import com.mmzs.bigdata.po.User; 6 7 public class UserDaoImpl extends BaseDao implements UserDao { 8 9 @Override 10 public User selectUser(String userName, String passWord) { 11 12 String sql = "select * from t_user where userName=? and passWord=?"; 13 List<User> userlist = this.getEntityList(User.class, sql, userName, passWord); 14 15 return null!= userlist&&!userlist.isEmpty()?userlist.get(0):null; 16 } 17 18 19 20 public static void main(String[] args) { 21 User user = new UserDaoImpl().selectUser("ligang", "123456"); 22 System.err.println(user); 23 } 24 }
在UserDaoImpl中利用20-23行代码测试是否能从数据库中取到数据。
5、建立service层
1 package com.mmzs.bigdata.service; 2 3 import com.mmzs.bigdata.po.User; 4 5 public interface UserService { 6 public User getUser(String userName, String passWord); 7 }
1 package com.mmzs.bigdata.service; 2 3 import com.mmzs.bigdata.po.User; 4 5 public class UserServiceImpl implements UserService { 6 7 @Override 8 public User getUser(String userName, String passWord) { 9 10 return null; 11 } 12 13 }
1 package com.mmzs.bigdata.action; 2 3 import javax.servlet.http.HttpServletRequest; 4 import javax.servlet.http.HttpServletResponse; 5 6 /** 7 * 用户模块控制器 8 * @author Administrator 9 * 10 */ 11 public class UserAction extends BaseAction { 12 13 /** 14 * 用户登录 15 * @param request 16 * @param response 17 */ 18 public void login(HttpServletRequest request, HttpServletResponse response) { 19 String userName = request.getParameter("userName"); 20 String passWord = request.getParameter("passWord"); 21 System.out.println(userName+":"+passWord); 22 } 23 }
将userAction配置到web.xml文件中
1 <?xml version="1.0" encoding="UTF-8"?> 2 <web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"> 3 <display-name>BigData6-1</display-name> 4 5 <servlet> 6 <servlet-name>userAction</servlet-name> 7 <servlet-class>com.mmzs.bigdata.action.UserAction</servlet-class> 8 </servlet> 9 10 <servlet-mapping> 11 <servlet-name>userAction</servlet-name> 12 <url-pattern>/userAction</url-pattern> 13 </servlet-mapping> 14 15 16 17 18 19 20 <welcome-file-list> 21 <welcome-file>index.jsp</welcome-file> 22 </welcome-file-list> 23 </web-app>
==========这是华丽的分割线============
发现自己的BaseDao中getEntityList方法名字不优美;换成executeDQL,同时它的子类UserDaoImpl也作相应的修改;同时url后面传递的参数名子也做了优化。
然后继续封装其它的方法,继续完善BaseDao:
1 package com.mmzs.bigdata.dao; 2 3 import java.lang.reflect.InvocationTargetException; 4 import java.lang.reflect.Method; 5 import java.sql.Connection; 6 import java.sql.DriverManager; 7 import java.sql.PreparedStatement; 8 import java.sql.ResultSet; 9 import java.sql.ResultSetMetaData; 10 import java.sql.SQLException; 11 import java.util.ArrayList; 12 import java.util.Date; 13 import java.util.List; 14 import java.util.Map; 15 16 import com.mysql.jdbc.Field; 17 18 public class BaseDao { 19 //URL指向要访问的数据库名mydata 20 private static String url; 21 //驱动程序名 22 private static String driver; 23 //MySQL配置时的用户名 24 private static String userName; 25 //MySQL配置时的密码 26 private static String passWord; 27 /** 28 * 连接数据库的驱动 29 */ 30 static { 31 url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8"; 32 driver="com.mysql.jdbc.Driver"; 33 userName = "root"; 34 passWord = "123456"; 35 try { 36 Class.forName(driver);//加载驱动类 37 } catch (ClassNotFoundException e) { 38 e.printStackTrace(); 39 } 40 } 41 42 /** 43 * 返回数据库链接 44 * @return 45 */ 46 public Connection getConnection() { 47 Connection conn = null; 48 try { 49 conn = DriverManager.getConnection(url, userName, passWord); 50 } catch (SQLException e) { 51 e.printStackTrace(); 52 } 53 54 return conn; 55 } 56 57 /** 58 * 执行通用插入操作 59 * @param pkClass 60 * @param sql 61 * @param params 62 * @return 主键列表(主键列表的长度代表插入函数的影响函数) 63 */ 64 public <T> List<T> executeInsert(Class<T> pkClass, String sql, Object... params) { 65 //获取数据库连接 66 Connection conn = getConnection(); 67 if (null == conn) return null; 68 69 T t = null; 70 ResultSet pkRes = null; 71 PreparedStatement pstat = null; 72 List<T> pkList = new ArrayList<T>(); 73 try { 74 //预编译SQL语句 75 pstat = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); 76 //为预编译好的SQL语句传递参数 77 for (int i = 0; i < params.length; i++) { 78 pstat.setObject(i+1, params[i]); 79 } 80 //执行增删改等操作返回影响的行数 81 pstat.executeUpdate(); 82 //获取生成的主键结果集 83 pkRes = pstat.getGeneratedKeys(); 84 //遍历主键结果集 85 while (pkRes.next()) { 86 //主键结果集中的每一条记录只有一列(这一列代表主键值),所以只能取下标1 87 t = (T) pkRes.getObject(1); 88 pkList.add(t); 89 } 90 return pkList; 91 92 } catch (SQLException e) { 93 e.printStackTrace(); 94 }finally { 95 try { 96 if (null != pkRes) { 97 pkRes.close(); 98 } 99 if (null != pstat) { 100 pstat.close(); 101 } 102 if (null != conn) { 103 conn.close(); 104 } 105 } catch (SQLException e) { 106 e.printStackTrace(); 107 } 108 } 109 110 return null; 111 } 112 113 /** 114 * 执行通用的增删改 115 * @param sql 116 * @param params 117 * @return 影响行数 118 */ 119 public Integer executeDML(String sql, Object... params) { 120 //获取数据库连接 121 Connection conn = getConnection(); 122 if (null == conn) return null; 123 124 Integer count = null; 125 PreparedStatement pstat = null; 126 //为预编译好的SQL语句传递参数 127 try { 128 //预编译SQL语句 129 pstat = conn.prepareStatement(sql); 130 //为预编译好的SQL语句传递参数 131 for (int i = 0; i < params.length; i++) { 132 pstat.setObject(i+1, params[i]); 133 } 134 //执行增删改等操作 135 count = pstat.executeUpdate(); 136 return count; 137 138 } catch (SQLException e) { 139 e.printStackTrace(); 140 }finally { 141 try { 142 if (null != pstat) { 143 pstat.close(); 144 } 145 if (null != conn) { 146 conn.close(); 147 } 148 } catch (SQLException e) { 149 e.printStackTrace(); 150 } 151 } 152 return 0; 153 } 154 155 /** 156 * 执行数据库查询操作 157 * @param entityClass 158 * @param sql 159 * @param params 160 * @return 结果集 161 */ 162 public <T> List<T> executeDQL(Class<T> entityClass, String sql, Object... params) { 163 //获取数据库连接 164 Connection conn = getConnection(); 165 if (null == conn) { 166 return null; 167 } 168 // 169 ResultSet res = null; 170 //对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的 171 PreparedStatement pstat = null;//import java.sql.PreparedStatement; 172 List<T> list = new ArrayList<>(); 173 try { 174 //预编译SQL语句 175 pstat = conn.prepareStatement(sql); 176 //为预编译好的SQL语句传递参数 177 for (int i = 0; i < params.length; i++) { 178 pstat.setObject(i+1, params[i]); 179 } 180 //执行SQL语句并返回结果集 181 res = pstat.executeQuery(); 182 //获取结果集元数据 183 ResultSetMetaData rsmd = res.getMetaData(); 184 //获取结果集中列的数量(字段的数量) 185 Integer columnNum = rsmd.getColumnCount(); 186 187 //简单类型包括数字类型、字符串类型和日期类型 188 if (String.class.isAssignableFrom(entityClass) || 189 Number.class.isAssignableFrom(entityClass) || 190 Date.class.isAssignableFrom(entityClass)) {//简单类型 191 T t = null; 192 //遍历每一条记录 193 while (res.next()) { 194 //类型转换必须类型兼容;低类型向高类型自动转换,反之强制转换; 195 t = (T)res.getObject(1);//返回单例,索引只能去1 196 list.add(t); 197 } 198 }else if(Map.class.isAssignableFrom(entityClass)) {//字典类型,Map是顶层接口 199 T t = null; 200 //获取的是类自身声明的所有方法 201 Method putMethod = entityClass.getDeclaredMethod("put", Object.class, Object.class); 202 while (res.next()) { 203 //调用反射调用Map实现累的无参数构造创建Map实例对象 204 t = entityClass.newInstance(); 205 //循环每条记录中的各个字段 206 for (int i = 0; i < columnNum; i++) { 207 //获取列名(它对应于Map中的Key) 208 String fieldName = rsmd.getColumnLabel(i+1); 209 //获取列值(它对应于Map中的Value) 210 Object fieldValue = res.getObject(fieldName); 211 //调用put方法往Map中添加键值对 212 putMethod.invoke(t, fieldName, fieldValue); 213 } 214 list.add(t); 215 } 216 }else { //实体类型 217 T t = null; 218 while (res.next()) { 219 //使用反射调用实体类的无参数构造创建实体对象 220 t = entityClass.newInstance(); 221 for (int i = 0; i < columnNum; i++) { 222 //获取结果集中的字段名(或别名) 223 String fieldName = rsmd.getColumnLabel(i+1); 224 //1.根据字段名获取字段值 225 Object fieldValue = res.getObject(fieldName); 226 //2.根据索引获取字段值 227 //Object fieldValue = res.getObject(i+1); 228 //getDeclaredField是可以获取一个类的所有字段. 229 //通过反射根据字段名查找实体类(User类)中的属性 230 java.lang.reflect.Field field = entityClass.getDeclaredField(fieldName); 231 //打开访问权限 232 field.setAccessible(true); 233 field.set(t, fieldValue); 234 } 235 list.add(t); 236 } 237 } 238 return list; 239 } catch (SQLException e) { 240 e.printStackTrace(); 241 } catch (NoSuchMethodException e) { 242 e.printStackTrace(); 243 } catch (SecurityException e) { 244 e.printStackTrace(); 245 } catch (InstantiationException e) { 246 e.printStackTrace(); 247 } catch (IllegalAccessException e) { 248 e.printStackTrace(); 249 } catch (IllegalArgumentException e) { 250 e.printStackTrace(); 251 } catch (InvocationTargetException e) { 252 e.printStackTrace(); 253 } catch (NoSuchFieldException e) { 254 e.printStackTrace(); 255 }finally { 256 try { 257 if (null != res) { 258 res.close(); 259 } 260 if (null != pstat) { 261 pstat.close(); 262 } 263 if (null != conn) { 264 conn.close(); 265 } 266 } catch (SQLException e) { 267 e.printStackTrace(); 268 } 269 } 270 return null; 271 } 272 273 274 275 276 277 278 // public static void main(String[] args) { 279 // Connection conn = new BaseDao().getConnection(); 280 // System.err.println(conn); 281 // } 282 }
在UserDaoImpl中测试:
1 package com.mmzs.bigdata.dao; 2 3 import java.sql.Date; 4 import java.util.List; 5 6 import com.mmzs.bigdata.po.User; 7 8 public class UserDaoImpl extends BaseDao implements UserDao { 9 10 @Override 11 public User selectUser(String userName, String passWord) { 12 13 String sql = "select * from t_user where userName=? and passWord=?"; 14 List<User> userlist = this.executeDQL(User.class, sql, userName, passWord); 15 16 return null!= userlist&&!userlist.isEmpty()?userlist.get(0):null; 17 } 18 19 20 21 /** 22 * @param args 23 */ 24 public static void main(String[] args) { 25 //测试executeDQL 26 // User user = new UserDaoImpl().selectUser("ligang", "123456"); 27 // System.out.println(user); 28 29 //测试executeInsert 30 // String sql = "insert into t_user(username,password,realname,weight,height,birthday) values(?,?,?,?,?,?),(?,?,?,?,?,?)"; 31 // List<Integer> pkList = new UserDaoImpl().executeInsert(Integer.class, sql, "zhangsan","123456","张三",75.55,176,Date.valueOf("1997-6-6"),"lisi","lisi","张三",55.55,176,Date.valueOf("2005-6-6")); 32 // System.out.println("主键列表:"+pkList); 33 // System.out.println("影响行数:"+pkList.size()); 34 35 //测试executeDML 36 String sql = "update t_user set username=?,password=?,realname=?,weight=?,height=?,birthday=? where userid=?"; 37 Integer count = new UserDaoImpl().executeDML( sql, "ligang","123456","张三",75.55,176,Date.valueOf("1997-6-6"),1); 38 System.out.println("影响行数:"+count); 39 } 40 }
==========这是华丽的分割线============
发现自己的BaseDao中的连接数据库的部分写的太固定;比如你需要修改密码时,需要改源代码,然后提交到运维测试,需要走一大圈流程;所以接下来我们把连接数据库的部分写到一个文本中,这样子需要修改时就不需要修改源代码了;
首先将如下代码进行一定修改,写到src下的db.properties中:
url = "jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8"; driver="com.mysql.jdbc.Driver"; userName = "root"; passWord = "123456";
在db.properties文件中时以键值对的形式存储的;以第一个等号为分界线,默认左右都为字符串,=左边为键,右边为值;为了便于阅读,如使用的是jdbc的,就用jdbc.xxx
jdbc.url = jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 jdbc.driver=com.mysql.jdbc.Driver jdbc.userName = root jdbc.passWord =123456
package com.mmzs.bigdata.dao; import java.io.IOException; import java.io.InputStream; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.ResultSetMetaData; import java.sql.SQLException; import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.Map; import java.util.Properties; public class BaseDao { //URL指向要访问的数据库名mydata private static String url; //驱动程序名 private static String driver; //MySQL配置时的用户名 private static String userName; //MySQL配置时的密码 private static String passWord; /** * 连接数据库的驱动 */ static { try { Properties properties = new Properties(); //此处/表示src根路径;创建指向磁盘文件中属性文件的输入流 InputStream fis = BaseDao.class.getResourceAsStream("/db.properties"); //将属性文件中的内容从磁盘读入到内存中 properties.load(fis); //取连接数据库的参数值 url = properties.getProperty("jdbc.url"); driver = properties.getProperty("jdbc.driver"); userName = properties.getProperty("jdbc.userName"); passWord = properties.getProperty("jdbc.passWord"); //将驱动类装载到JVM内存的方法区 Class.forName(driver); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } } /** * 返回数据库链接 * @return */ public Connection getConnection() { Connection conn = null; try { conn = DriverManager.getConnection(url, userName, passWord); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 执行通用插入操作 * @param pkClass * @param sql * @param params * @return 主键列表(主键列表的长度代表插入函数的影响函数) */ public <T> List<T> executeInsert(Class<T> pkClass, String sql, Object... params) { //获取数据库连接 Connection conn = getConnection(); if (null == conn) return null; T t = null; ResultSet pkRes = null; PreparedStatement pstat = null; List<T> pkList = new ArrayList<T>(); try { //预编译SQL语句 pstat = conn.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS); //为预编译好的SQL语句传递参数 for (int i = 0; i < params.length; i++) { pstat.setObject(i+1, params[i]); } //执行增删改等操作返回影响的行数 pstat.executeUpdate(); //获取生成的主键结果集 pkRes = pstat.getGeneratedKeys(); //遍历主键结果集 while (pkRes.next()) { //主键结果集中的每一条记录只有一列(这一列代表主键值),所以只能取下标1 t = (T) pkRes.getObject(1); pkList.add(t); } return pkList; } catch (SQLException e) { e.printStackTrace(); }finally { try { if (null != pkRes) { pkRes.close(); } if (null != pstat) { pstat.close(); } if (null != conn) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } return null; } /** * 执行通用的增删改 * @param sql * @param params * @return 影响行数 */ public Integer executeDML(String sql, Object... params) { //获取数据库连接 Connection conn = getConnection(); if (null == conn) return null; Integer count = null; PreparedStatement pstat = null; //为预编译好的SQL语句传递参数 try { //预编译SQL语句 pstat = conn.prepareStatement(sql); //为预编译好的SQL语句传递参数 for (int i = 0; i < params.length; i++) { pstat.setObject(i+1, params[i]); } //执行增删改等操作 count = pstat.executeUpdate(); return count; } catch (SQLException e) { e.printStackTrace(); }finally { try { if (null != pstat) { pstat.close(); } if (null != conn) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } return 0; } /** * 执行数据库查询操作 * @param entityClass * @param sql * @param params * @return 结果集 */ public <T> List<T> executeDQL(Class<T> entityClass, String sql, Object... params) { //获取数据库连接 Connection conn = getConnection(); if (null == conn) { return null; } // ResultSet res = null; //对于只执行一次的SQL语句选择Statement是最好的. 相反, 如果SQL语句被多次执行选用PreparedStatement是最好的 PreparedStatement pstat = null;//import java.sql.PreparedStatement; List<T> list = new ArrayList<>(); try { //预编译SQL语句 pstat = conn.prepareStatement(sql); //为预编译好的SQL语句传递参数 for (int i = 0; i < params.length; i++) { pstat.setObject(i+1, params[i]); } //执行SQL语句并返回结果集 res = pstat.executeQuery(); //获取结果集元数据 ResultSetMetaData rsmd = res.getMetaData(); //获取结果集中列的数量(字段的数量) Integer columnNum = rsmd.getColumnCount(); //简单类型包括数字类型、字符串类型和日期类型 if (String.class.isAssignableFrom(entityClass) || Number.class.isAssignableFrom(entityClass) || Date.class.isAssignableFrom(entityClass)) {//简单类型 T t = null; //遍历每一条记录 while (res.next()) { //类型转换必须类型兼容;低类型向高类型自动转换,反之强制转换; t = (T)res.getObject(1);//返回单例,索引只能去1 list.add(t); } }else if(Map.class.isAssignableFrom(entityClass)) {//字典类型,Map是顶层接口 T t = null; //获取的是类自身声明的所有方法 Method putMethod = entityClass.getDeclaredMethod("put", Object.class, Object.class); while (res.next()) { //调用反射调用Map实现累的无参数构造创建Map实例对象 t = entityClass.newInstance(); //循环每条记录中的各个字段 for (int i = 0; i < columnNum; i++) { //获取列名(它对应于Map中的Key) String fieldName = rsmd.getColumnLabel(i+1); //获取列值(它对应于Map中的Value) Object fieldValue = res.getObject(fieldName); //调用put方法往Map中添加键值对 putMethod.invoke(t, fieldName, fieldValue); } list.add(t); } }else { //实体类型 T t = null; while (res.next()) { //使用反射调用实体类的无参数构造创建实体对象 t = entityClass.newInstance(); for (int i = 0; i < columnNum; i++) { //获取结果集中的字段名(或别名) String fieldName = rsmd.getColumnLabel(i+1); //1.根据字段名获取字段值 Object fieldValue = res.getObject(fieldName); //2.根据索引获取字段值 //Object fieldValue = res.getObject(i+1); //getDeclaredField是可以获取一个类的所有字段. //通过反射根据字段名查找实体类(User类)中的属性 java.lang.reflect.Field field = entityClass.getDeclaredField(fieldName); //打开访问权限 field.setAccessible(true); field.set(t, fieldValue); } list.add(t); } } return list; } catch (SQLException e) { e.printStackTrace(); } catch (NoSuchMethodException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (IllegalArgumentException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); }finally { try { if (null != res) { res.close(); } if (null != pstat) { pstat.close(); } if (null != conn) { conn.close(); } } catch (SQLException e) { e.printStackTrace(); } } return null; } }
==========这是华丽的分割线============
接下我们尝试将sql语句写到文本文件中来读取,优点同上;
package com.mmzs.bigdata.dao; import java.sql.Date; import java.util.List; import com.mmzs.bigdata.po.User; public class UserDaoImpl extends BaseDao implements UserDao { @Override public User selectUser(String userName, String passWord) { String sql = "select * from t_user where userName=? and passWord=?"; List<User> userlist = this.executeDQL(User.class, sql, userName, passWord); return null!= userlist&&!userlist.isEmpty()?userlist.get(0):null; } /** * 测试xml的相关操作 */ public static void main(String[] args) { Map<String, Object> user = new HashMap<String, Object>(); user.put("userId", 12); user.put("userName", "ligang"); user.put("passWord", "liagan"); System.out.println("======序列化======"); XStream stream = new XStream(); String xml = stream.toXML(user); System.out.println(xml); System.out.println("======反序列化======"); Map<String, Object> newUser = (Map<String, Object>) stream.fromXML(xml); String userName = (String) newUser.get("userName"); System.out.println(newUser+"==="+userName); } }
最后,在src下面新建sql.xml;
<?xml version="1.0" encoding="UTF-8"?> <map> <entry> <string>selectUser</string> <string>select * from t_user where userName=? and passWord=?</string> </entry> </map>
在UserDaoImpl 中进行最终测试;
package com.mmzs.bigdata.dao; import java.io.InputStream; import java.sql.Date; public class UserDaoImpl extends BaseDao implements UserDao { private Map<String, String> sqlMap; public UserDaoImpl() { XStream stream = new XStream(); InputStream fis = UserDao.class.getResourceAsStream("/sql.xml"); sqlMap = (Map<String, String>) stream.fromXML(fis); } @Override public User selectUser(String userName, String passWord) { String sql = sqlMap.get("selectUser"); List<User> userlist = this.executeDQL(User.class, sql, userName, passWord); return null!= userlist&&!userlist.isEmpty()?userlist.get(0):null; } public static void main(String[] args) { User user = new UserDaoImpl().selectUser("ligang", "123456"); System.out.println(user); } }
==========这是华丽的分割线============
现在准备工作就绪,我们开始写登录页面进行登陆验证:
因为Dao层已经写完了,所以直接开始写Service实现层:
1 package com.mmzs.bigdata.service; 2 3 import com.mmzs.bigdata.dao.UserDao; 4 import com.mmzs.bigdata.dao.UserDaoImpl; 5 import com.mmzs.bigdata.po.User; 6 7 public class UserServiceImpl implements UserService { 8 9 private UserDao userDao; 10 11 public UserServiceImpl() { 12 userDao = new UserDaoImpl(); 13 } 14 15 16 @Override 17 public User getUser(String userName, String passWord) { 18 return userDao.selectUser(userName, passWord); 19 } 20 21 }
然后完善UserAction类:
1 package com.mmzs.bigdata.action; 2 3 import java.io.IOException; 4 5 import javax.servlet.ServletException; 6 import javax.servlet.http.HttpServletRequest; 7 import javax.servlet.http.HttpServletResponse; 8 9 import com.mmzs.bigdata.po.User; 10 import com.mmzs.bigdata.service.UserService; 11 import com.mmzs.bigdata.service.UserServiceImpl; 12 13 /** 14 * 用户模块控制器 15 * @author Administrator 16 * 17 */ 18 public class UserAction extends BaseAction { 19 20 private UserService userService; 21 22 public UserAction() { 23 userService = new UserServiceImpl(); 24 } 25 /** 26 * 用户登录 27 * @param request 28 * @param response 29 * @throws IOException 30 * @throws ServletException 31 */ 32 public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 33 String userName = request.getParameter("userName"); 34 String passWord = request.getParameter("passWord"); 35 User user = userService.getUser(userName, passWord); 36 if (null != user) {//登陆成功 37 request.getSession().setAttribute("loginUser", user); 38 request.getRequestDispatcher("/main.jsp").forward(request, response); 39 System.out.println("登陆成功!"); 40 return;//如果你是一个比较有良知的人,加一个return;因为加了执行到此处就结束,否则会往下执行自动结束;理论上加与不加效果相同; 41 } else {//登录失败 42 request.setAttribute("loginError", "用户名或密码输入错误"); 43 request.getRequestDispatcher("/login.jsp").forward(request, response); 44 } 45 } 46 }
写出UserAction类成功和失败返回的界面:
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> </head> <body> </body> </html> 登陆成功!
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <% String path = request.getContextPath(); String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; %> <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> <html> <head> <base href="<%=basePath%>"> <title>My JSP 'login.jsp' starting page</title> <meta http-equiv="pragma" content="no-cache"> <meta http-equiv="cache-control" content="no-cache"> <meta http-equiv="expires" content="0"> <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> <meta http-equiv="description" content="This is my page"> <!-- <link rel="stylesheet" type="text/css" href="styles.css"> --> <script type="text/javascript"> //用于验证登陆参数 function validate(Form) { var userName = Form.userName.value; var passWord = Form.passWord.value; if(""==userName || ""==passWord) { alert("请完整的输入用户名和密码"); return false;//取消表但提交 } } </script> </head> <body> <span style="font-size: 22px;font-weight: bolder;color: red">用户登陆</span> <hr color="green" size="2" width="100%" /> <form id="loginForm" action="/BigData6-1/userAction" method="post"> <input type="hidden" name="method" value="login"> <input name="userName" ><br><br> <input name="passWord" type="password" ><br><br> <!-- 只有带了name属性的才会被提交到服务器 --> <input type="submit" value="登录" onclick="return validate(this.form)"> </form> <span style="font-size: 14px;font-weight: bolder;color: red">${loginError }</span> </body> </html>
写到此处,整个程序整体已经比较完整了;
==========这是华丽的分割线============
接下来,我们增加点用户,然后打算做一个用户列表的分页查询:
1、首先就需要在dao层写一个查询所有用户的方法
1 <?xml version="1.0" encoding="UTF-8"?> 2 <map> 3 <entry> 4 <string>selectUser</string> 5 <string>select * from t_user where userName=? and passWord=?</string> 6 </entry> 7 <entry> 8 <string>selectUserList</string> 9 <string>select * from t_user limit ?,?</string> 10 </entry> 11 <entry> 12 <string>selectUserCount</string> 13 <string>select count(1) from t_user</string> 14 </entry> 15 </map>
/** * 根据通用查询查询用户 * @param params * @return */ public List<User> selectUserList(Map<String, Object> params);
@Override public List<User> selectUserList(Map<String, Object> params) { Integer start = (Integer) params.get("start"); Integer count = (Integer) params.get("count"); String sql = sqlMap.get("selectUserList"); List<User> userList = executeDQL(User.class, sql, start, count); return userList; }
2、写出service层
/** * @param curPage 跳转到的目标也 * @param count 每页显示的记录数量 * @return 分页字典对象 */ public Map<String, Object> getUserList(Integer curPage, Integer count);
package com.mmzs.bigdata.service; import java.util.HashMap; import java.util.List; import java.util.Map; import com.mmzs.bigdata.dao.UserDao; import com.mmzs.bigdata.dao.UserDaoImpl; import com.mmzs.bigdata.po.User; public class UserServiceImpl implements UserService { private UserDao userDao; public UserServiceImpl() { userDao = new UserDaoImpl(); } @Override public User getUser(String userName, String passWord) { return userDao.selectUser(userName, passWord); } @Override public Map<String, Object> getUserList(Integer curPage, Integer count) { //计算分页的起始索引 Integer start = (curPage-1)*count; //包装分页字典 Map<String, Object> params = new HashMap<String, Object>(); params.put("start", start); params.put("count", count); //通过分页参数查询分页数据 List<User> userList = userDao.selectUserList(params); //查询表的总记录数量 Integer totalCount = userDao.selectUserCount(); //计算总页数 Integer totalPage = totalCount/count; if (totalCount%count != 0) {//如果有余数,则总页数加1 totalPage++; } //包装分页数据字典 Map<String, Object> resMap = new HashMap<String, Object>(); resMap.put("userList", userList); resMap.put("curPage", curPage); resMap.put("totalPage", totalPage); return resMap; } }
1 package com.mmzs.bigdata.action; 2 3 import java.io.IOException; 4 import java.util.HashMap; 5 import java.util.Map; 6 7 import javax.servlet.ServletException; 8 import javax.servlet.http.HttpServletRequest; 9 import javax.servlet.http.HttpServletResponse; 10 11 import com.mmzs.bigdata.po.User; 12 import com.mmzs.bigdata.service.UserService; 13 import com.mmzs.bigdata.service.UserServiceImpl; 14 15 /** 16 * 用户模块控制器 17 * @author Administrator 18 * 19 */ 20 public class UserAction extends BaseAction { 21 22 private UserService userService; 23 24 public UserAction() { 25 userService = new UserServiceImpl(); 26 } 27 /** 28 * 用户登录 29 * @param request 30 * @param response 31 * @throws IOException 32 * @throws ServletException 33 */ 34 public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 35 String userName = request.getParameter("userName"); 36 String passWord = request.getParameter("passWord"); 37 38 User user = userService.getUser(userName, passWord); 39 if (null != user) {//登陆成功 40 request.getSession().setAttribute("loginUser", user); 41 Map<String, Object> resMap = userService.getUserList(1, COUNT); 42 43 request.setAttribute("curPage", resMap.get("curPage")); 44 request.setAttribute("totalPage", resMap.get("totalPage")); 45 request.setAttribute("userList", resMap.get("userList")); 46 System.out.println(resMap); 47 request.getRequestDispatcher("/main.jsp").forward(request, response); 48 return;//如果你是一个比较有良知的人,加一个return;因为加了执行到此处就结束,否则会往下执行自动结束;理论上加与不加效果相同; 49 } else {//登录失败 50 request.setAttribute("loginError", "用户名或密码输入错误"); 51 request.getRequestDispatcher("/login.jsp").forward(request, response); 52 } 53 } 54 }
每页显示的记录数量
/** * 每页显示的记录数量 */ protected static final Integer COUNT = 5;
在BaseAction中用一个常量固定化,分页所需要的参数:
/** * 总数量 * @return */ public Integer selectUserCount();
@Override public Integer selectUserCount() { String sql = sqlMap.get("selectUserCount"); List<Long> counts = executeDQL(Long.class, sql); return null!= counts&&!counts.isEmpty()?counts.get(0).intValue():null; }
写界面,并且分页所需参数名字保持一致:
1 <%@ page language="java" pageEncoding="UTF-8"%> 2 <script type="text/javascript"> 3 var curPage=${curPage} 4 var totalPage=${totalPage} 5 6 //首页 7 function firstPage(){ 8 if(curPage<=1){ 9 alert("当前页已经是第一页!"); 10 return; 11 } 12 sepPage(1);//执行翻页(翻到第一页) 13 } 14 15 //上一页 16 function prePage(){ 17 if(curPage<=1){ 18 alert("当前页已经是第一页!"); 19 return; 20 } 21 sepPage(curPage-1);//执行翻页 22 } 23 24 //下一页 25 function nextPage(){ 26 if(curPage>=totalPage){ 27 alert("当前页已经是末页!"); 28 return; 29 } 30 sepPage(curPage+1);//执行翻页 31 } 32 33 //末页 34 function lastPage(){ 35 if(curPage>=totalPage){ 36 alert("当前页已经是末页!"); 37 return; 38 } 39 sepPage(totalPage);//执行翻页 40 } 41 42 //跳转到 43 function gotoPage(){ 44 var toPage=document.getElementById("toPage").value; 45 var rex=/^\d+$/ 46 if(!rex.test(toPage)||parseInt(toPage)<1||parseInt(toPage)>totalPage){ 47 alert("输入的页号不合理!"); 48 return; 49 } 50 if(parseInt(curPage)==parseInt(toPage)){ 51 alert("当前页已经是你输入的页号"); 52 return; 53 } 54 sepPage(toPage); 55 } 56 </script> 57 <div style="text-align: center;"> 58 <pre style="display: inline;font-size:16px;">当前是第:${curPage}/${totalPage}页 </pre> 59 <input type="button" value="首页" onclick="firstPage()"/> 60 <input type="button" value="上一页" onclick="prePage()"/> 61 <input type="button" value="下一页" onclick="nextPage()"/> 62 <input type="button" value="末页" onclick="lastPage()"/> 63 <input type="button" value="跳转到" onclick="gotoPage()"/> 64 <input id="toPage" name="toPage" style="width:50px;"/>页 65 </div>
1 <%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> 2 <%@ taglib uri="http://java.sun.com/jstl/core_rt" prefix="c" %> 3 <% 4 String path = request.getContextPath(); 5 String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 6 %> 7 8 <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 9 <html> 10 <head> 11 <base href="<%=basePath%>"> 12 13 <title>My JSP 'login.jsp' starting page</title> 14 15 <meta http-equiv="pragma" content="no-cache"> 16 <meta http-equiv="cache-control" content="no-cache"> 17 <meta http-equiv="expires" content="0"> 18 <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 19 <meta http-equiv="description" content="This is my page"> 20 <style type="text/css"> 21 table,td,th{ 22 border: 1px solid black; 23 height: 20px; 24 } 25 </style> 26 27 </head> 28 29 <body> 30 <span style="font-size: 22px;font-weight: bolder;color: red">用户信息表</span> 31 <hr color="green" size="2" width="100%" /> 32 <div id="dataDiv"> 33 <table weight="600" height="400" cellpadding="0" cellspacing="0"> 34 <thead> 35 <tr> 36 <th> 37 <input type="checkbox" id="allSel">全选 38 </th> 39 <th>用户名</th> 40 <th>密码</th> 41 <th>姓名</th> 42 <th>体重</th> 43 <th>身高</th> 44 <th>生日</th> 45 <th>操作</th> 46 </tr> 47 </thead> 48 <tbody> 49 <c:forEach items="${userList }" var="user" varStatus="stat"> 50 <tr> 51 <td><input type="checkbox" name="userIds" value="${user.userId }"></td> 52 <td>${user.userName }</td> 53 <td>${user.passWord }</td> 54 <td>${user.realName }</td> 55 <td>${user.weight }</td> 56 <td>${user.height }</td> 57 <td>${user.birthday }</td> 58 <td> 59 <input type="button" value="删除"> 60 <input type="button" value="修改"> 61 </td> 62 </tr> 63 </c:forEach> 64 </tbody> 65 </table> 66 </div> 67 </body> 68 </html>
进行到此时,测试代码,成功登陆就已经能够得到用户列表了。
<script type="text/javascript"> //分页函数 function sepPage(toPage) { window.location.href="/BigData6-1/userAction?method=list&curPage="+toPage; } </script>
<tfoot> <tr> <td colspan="8"> <%@ include file="paging.jsp" %> </td> </tr> </tfoot>
/** * 列表分页 * @param request * @param response * @throws IOException * @throws ServletException */ public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String curPage = request.getParameter("curPage"); Map<String, Object> resMap = userService.getUserList(Integer.parseInt(curPage), COUNT); request.setAttribute("curPage", resMap.get("curPage")); request.setAttribute("totalPage", resMap.get("totalPage")); request.setAttribute("userList", resMap.get("userList")); request.getRequestDispatcher("/main.jsp").forward(request, response); }
进行到此时,测试代码,成功登陆就已经能够得到用户列表并操作分页功能了。
<script type="text/javascript"> //分页函数 function sepPage(toPage) { //window.location.href="/BigData6-1/userAction?method=list&curPage="+toPage; //var div = $("div#dataDiv").get(0); //ajax回调函数 function callBack(data){ $("div#dataDiv").html(data); } /* * A、如果需要get方式提交则可以调$.get(…) B、get与post一共有四个参数: 第一个参数:提交的服务端地址 第二个参数:提交到服务端的参数 第三个参数:服务端成功响应回来之后的回调函数,回调函数的参数表示服务端响应回来的数据 第四个参数:服务端响应回来的数据格式(html、json、xml) */ $.post("/BigData6-1/userAction", "method=list&curPage="+toPage, callBack, "html") } </script>
/** * 列表分页 * @param request * @param response * @throws IOException * @throws ServletException */ public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String curPage = request.getParameter("curPage"); Map<String, Object> resMap = userService.getUserList(Integer.parseInt(curPage), COUNT); //大公司操作 // StringWriter writer = new StringWriter(); // ObjectMapper mapper = new ObjectMapper(); // mapper.writeValue(writer, resMap); // String jsonString = writer.toString(); // response.getWriter().write(jsonString); //小公司操作 request.setAttribute("curPage", resMap.get("curPage")); request.setAttribute("totalPage", resMap.get("totalPage")); request.setAttribute("userList", resMap.get("userList")); //request.getRequestDispatcher("/main.jsp").forward(request, response); request.getRequestDispatcher("/table.jsp").forward(request, response); }
<%@ page language="java" import="java.util.*" pageEncoding="utf-8"%> <%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %> <table weight="600" height="400" cellpadding="0" cellspacing="0"> <thead> <tr> <th> <input type="checkbox" id="allSel"> 全选 </th> <th>用 户 名</th> <th>密 码</th> <th>姓 名</th> <th>体 重</th> <th>身 高</th> <th>生 日</th> <th>操 作</th> </tr> </thead> <tbody> <c:forEach items="${userList }" var="user" varStatus="stat"> <tr> <td><input type="checkbox" name="userIds" value="${user.userId }"></td> <td>${user.userName }</td> <td>${user.passWord }</td> <td>${user.realName }</td> <td>${user.weight }</td> <td>${user.height }</td> <td>${user.birthday }</td> <td> <input type="button" value="删除"> <input type="button" value="修改"> </td> </tr> </c:forEach> </tbody> <tfoot> <tr> <td colspan="8"> <%@ include file="paging.jsp" %> </td> </tr> </tfoot> </table>
进行到此时,测试代码,成功登陆就,同样能够得到用户列表并操作分页功能,只是此时我们使用的传值的方式不同了。
<entry> <string>selectUserListByCondition</string> <string>select * from t_user where realName like ? limit ?,?</string> </entry> <entry> <string>selectUserCountByCondition</string> <string>select count(1) from t_user where realName like ?</string> </entry>
在main方法中添加:
<form id="queryForm">
<input type="hidden" name="method" value="list" />
<input type="hidden" name="curPage" value="1" />
姓名:<input name="realName" />
<input type="button" value="查询" onclick="sepPage(1)" />
</form>
<div id="dataDiv">
<script type="text/javascript"> //分页函数 function sepPage(toPage) { var JForm = $("form#queryForm"); //获取name=curPage的输入框中的值 $("input[name=curPage]:hidden",JForm).val(toPage); //序列表表格内容为字符串。 var queryString = JForm.serialize(); //ajax回调函数 function callBack(data){ $("div#dataDiv").html(data); } /* * A、如果需要get方式提交则可以调$.get(…) B、get与post一共有四个参数: 第一个参数:提交的服务端地址 第二个参数:提交到服务端的参数 第三个参数:服务端成功响应回来之后的回调函数,回调函数的参数表示服务端响应回来的数据 第四个参数:服务端响应回来的数据格式(html、json、xml) */ $.post("/BigData6-1/userAction", queryString, callBack, "html") } </script>
此时sepPage函数调用的是Action的list函数,由于之前都是实用的service层的getUserList函数来进行具体操作,但是之前都是只传递了两个参数(但前页curPage和每页显示的记录数COUNT);要修改起来比较麻烦,所以我们此时选择new一个Map来传参;则:
public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String curPage = request.getParameter("curPage");//curPage得到的是String类型需转化为integer类型 String realName = request.getParameter("realName"); realName = new String(realName.getBytes("ISO-8859-1"), "UTF-8");//需要转码中文才能搞定 Map<String, Object> args = new HashMap<String, Object>(); args.put("curPage", Integer.parseInt(curPage)); args.put("count", COUNT); if (null != realName && !realName.trim().isEmpty()) { args.put("realName", realName); } Map<String, Object> resMap = userService.getUserList(args);
public Map<String, Object> getUserList(Map<String, Object> params);
@Override public Map<String, Object> getUserList(Map<String, Object> args) { //取出分页查询参数 Integer curPage = (Integer)args.get("curPage"); Integer count = (Integer) args.get("count"); String realName = (String) args.get("realName"); //计算分页的起始索引 Integer start = (curPage-1)*count; //包装分页字典 Map<String, Object> params = new HashMap<String, Object>(); params.put("start", start); params.put("count", count); if (null != realName) {//分页查询显示列表 params.put("realName", "%"+realName+"%"); } //查询表的总记录数量 Integer totalCount = userDao.selectUserCount(params); //计算总页数 Integer totalPage = totalCount/count; if (totalCount%count != 0) {//如果有余数,则总页数加1 totalPage++; } //通过分页参数查询分页数据 List<User> userList = userDao.selectUserList(params);
@Override public Integer selectUserCount(Map<String, Object> params) { Object realName = params.get("realName"); List<Number> counts = null; if (null == realName) {//登陆之后查询表的总数量 String sql = sqlMap.get("selectUserCount"); counts = executeDQL(Number.class, sql);//用Number可以避免一切返回类型不兼容问题 }else { //条件查询总数量 String sql = sqlMap.get("selectUserCountByCondition"); counts = executeDQL(Number.class, sql, realName); } return null!= counts&&!counts.isEmpty()?counts.get(0).intValue():null; }
@Override public List<User> selectUserList(Map<String, Object> params) { Integer start = (Integer) params.get("start"); Integer count = (Integer) params.get("count"); Object realName = params.get("realName"); List<User> userList = null; if (null == realName) {//登陆之后显示主页列表 String sql = sqlMap.get("selectUserList"); userList = executeDQL(User.class, sql, start, count); }else { //条件查询加分页显示列表 String sql = sqlMap.get("selectUserListByCondition"); userList = executeDQL(User.class, sql, realName, start, count); } return userList; }
进行到此时,测试代码,成功登陆就,同样能够得到用户列表并操作分页功能。
==========这是华丽的分割线============
<script type="text/javascript"> //用户注册函数 function register(Form) { var dict = { url:"/BigData6-1/userAction?method=register", type:"post", //dataType:"xml", dataType:"json", beforeSubmit:function(dataDictList, JForm, options){ //此函数用于在提交表单之前进行验证,如果此函数返回false //则取消表单的提交 }, success:function(jsonDict) { //此函数是服务端成功响应回来之后需要回调的函数 $("input:button", Form).val("继续注册"); //修改图片的路径 $("img#userPhoto").attr("src",jsonDict.photoPath); /* //从XML文档中提取图片路径 var imgPath =$("body",xmlDoc).html(); alert(imgPath); //修改图片的路径 $("img#userPhoto").attr("src",imgPath); */ } } //使用ajax提交带有文件域的表单 $(Form).ajaxSubmit(dict); } </script>
1 package com.mmzs.bigdata.action; 2 3 import java.io.File; 4 import java.io.IOException; 5 import java.io.PrintWriter; 6 import java.io.StringWriter; 7 import java.sql.Date; 8 import java.util.HashMap; 9 import java.util.List; 10 import java.util.Map; 11 12 import javax.jms.ObjectMessage; 13 import javax.servlet.ServletException; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 17 import org.apache.commons.fileupload.FileItem; 18 import org.codehaus.jackson.map.ObjectMapper; 19 20 import com.mmzs.bigdata.po.User; 21 import com.mmzs.bigdata.service.UserService; 22 import com.mmzs.bigdata.service.UserServiceImpl; 23 import com.thoughtworks.xstream.mapper.Mapper; 24 25 /** 26 * 用户模块控制器 27 * @author Administrator 28 * 29 */ 30 /** 31 * @author Administrator 32 * 33 */ 34 public class UserAction extends BaseAction { 35 36 private UserService userService; 37 38 public UserAction() { 39 userService = new UserServiceImpl(); 40 } 41 /** 42 * 用户登录 43 * @param request 44 * @param response 45 * @throws IOException 46 * @throws ServletException 47 */ 48 public void login(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 49 String userName = request.getParameter("userName"); 50 String passWord = request.getParameter("passWord"); 51 52 User user = userService.getUser(userName, passWord); 53 if (null != user) {//登陆成功 54 request.getSession().setAttribute("loginUser", user); 55 Map<String, Object> args = new HashMap<String, Object>(); 56 args.put("curPage", 1); 57 args.put("count", COUNT); 58 Map<String, Object> resMap = userService.getUserList(args); 59 60 request.setAttribute("curPage", resMap.get("curPage")); 61 request.setAttribute("totalPage", resMap.get("totalPage")); 62 request.setAttribute("userList", resMap.get("userList")); 63 request.getRequestDispatcher("/main.jsp").forward(request, response); 64 return;//如果你是一个比较有良知的人,加一个return;因为加了执行到此处就结束,否则会往下执行自动结束;理论上加与不加效果相同; 65 } else {//登录失败 66 request.setAttribute("loginError", "用户名或密码输入错误"); 67 request.getRequestDispatcher("/login.jsp").forward(request, response); 68 } 69 } 70 71 /** 72 * 列表分页 73 * @param request 74 * @param response 75 * @throws IOException 76 * @throws ServletException 77 */ 78 public void list(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 79 String curPage = request.getParameter("curPage");//curPage得到的是String类型需转化为integer类型 80 String realName = request.getParameter("realName"); 81 realName = new String(realName.getBytes("ISO-8859-1"), "UTF-8");//需要转码中文才能搞定 82 83 Map<String, Object> args = new HashMap<String, Object>(); 84 args.put("curPage", Integer.parseInt(curPage)); 85 args.put("count", COUNT); 86 if (null != realName && !realName.trim().isEmpty()) { 87 args.put("realName", realName); 88 } 89 90 91 Map<String, Object> resMap = userService.getUserList(args); 92 //大公司操作 93 // StringWriter writer = new StringWriter(); 94 // ObjectMapper mapper = new ObjectMapper(); 95 // mapper.writeValue(writer, resMap); 96 // String jsonString = writer.toString(); 97 // response.getWriter().write(jsonString); 98 99 //小公司操作 100 request.setAttribute("curPage", resMap.get("curPage")); 101 request.setAttribute("totalPage", resMap.get("totalPage")); 102 request.setAttribute("userList", resMap.get("userList")); 103 //request.getRequestDispatcher("/main.jsp").forward(request, response); 104 request.getRequestDispatcher("/table.jsp").forward(request, response); 105 } 106 107 /** 108 * 用于处理用户注册 109 * @param request 110 * @param response 111 * @throws ServletException 112 * @throws IOException 113 */ 114 public void register(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 115 //解析带有文件域的表单提交请求 116 Map<String, List<Object>> paramMap = super.parseUpload(request); 117 118 String userName = (String) paramMap.get("userName").get(0); 119 String passWord = (String) paramMap.get("passWord").get(0); 120 String realName = (String) paramMap.get("realName").get(0); 121 String weight = (String) paramMap.get("weight").get(0); 122 String height = (String) paramMap.get("height").get(0); 123 String birthday = (String) paramMap.get("birthday").get(0); 124 125 FileItem photo = (FileItem) paramMap.get("photo").get(0); 126 //获取文件名 127 String fileName = photo.getName(); 128 //图片在工程中的相对路径 129 String photoPath = "/BigData6-1/upload/"+fileName; 130 131 System.out.println(userName+":"+realName+":"+birthday); 132 //利用注册的用户信息创建对象 133 User user = new User(userName, passWord, realName, Double.parseDouble(weight), Integer.parseInt(height), 134 Date.valueOf(birthday), photoPath); 135 //添加用户信息到数据库 136 Integer pk = userService.addUser(user); 137 System.out.println("主键:"+pk); 138 139 140 //将返回Ajax的信息包装成Json字典对象 141 Map <String, Object> jsonMap = new HashMap<String, Object>(); 142 if (null != pk) { 143 jsonMap.put("addTip", "success"); 144 }else { 145 jsonMap.put("addTip", "error"); 146 } 147 148 jsonMap.put("photoPath", photoPath); 149 150 StringWriter writer = new StringWriter(); 151 mapper.writeValue(writer,jsonMap); 152 String json = writer.toString(); 153 154 155 156 //获取文件需要保存的服务端路径 157 String filePath = this.getServletContext().getRealPath("/upload"); 158 //根据文件服务端的绝对路径创建对象 159 File fileFullName = new File(filePath+File.separator+fileName); 160 PrintWriter pw = null; 161 try { 162 //存储文件到服务端指定的路径下 163 photo.write(fileFullName); 164 System.out.println(photoPath); 165 //response.setContentType("text/html;charset=UTF-8");//json格式需要这行代码;xml格式不需要这行代码 166 pw = response.getWriter(); 167 pw.write(json); 168 System.out.println(pw); 169 pw.flush(); 170 171 } catch (Exception e) { 172 e.printStackTrace(); 173 }finally{ 174 if (null != pw) { 175 pw.close(); 176 } 177 } 178 } 179 180 }