首先数据库建表:
项目如何搭建?
我使用的是maven,导入相应的jar包,和依赖
mysql mysql-connector-java 8.0.28 junit junit 4.13.2 javax.servlet.jsp javax.servlet.jsp-api 2.3.3 com.guicedee.services javax.servlet-api 62 javax.servlet.jsp.jstl javax.servlet.jsp.jstl-api 1.2.2 junit junit 4.13.2 taglibs standard 1.1.2 com.alibaba fastjson 1.2.79
搭建项目准备工作
- 搭建一个maven web项目配置Smart tomcat测试项目是否能跑起来导入项目中需要的jar包,jsp,Servlet,MySQL驱动jstl,standard,junit等构建项目包结构
6.编写实体类、ROM映射:表–类映射
7.编写基础公共类数据库配置文件
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306/smbms?useSSL=true&useUnicode=true&characterEncoding=utf-8 username=root password=password2.编写数据库公共类
package com.happy.dao;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;
public class baseDao {
static{//静态代码块,在类加载的时候执行
init();
}
private static String driver;
private static String url;
private static String username;
private static String password;
//初始化连接参数,从配置文件里获得
public static void init(){
Properties properties=new Properties();
String configFile = "db.properties";
InputStream is=baseDao.class.getClassLoader().getResourceAsStream(configFile);
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
driver=properties.getProperty("driver");
url=properties.getProperty("url");
username=properties.getProperty("username");
password=properties.getProperty("password");
}
//获取数据库连接
//static
public static Connection getConnection(){
Connection connection = null;
try {
Class.forName(driver);
connection = DriverManager.getConnection(url, username, password);
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return connection;
}
//static
//编写公共查询方法
public static ResultSet execute(Connection connection,PreparedStatement preparedStatement,ResultSet resultSet,String sql,Object[] params) throws Exception{
//预编译的sql不需要传参,直接执行即可
preparedStatement = connection.prepareStatement(sql);
for(int i = 0; i < params.length; i++){
//setObject占位符从1开始,但是我们的数组是从0开始
preparedStatement.setObject(i+1, params[i]);
}
resultSet = preparedStatement.executeQuery();//新添加sql
return resultSet;
}
//static
//编写增删改公共方法
public static int execute(Connection connection,PreparedStatement preparedStatement,String sql,Object[] params) throws Exception{
int updateRows = 0;
preparedStatement = connection.prepareStatement(sql);
for(int i = 0; i < params.length; i++){
preparedStatement.setObject(i+1, params[i]);
}
updateRows = preparedStatement.executeUpdate();
return updateRows;
}
//static
public static boolean closeResource(Connection connection,PreparedStatement preparedStatement, ResultSet resultSet){
boolean flag = true;
if(resultSet != null){
try {
resultSet.close();
resultSet = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(preparedStatement != null){
try {
preparedStatement.close();
preparedStatement = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
if(connection != null){
try {
connection.close();
connection = null;//GC回收
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
flag = false;
}
}
return flag;
}
}
3.编写字符编码过滤器
servletRequest.setCharacterEncoding("utf-8");
servletResponse.setCharacterEncoding("utf-8");
filterChain.doFilter(servletRequest,servletResponse);
8.导入静态资源
登录功能实现
1.编写前端页面
2.设置首页
1.设置欢迎首页
login.jsp
根据三层架构我们需要先从dao层写,用户登录的接口(面向接口的编程)
三层架构:dao---->service---->servlet
//得到要登录的用户 public User getLoginUser(Connection connection, String userCode) throws Exception;
4.编写dao层接口的实现类
public class UserDaoImpl implements UserDao{
//持久层只做查询数据库的内容
public User getLoginUser(Connection connection, String userCode) throws Exception{
//准备三个对象
PreparedStatement pstm = null;
ResultSet rs = null;
User user = null;
//判断是否连接成功
if(null != connection){
String sql = "select * from smbms_user where userCode=?";
Object[] params = {userCode};
rs = baseDao.execute(connection, pstm, rs, sql, params);
if(rs.next()){
user = new User();
user.setId(rs.getInt("id"));
user.setUserCode(rs.getString("userCode"));
user.setUserName(rs.getString("userName"));
user.setUserPassword(rs.getString("userPassword"));
user.setGender(rs.getInt("gender"));
user.setBirthday(rs.getDate("birthday"));
user.setPhone(rs.getString("phone"));
user.setAddress(rs.getString("address"));
user.setUserRole(rs.getInt("userRole"));
user.setCreatedBy(rs.getInt("createdBy"));
user.setCreationDate(rs.getTimestamp("creationDate"));
user.setModifyBy(rs.getInt("modifyBy"));
user.setModifyDate(rs.getTimestamp("modifyDate"));
}
baseDao.closeResource(null, pstm, rs);
}
return user;
}
}
5.编写业务层接口
//用户登录 public User login(String userCode,String password);
6.业务层实现接口类
public class UserServiceImpl implements UserService{
//业务层都会调用dao层,所以我们要引入dao层
//只处理对应业务
private UserDao userDao;
public UserServiceImpl(){
userDao = new UserDaoImpl();
}
public User login(String userCode, String password) {
Connection connection = null;
//通过业务层调用相应的具体数据数据库操作
User user =null;
try {
connection = baseDao.getConnection();
user = userDao.getLoginUser(connection, userCode);
} catch (Exception e) {
e.printStackTrace();
}finally {
baseDao.closeResource(connection,null,null);
}
return user;
}
//测试代码
}
7.编写Servlet
public class LoginServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
System.out.println("LoginServlet--->start...");
//获取用户名和密码
String userCode = req.getParameter("userCode");
String userPassword = req.getParameter("userPassword");
//和数据库中的密码进行对比,调用业务层
UserService userService = new UserServiceImpl();
User user = userService.login(userCode, userPassword);//这里已经把登陆的人给查出来了
if (user!=null){
//放入session
req.getSession().setAttribute(Constants.USER_SESSION,user);
resp.sendRedirect("jsp/frame.jsp");
}else {//查无此人,无法登录
//转发回登陆界面,顺带提示他,用户名或者密码不正确
req.setAttribute("error","用户名或者密码不正确");
req.getRequestDispatcher("login.jsp").forward(req,resp);
}
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
8.注册Servlet(一定要记得)
LoginServlet com.happy.servlet.user.LoginServlet LoginServlet /login.do
9.测试访问,保证以上功能可以成功
登录功能优化
注销功能:思路---->移除session,返回登录页面
public class LogoutServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//移除用户的session
req.getSession().removeAttribute(Constants.USER_SESSION);
resp.sendRedirect(req.getContextPath()+"/login.jsp");//返回登录页面
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
}
**注册xml
LogoutServlet com.happy.servlet.user.LogoutServlet LogoutServlet /jsp/logout.do
登录拦截优化
编写一个过滤器,并注册
public class SysFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest rep, ServletResponse resp, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request = (HttpServletRequest) rep; //为了获得session
HttpServletResponse response = (HttpServletResponse) resp; //为了重定向
//过滤器从session中获取用户
User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
if (user==null){ //已经被移除或者注销了,或者未登录
response.sendRedirect("/smbms/error.jsp");
}else {
filterChain.doFilter(rep,resp);
}
}
@Override
public void destroy() {
}
}
注册xml
SysFilter com.happy.filter.SysFilter SysFilter /jsp/*
测试,登录,注册,权限,都要保证可以运行
密码修改
1.导入前端素材
2.写项目,建议从底层向上写
3.UserDao接口
//修改当前用户密码 public int updatePwd(Connection connection, int id, String password) throws Exception;
4.UserDao接口实现类
//修改当前用户密码
@Override
public int updatePwd(Connection connection, int id, String password) throws Exception {
System.out.println("Uservlet: "+password);
PreparedStatement pstm = null;
int execute = 0;
if (connection!=null){
String sql ="update smbms_user set userPassword = ? where id = ?";
Object params[] = {password,id};
execute = baseDao.execute(connection,pstm,sql,params);
baseDao.closeResource(null,pstm,null);//各司其职,所以有两个为null
}
return execute;
}
5.UserServece层
//根据用户的id修改密码 public boolean updatePwd(int id,String pwd);
6.编写UserService实现类
//根据用户的id修改密码
@Override
public boolean updatePwd(int id, String pwd) {
System.out.println("Uservlet: "+pwd);
Connection connection = null;
boolean flag = false;
//修改密码
try {
connection = baseDao.getConnection();
if (userDao.updatePwd(connection,id,pwd)>0){
flag = true;
}
} catch (Exception e) {
e.printStackTrace();
}finally {
baseDao.closeResource(connection,null,null);
}
return flag;
}
7.servlet记得实现复用,要提取出方法!在 dao层 和 service层 自己写映射类和实现类,下面是 servlet层 的主体
public class UserServlet extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String method = req.getParameter("method");
if (method != "savepwd" && method != null) {
this.updatePwd(req, resp);
}
//实现复用
// 想添加新的增删改查,直接用if(method != "savepwd" && method != null);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doGet(req, resp);
}
public void updatePwd(HttpServletRequest req, HttpServletResponse resp) {
// 通过session获得用户id
Object o = req.getSession().getAttribute(Constants.USER_SESSION);
String newpassword = req.getParameter("newpassword");
boolean flag = false;
if (o != null && newpassword != null) {
UserService userService = new UserServiceImpl();
try {
flag = userService.updatePwd(((User) o).getId(), newpassword);
} catch (SQLException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
if (flag) {
req.setAttribute("message", "密码修改成功,请退出,使用新密码登录");
// 密码修改成功,移除session(移除后不能再次修改密码,建议不移除)
req.getSession().removeAttribute(Constants.USER_SESSION);
} else {
// 密码修改失败
req.setAttribute("message", "密码修改失败");
}
} else {
// 密码修改有问题
req.setAttribute("message", "新密码有问题");
}
try {
req.getRequestDispatcher("/jsp/pwdmodify.jsp").forward(req, resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
注册xml
UserServlet com.happy.servlet.user.UserServlet UserServlet /jsp/user.do
8.测试,修改
优化密码修改使用Ajax
1.导入阿里巴巴的fastjson
com.alibaba fastjson 1.2.79
验证旧密码
public void pwdmodify(HttpServletRequest req,HttpServletResponse resp){
Object o = req.getSession().getAttribute(Constants.USER_SESSION);
String oldpassword = req.getParameter("oldpassword");
Map resultMap = new HashMap();
if (o==null){ //session过期了,过期了
resultMap.put("result","sessionerror");
}else if (StringUtils.isNullOrEmpty(oldpassword)){
resultMap.put("result","error");
}else {
String userPassword = ((User) o).getUserPassword();
if (oldpassword.equals(userPassword)){
resultMap.put("result","true");
}else {
resultMap.put("result","false");
}
}
try {
resp.setContentType("application/json");
PrintWriter writer = resp.getWriter();
writer.write(JSONArray.toJSONString(resultMap));
writer.flush();
writer.close();
} catch (IOException e) {
e.printStackTrace();
}
}
测试!
用户管理实现
1.导入分页的工具类-PageSupport
2.用户列表页面导入userlist.jsp
1.获取用户数量
1.UserDaoImpl(接口)
//根据用户名或者角色查询用户总数 public int getUserCount(Connection connection, String username, int userRole) throws Exception;
2.UserDaoImpl(实现类)
//根据用户名或者角色查询用户总数
@Override
public int getUserCount(Connection connection, String userName, int userRole) throws Exception {
PreparedStatement pstm = null;
ResultSet rs = null;
int count = 0;
if (connection!=null){
StringBuffer sql = new StringBuffer();
sql.append("select count(1) as count from smbms_user u,smbms_role r where u.userRole = r.id");
ArrayList
3.UserService(接口)
//查询记录数 public int getUserCount(String username,int userRole);
4.UserServiceImpl实现类
//查询记录数
@Override
public int getUserCount(String username, int userRole) {
Connection connection = null;
int count = 0;
try {
connection = baseDao.getConnection();
count = userDao.getUserCount(connection, username, userRole);
} catch (Exception e) {
e.printStackTrace();
}finally {
baseDao.closeResource(connection,null,null);
}
return count;
}
2.获取用户列表
1.UserDao(接口)
//通过条件查询-userList public ListgetUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception;
2.UserDaoImpl(实现类)
//通过条件查询-userList @Override public ListgetUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception { PreparedStatement pstm = null; ResultSet rs = null; List userList = new ArrayList (); if(connection != null){ StringBuffer sql = new StringBuffer(); //需要拼接就用StringBuffer sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id"); List list = new ArrayList (); if(!StringUtils.isNullOrEmpty(userName)){ sql.append(" and u.userName like ?"); list.add("%"+userName+"%"); } if(userRole > 0){ sql.append(" and u.userRole = ?"); list.add(userRole); } //当前页(当前页-1)*页面大小 //0,5 1,0 01234 //5,5 5,0 56789 //10,5 10,0 10~ sql.append(" order by creationDate DESC limit ?,?"); currentPageNo = (currentPageNo-1)*pageSize; list.add(currentPageNo); list.add(pageSize); Object[] params = list.toArray(); System.out.println("sql ----> " + sql.toString()); rs = baseDao.execute(connection, pstm, rs, sql.toString(), params); while(rs.next()){ User _user = new User(); _user.setId(rs.getInt("id")); _user.setUserCode(rs.getString("userCode")); _user.setUserName(rs.getString("userName")); _user.setGender(rs.getInt("gender")); _user.setBirthday(rs.getDate("birthday")); _user.setPhone(rs.getString("phone")); _user.setUserRole(rs.getInt("userRole")); _user.setUserRoleName(rs.getString("userRoleName")); userList.add(_user); } baseDao.closeResource(null, pstm, rs); } return userList; }
3.UserService(接口)
//根据条件查询用户列表 public ListgetUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);
4.UserServiceImpl(实现类)
//根据条件查询用户列表 @Override public ListgetUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) { // TODO Auto-generated method stub Connection connection = null; List userList = null; System.out.println("queryUserName ---- > " + queryUserName); System.out.println("queryUserRole ---- > " + queryUserRole); System.out.println("currentPageNo ---- > " + currentPageNo); System.out.println("pageSize ---- > " + pageSize); try { connection = baseDao.getConnection(); userList = userDao.getUserList(connection, queryUserName,queryUserRole,currentPageNo,pageSize); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ baseDao.closeResource(connection, null, null); } return userList; }
3、获取角色操作
为了我们的职责统一,我们可以把角色的操作单独放在一个包中,和pojo类对应
1、RoleDao(接口)
//获取角色列表 public ListgetRoleList(Connection connection)throws Exception;
2、RoleDaoIpml(实现类)
public class RoleDaoImpl implements RoleDao {
@Override
public List getRoleList(Connection connection) throws Exception {
PreparedStatement pstm = null;
ResultSet rs = null;
List roleList = new ArrayList();
if (connection != null) {
String sql = "select * from smbms_role";
Object[] params = {};
rs = baseDao.execute(connection, pstm, rs, sql, params);
while (rs.next()) {
Role _role = new Role();
_role.setId(rs.getInt("id"));
_role.setRoleCode(rs.getString("roleCode"));
_role.setRoleName(rs.getString("roleName"));
roleList.add(_role);
}
baseDao.closeResource(null, pstm, rs);
}
return roleList;
}
}
3.RoleService(接口)
//角色列表查询 public ListgetRoleList();
4、RoleServiceIpml(实现类)
public class RoleServiceImpl implements RoleService{
//引入Dao层
private RoleDao roleDao;
public RoleServiceImpl(){
roleDao = new RoleDaoImpl();
}
public List getRoleList() {
Connection connection = null;
List roleList = null;
try {
connection = baseDao.getConnection();
roleList = roleDao.getRoleList(connection);
} catch (Exception e) {
e.printStackTrace();
}finally {
baseDao.closeResource(connection,null,null);
}
return roleList;
}
//测试类
@Test
public void Test(){
RoleServiceImpl roleService = new RoleServiceImpl();
List roleList = roleService.getRoleList();
for (Role role : roleList){
System.out.println(role.getRoleName());
}
}
}
4.用户显示的servlet
1.获取用户前端的数据(查询)
2.判断请求是否需要执行,看参数的值判断
3.为了实现分页,需要计算出当前页面和总页面,页面大小
4.用户列表展示
5.返回前端
public void query(HttpServletRequest req,HttpServletResponse resp){
//查询用户列表
//从前端获取数据;
String queryUserName = req.getParameter("queryname");
String temp = req.getParameter("queryUserRole");
String pageIndex = req.getParameter("pageIndex");
int queryUserRole = 0;//防止为空,所以定义为0;
//获取用户列表
UserServiceImpl userService = new UserServiceImpl();
List userList = null;
//第一次请求一定是走第一页,页面大小固定的
int pageSize = 5;
int currentPageNo = 1;
if (queryUserName==null){
queryUserName="";
}
if (temp!=null && temp.equals("")){
queryUserRole = Integer.parseInt(temp);//给查询赋值!0 1 2 3
}
if (pageIndex!=null){
currentPageNo = Integer.parseInt(pageIndex);
}
//获取用户的总数(分页:上一页,下一页的情况)
int totalCount = userService.getUserCount(queryUserName,queryUserRole);
//总页数支持
PageSupport pageSupport = new PageSupport();
pageSupport.setCurrentPageNo(currentPageNo);
pageSupport.setPageSize(pageSize);
pageSupport.setTotalCount(totalCount);
int totalPageCount = ((int)(totalCount/pageSize))+1;
//控制首页和尾页
//如果页面要小于1了,就显示第一页的东西
if (currentPageNo<1){
currentPageNo=1;
}else if (currentPageNo>totalPageCount){//当前页大于总页数
currentPageNo=totalPageCount;
}
//用户列表展示
userList = userService.getUserList(queryUserName,queryUserRole,currentPageNo,pageSize);
req.setAttribute("userList",userList);
RoleServiceImpl roleService = new RoleServiceImpl();
List roleList = roleService.getRoleList();
req.setAttribute("roleList",roleList);
req.setAttribute("totalCount",totalCount);
req.setAttribute("currentPageNo",currentPageNo);
req.setAttribute("totalPageCount",totalPageCount);
req.setAttribute("queryUserName",queryUserName);
req.setAttribute("queryUserRole",queryUserRole);
//返回前端
try {
req.getRequestDispatcher("userlist.jsp").forward(req,resp);
} catch (ServletException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
这个项目到这差不多就完了,剩下的代码都是和上面一样,增删改查,修改一行代码的问题,还是根据三层架构的思想去编写代码,从后往前!



