smbms
数据库
项目如何搭建?
考虑是否使用Maven?使用maven需要导依赖,不使用maven需要导jar包。
项目搭建准备工作
-
搭建一个maven web项目。
-
配置tomcat。
-
测试项目是否能够跑起来。
-
导入项目中会遇到得jar包
- jsp,servlet,mysql驱动,jstl,stand。。。
- 创建项目结构。
-
编写实体类。
ORM映射:表-类映射
-
编写基础公共类
- 数据库配置文件
driver=com.mysql.jdbc.Driver url=jdbc:mysql://localhost:3306?useUnicode=true&characterEncoding=utf-8 username=root password=123456
- 编写数据库公共类
package com.jyw.dao; import java.io.IOException; import java.io.InputStream; import java.sql.*; import java.util.Properties; //操作数据库的公共类 public class BaseDao { private static String dirver; private static String url; private static String username; private static String password; //静态代码块,类加载的时候就初始化 static { Properties properties = new Properties(); //通过类加载器读取对应的资源 InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties"); try { properties.load(is); } catch (IOException e) { e.printStackTrace(); } dirver = properties.getProperty("driver"); url = properties.getProperty("url"); username = properties.getProperty("username"); password = properties.getProperty("password"); } //获取数据库的连接 public static Connection getConnection() { Connection connection = null; try { Class.forName(dirver); connection = DriverManager.getConnection(url, username, password); } catch (Exception e) { e.printStackTrace(); } return connection; } //编写查询公共方法 public static ResultSet execute(Connection connection, String sql, Object[] params, ResultSet resultSet, PreparedStatement statement) throws SQLException { //预编译sql,在后面直接执行就可以了。 statement = connection.prepareStatement(sql); for (int i = 0; i < params.length; i++) { statement.setObject(i + 1, params[i]); } resultSet = statement.executeQuery(); return resultSet; } //编写增删改公共方法 public static int execute(Connection connection, String sql, Object[] params, int affectRows, PreparedStatement statement) throws SQLException { statement = connection.prepareStatement(sql); for (int i = 0; i < params.length; i++) { statement.setObject(i + 1, params[i]); } affectRows = statement.executeUpdate(); return affectRows; } //释放资源 public static boolean closeResource(Connection connection, PreparedStatement statement, ResultSet resultSet) { boolean flag = true; if (resultSet!=null){ try { resultSet.close(); //GC回收 resultSet = null; } catch (SQLException throwables) { throwables.printStackTrace(); flag=false; } } if (statement!=null) { try { statement.close(); //GC回收 statement = null; } catch (SQLException throwables) { throwables.printStackTrace(); flag = false; } } if (connection!=null) { try { connection.close(); //GC回收 connection = null; } catch (SQLException throwables) { throwables.printStackTrace(); flag = false; } } return flag; } }
- 编写字符编码过滤器
-
导入静态资源
登录功能实现
- 编写前端页面
- 设置首页
<!--设置欢迎界面-->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
- 编写dao层登录用户登录的接口
public interface UserDao {
//得到要登录的用户
public User getLoginUser(Connection connection,String userCode);
}
- 编写dao接口的实现类
package com.jyw.dao.user;
import com.jyw.dao.BaseDao;
import com.jyw.pojo.User;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class UserDaoImpl implements UserDao{
public User getLoginUser(Connection connection, String userCode) {
PreparedStatement patm=null;
ResultSet rs=null;
User user=null;
if (connection!=null)
{
String sql="select * from user where userCode=? ";
Object[] params={userCode};
try {
rs=BaseDao.execute(connection,sql,params,rs,patm);
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(connection,patm,rs);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
return user;
}
}
- 业务层接口
//用户登录
public interface UserService {
public User login(String userCode,String password);
}
- 业务层实现类
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;
connection= BaseDao.getConnection();
//通过业务层调用对应的具体的数据库操作
User loginUser = userDao.getLoginUser(connection, userCode);
BaseDao.closeResource(connection,null,null);
return loginUser;
}
// @Test
// public void Test(){
// UserServiceImpl service = new UserServiceImpl();
// User admin = service.login("admin", "123456");
// System.out.println(admin.getUserName());
// }
}
- 编写servlet
public class LoginServlet extends HttpServlet {
//Servlet是控制层,调用业务层代码
@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");
//和数据库中的密码进行对比,调用业务层
UserServiceImpl 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);
}
}
-
注册servlet
<servlet> <servlet-name>LoginServlet</servlet-name> <servlet-class>com.jyw.servlet.user.LoginServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>LoginServlet</servlet-name> <url-pattern>/login.do</url-pattern> </servlet-mapping>
-
测试访问,确保以上功能成功
总结:servlet控制层,负责接收用户参数,调用业务层,转发视图。
service业务层负责处理对应业务
Dao持久层负责查询数据库
jsp前端负责展示界面
登陆功能优化
注销功能:
思路:移除Session,返回登陆页面
public class LoginOut extends HttpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//移除用户的Constants.USER_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
<servlet>
<servlet-name>LoginOut</servlet-name>
<servlet-class>com.jyw.servlet.user.LoginOut</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginOut</servlet-name>
<url-pattern>/jsp/logout.do</url-pattern>
</servlet-mapping>
登陆拦截优化
编写一个过滤器,并注册
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest request=(HttpServletRequest)servletRequest;
HttpServletResponse response=(HttpServletResponse)servletResponse;
//从Session中获取用户
User user = (User) request.getSession().getAttribute(Constants.USER_SESSION);
if (user==null)//没有登陆就回去登陆
{
response.sendRedirect(request.getContextPath()+"/error.jsp");
}else
{
//继续走
filterChain.doFilter(servletRequest,servletResponse);
}
}
<!--用户登陆过滤器-->
<filter>
<filter-name>SysFilter</filter-name>
<filter-class>com.jyw.filter.SysFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>SysFilter</filter-name>
<url-pattern>/jsp/*</url-pattern>
</filter-mapping>
测试,登录,注销,权限,都要保证OK!
密码修改
- 导入前端素材。
<li><a href="${pageContext.request.contextPath }/jsp/pwdmodify.jsp">密码修改</a></li>
- 写项目,建议从底层网上写。
- 写UserDao接口
//修改当前用户密码
public int updatePwd(Connection connection,int id,int password) throws SQLException;
- 写UserDao接口实现类
public int updatePwd(Connection connection, int id, int password) throws SQLException {
int execute = 0;
if (connection != null) {
PreparedStatement pstm = null;
String sql = "update user set userPassword=? where id=? ";
Object params[] = {password, id};
execute = BaseDao.execute(connection, sql, params, pstm);
BaseDao.closeResource(connection, pstm, null);
}
return execute;
}
-
UserService
//修改用户密码 public boolean updatePwd(int id,int pwd) throws SQLException;
-
UserService实现类
public boolean updatePwd(int id, int pwd) {
Connection connection =null;
boolean flag=false;
int affectRows=0;
//修改密码
try {
connection=BaseDao.getConnection();
affectRows=userDao.updatePwd(connection,id,pwd);
if (affectRows>0) {
flag=true;
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
BaseDao.closeResource(connection,null,null);
}
return flag;
}
-
注册servlet
<servlet> <servlet-name>UserServlet</servlet-name> <servlet-class>com.jyw.servlet.user.UserServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>UserServlet</servlet-name> <url-pattern>/jsp/user.do</url-pattern> </servlet-mapping>
-
记得实现复用,需要提取出方法
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOException {
String method = req.getParameter("method");
if (method.equals("savepwd")&&method!=null)
{
//修改密码
this.updatePwd(req, resp);
}
}
//修改密码
public void updatePwd(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
//从Session里面拿ID
Object obj = req.getSession().getAttribute(Constants.USER_SESSION);
String oldpassword = req.getParameter("oldpassword");//旧密码
String newpassword = req.getParameter("newpassword");//新密码
String rnewpassword = req.getParameter("rnewpassword");//确认密码
if (obj != null && (!StringUtils.isNullOrEmpty(newpassword))) {
UserService userService = new UserServiceImpl();
boolean flag = userService.updatePwd(((User) obj).getId(), newpassword);
if (flag) {
req.setAttribute("message", "密码修改成功。请退出,使用新密码登陆。");
//密码修改成功,移除当前Session
req.getSession().removeAttribute(Constants.USER_SESSION);
} else {//密码修改失败
req.setAttribute("message", "密码修改失败。");
}
} else {
req.setAttribute("message", "新密码设置错误。");
}
//转发
req.getRequestDispatcher("pwdmodify.jsp").forward(req, resp);
}
- 测试
优化密码修改,使用Ajax
- 阿里巴巴的Fastjson
<!-- https://mvnrepository.com/artifact/com.alibaba/fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.62</version>
</dependency>
-
//验证旧密码,session中有用户的密码 public void pwdModify(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //从Session里面拿ID Object obj = req.getSession().getAttribute(Constants.USER_SESSION); String oldpassword = req.getParameter("oldpassword");//旧密码 //万能的Map:结果集 Map<String, String> result = new HashMap<String, String>(); if (obj == null) {//Session过期了,失效了 result.put("result", "sessionerror"); } else if (StringUtils.isNullOrEmpty(oldpassword)) { //输入与的密码为空 result.put("result", "error"); } else { if (((User) obj).getUserPassword().equals(oldpassword)) { result.put("result", "true"); } else { result.put("result", "false"); } } resp.setContentType("application/json"); PrintWriter writer = resp.getWriter(); //JSONArray是阿里的JSON工具类,转换格式 writer.write(JSONArray.toJSONString(result)); writer.flush(); writer.close(); }
-
测试
用户管理实现
思路:
1.导入分页工具类
2.用户列表页面导入
userlist.jsp
1、获取用户数量
-
UserDao
//查询用户总数 public int getUserCount(Connection connection,String username,int userRows) throws SQLException;
-
UserDaoImpl
//根据用户名或者角色,获取用户总数 public int getUserCount(Connection connection, String username, int userRow) throws SQLException { PreparedStatement pstm = null; ResultSet rs = null; int count=0; if (connection != null) { StringBuffer sql = new StringBuffer(); sql.append("select count(1) as count " + "from user u left join role r on u.userRole=r.id where 1=1 "); ArrayList<Object> list = new ArrayList<Object>();//存放我们的参数 if (!StringUtils.isNullOrEmpty(username)) { sql.append(" and u.userName like ? "); list.add("%" + username + "%");//index:0 } if (userRow > 0) { sql.append(" and u.userRole = ?"); list.add(userRow);//index:0 } //怎么把list转换为数组 Object[] params = list.toArray(); System.out.println("UserDaoImpl->getUserCount:" + sql.toString());//输出最后完整的sql语句 rs = BaseDao.execute(connection, sql.toString(), params, rs, pstm); if (rs.next()) { count = rs.getInt("count");//从结果集中获取最终的数量 } BaseDao.closeResource(null,pstm,rs); } return count; }
-
UserService
//查询记录数 public int getUserCount(String username,int userRole);
-
UserServiceImpl
//查询记录数
public int getUserCount(String username, int userRole) {
Connection connection = null;
int count = 0;
try {
connection = BaseDao.getConnection();
count=userDao.getUserCount(connection, username, userRole);
} catch (SQLException throwables) {
throwables.printStackTrace();
}
finally {
BaseDao.closeResource(connection,null,null);
}
return count;
}
2、获取用户列表
-
UserDao
//通过查询条件查询userlist public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize)throws Exception;
-
UserDaoImpl
public List<User> getUserList(Connection connection, String userName, int userRole, int currentPageNo, int pageSize) throws Exception { // TODO Auto-generated method stub PreparedStatement pstm = null; ResultSet rs = null; List<User> userList = new ArrayList<User>(); if(connection != null){ StringBuffer sql = new StringBuffer(); sql.append("select u.*,r.roleName as userRoleName from smbms_user u,smbms_role r where u.userRole = r.id"); List<Object> list = new ArrayList<Object>(); if(!StringUtils.isNullOrEmpty(userName)){ sql.append(" and u.userName like ?"); list.add("%"+userName+"%"); } if(userRole > 0){ sql.append(" and u.userRole = ?"); list.add(userRole); } 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, sql.toString(), params,rs,pstm ); 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; }
-
UserService
//获取用户列表 public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize);
-
UserServiceImpl
public List<User> getUserList(String queryUserName, int queryUserRole, int currentPageNo, int pageSize) {
// TODO Auto-generated method stub
Connection connection = null;
List<User> 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类对应。
4、用户显示的Servlet
1.获取用户前端的数据(查询)。
2.判断请求是否需要执行。看参数的值判断。
3.为了实现分页,需要计算出当前页面和总页面,页面大小。
4.用户列表展示。
小黄鸭调试法:对着小黄鸭解释代码。