目录
朴素版写法
Controller层
Service层
DAO层
整合SpringMVC
Controller层
整合MyBatis
Mapper层
整合Spring
总结
Controller层
Service层
Mapper层
以简单的登录功能来分析。
朴素版写法
Controller层
1、编写XXXServlet类,用于接收前端某一个指定的请求(如果前端有多个请求,那么需要创建相应数量的Servlet类,来分配处理单一请求),这里就是LoginServlet。
package cn.edu.guet.web;
public class LoginServlet extends HttpServlet {
private UserService us = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
boolean b = us.login(username, password);
//异步操作
if(b){
response.setContentType("application/json;charset=UTF-8");
Result res = new Result("true", username);
Gson gson = new Gson();
String s = gson.toJson(res);
PrintWriter out = response.getWriter();
out.print(s);
out.flush();
out.close();
}else{
response.sendRedirect("login.html");
}
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
2、在web.xml配置该servlet的映射。前端浏览器需要请求服务器的login地址来获得该Servlet的服务。
LoginServlet cn.edu.guet.web.LoginServlet LoginServlet /login
Service层
1、编写UserServiceImpl及接口IUserService。
2、在UserServiceImpl中一般情况是直接调用Dao层的方法,部分涉及复杂业务的操作需要用到事务。
package cn.edu.guet.service.impl;
public class UserServiceImpl implements IUserService {
private IUserDao ud = new UserDaoImpl();
@Override
public boolean login(String username, String password) {
return ud.login(username,password);
}
}
DAO层
1、编写UserDaoImpl及接口IUserDao。
2、在UserDaoImpl中建立数据库连接,并执行相应的SQL语句,将结果依次返回 ==> Service ==>Servlet ==> 浏览器。
package cn.edu.guet.dao.impl;
public class UserDaoImpl implements IUserDao {
String user = "root";
String pass = "root";
String url = "jdbc:mysql://localhost:3306/db01?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rs = null;
@Override
public boolean login(String username, String password) {
boolean b = false;
String sql = "SELECt password,salt FROM sys_user WHERe name=?";
try {
Class.forName("com.mysql.cj.jdbc.Driver");
conn = DriverManager.getConnection(url,user,pass);
pstm = conn.prepareStatement(sql);
pstm.setString(1,username);
rs = pstm.executeQuery();
if(rs.next()){
String enc = rs.getString("password");
String salt = rs.getString("salt");
PasswordEncoder md5 = new PasswordEncoder(salt, "MD5");
b = md5.matches(enc, password);
if(b) System.out.println("登录成功!");
else System.out.println("登录失败!");
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
try {
rs.close();
pstm.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return b;
}
}
整合SpringMVC
SpringMVC主要是对Controller层进行优化,最主要的作用:
1、更为简便的请求映射配置。省去了在web.xml中大量配置映射的过程。
2、使一个类中可以处理多个请求。根据这一特点,我们可以按某种标准来将前端的所有请求划分成若干个类,每个类中的请求都有相似的特征。一般的划分依据就是按照要操作的目标数据表来划分,即如果3个请求都是要操作user表,那么就可以将这3个请求封装在一个类中。
3、封装了获取请求参数,以及对浏览器响应数据的操作。这一点我认为是最重要的。
Controller层1、省去了以前在web.xml中的servlet映射配置,取而代之使用注解@RequestMapping("/login")的方式来进行映射配置。写法更为方便。
2、类名从LoginServlet变为UserController,说明现在的类不只是能够处理login这一个请求,其他涉及数据库user表操作的请求都能写在该类中。
3、请求参数直接写在方法形参中,SpringMVC会自动帮注入。返回的数据SpringMVC会自动帮转换成JSON数据返回给浏览器。
package cn.edu.guet.controller;
@Controller
public class UserController {
IUserService userService = new UserServiceImpl();
@RequestMapping("/login")
public User login(String username, String password) {
User user = userService.login(username, password);
return user;
}
@RequestMapping("/updateUser")
public int updateUser(User user) {
return userService.updateUser(user);
}
@RequestMapping("/addUser")
public int addUser(User user) {
return userService.addUser(user);
}
}
对比一下之前的做法,就能感受到SpringMVC框架的强大!
1、web.xml中配置映射
LoginServlet
cn.edu.guet.web.LoginServlet
LoginServlet
/login
2、创建LoginServlet接收单一请求
public class LoginServlet extends HttpServlet {
private UserService us = new UserServiceImpl();
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
String username = request.getParameter("username");
String password = request.getParameter("password");
boolean b = us.login(username, password);//异步操作
if(b){
response.setContentType("application/json;charset=UTF-8");Result res = new Result("true", username);
Gson gson = new Gson();
String s = gson.toJson(res);PrintWriter out = response.getWriter();
out.print(s);
out.flush();
out.close();
}else{
response.sendRedirect("login.html");
}
}@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
doGet(request,response);
}
}
Service层和Dao层不在SpringMVC的管辖范围内,所以与朴素版的代码相同。
整合MyBatis
MyBatis主要是对Dao层进行优化,并将其改名为Mapper。
Mapper层
1、UserMapper.java
package org.example.mapper;
public interface UserMapper {
User login(@Param("username") String username,@Param("password") String password);
int addUser(User user);
int updateUser(User user);
}
2、UserMapper.xml
INSERT INTO sys_user(id,name,nick_name,password,salt) VALUES(#{id},#{name},#{nick_name},#{password},#{salt}) UPDATE sys_user SET name=#{name},nick_name=#{nick_name},password=#{password},salt=#{salt} WHERe id=#{id}
对比之前的写法,可以发现之前的代码冗长、重复工作多。
package cn.edu.guet.dao.impl;
public class UserDaoImpl implements IUserDao {
String user = "root";
String pass = "root";
String url = "jdbc:mysql://localhost:3306/db01?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true";
Connection conn = null;
PreparedStatement pstm = null;
ResultSet rs = null;@Override
public boolean login(String username, String password) {
boolean b = false;String sql = "SELECT password,salt FROM sys_user WHERe name=?";
try {
Class.forName("com.mysql.cj.jdbc.Driver");conn = DriverManager.getConnection(url,user,pass);
pstm = conn.prepareStatement(sql);
pstm.setString(1,username);
rs = pstm.executeQuery();
if(rs.next()){
String enc = rs.getString("password");
String salt = rs.getString("salt");PasswordEncoder md5 = new PasswordEncoder(salt, "MD5");
b = md5.matches(enc, password);
if(b) System.out.println("登录成功!");
else System.out.println("登录失败!");
}
} catch (SQLException | ClassNotFoundException e) {
e.printStackTrace();
}finally {
try {
rs.close();
pstm.close();
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return b;
}
}
整合Spring
Spring框架主要是提供一个IOC容器,该容器中包含若干对象,这些对象都是单例设计模式。我们可以将项目中符合单例模式思想的类放到IOC容器中,以便Spring容器自动注入。
Spring的主要规范就是不使用new关键字来创建对象,当然并不是使用Spring后所有对象都不能用new创建,只局限于那些符合单例模式的类,例如接口实现类、工具类都应配置在Spring容器中。
总结
整合三个框架后的项目:
Controller层package cn.edu.guet.controller;
@Controller
public class LoginController {
@AutoWired
IUserService userService;
@RequestMapping("/login")
public User login(String username, String password) {
User user = userService.login(username, password);
return user;
}
@RequestMapping("/addUser")
public int addUser(User user){
return userService.addUser(user);
}
}
Service层
package cn.edu.guet.service.impl;
public class UserServiceImpl implements IUserService {
@Autowired
IUserDao ud;
@Override
public User login(String username, String password) {
return ud.login(username, password);
}
@Override
public int addUser(User user) {
return ud.addUser(user);
}
@Override
public int updateUser(User user) {
return ud.updateUser(user);
}
}
Mapper层
1、UserMapper.java
package org.example.mapper;
public interface UserMapper {
User login(@Param("username") String username,@Param("password") String password);
int addUser(User user);
int updateUser(User user);
}
2、UserMapper.xml
INSERT INTO sys_user(id,name,nick_name,password,salt) VALUES(#{id},#{name},#{nick_name},#{password},#{salt}) UPDATE sys_user SET name=#{name},nick_name=#{nick_name},password=#{password},salt=#{salt} WHERe id=#{id}
框架的配置文件在本文都未提及。配置文件只需要编写一次,就可供全局使用。



