目录
朴素版写法
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的服务。
<servlet>
<servlet-name>LoginServlet</servlet-name>
<servlet-class>cn.edu.guet.web.LoginServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>LoginServlet</servlet-name>
<url-pattern>/login</url-pattern>
</servlet-mapping>
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中配置映射
????<servlet> ? ? ? ? <servlet-name>LoginServlet</servlet-name> ? ? ? ? <servlet-class>cn.edu.guet.web.LoginServlet</servlet-class> ? ? </servlet>
? ? <servlet-mapping> ? ? ? ? <servlet-name>LoginServlet</servlet-name> ? ? ? ? <url-pattern>/login</url-pattern> ? ? </servlet-mapping>
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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserMapper">
<insert id="addUser">
INSERT INTO sys_user(id,name,nick_name,password,salt) VALUES(#{id},#{name},#{nick_name},#{password},#{salt})
</insert>
<update id="updateUser">
UPDATE sys_user SET name=#{name},nick_name=#{nick_name},password=#{password},salt=#{salt} WHERE id=#{id}
</update>
<select id="login" resultType="org.example.bean.User">
SELECT id,nick_name,password,salt FROM sys_user WHERE name=#{username} AND password=#{password}
</select>
</mapper>
对比之前的写法,可以发现之前的代码冗长、重复工作多。
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
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.example.mapper.UserMapper">
<insert id="addUser">
INSERT INTO sys_user(id,name,nick_name,password,salt) VALUES(#{id},#{name},#{nick_name},#{password},#{salt})
</insert>
<update id="updateUser">
UPDATE sys_user SET name=#{name},nick_name=#{nick_name},password=#{password},salt=#{salt} WHERE id=#{id}
</update>
<select id="login" resultType="org.example.bean.User">
SELECT id,nick_name,password,salt FROM sys_user WHERE name=#{username} AND password=#{password}
</select>
</mapper>
框架的配置文件在本文都未提及。配置文件只需要编写一次,就可供全局使用。
|