天天看點

SSM——使用者資訊管理系統

文章目錄

    • SSM——使用者資訊管理系統
        • 1 核心功能
        • 2 整體架構:
        • 3 資料庫表設計
        • 4 建立實體類(POJO)
        • 5 UserMapper接口
        • 6 編寫UserMapper.xml
        • 7 配置SpringBoot (application.properties)
        • 8 service層設計
        • 9 Controller層設計
        • 10 使用者登入狀态攔截——攔截器

SSM——使用者資訊管理系統

源碼連結:使用者資訊管理系統

1 核心功能

  1. 登入、注冊
  2. 添加使用者資訊
  3. 删除某一個使用者資訊
  4. 删除選中的使用者資訊
  5. 分頁查詢所有使用者資訊
  6. 模糊查詢使用者資訊
  7. 更新使用者資訊

2 整體架構:

項目整體基于HTTP協定,前端使用 HTML+CSS+JS 建構頁面整體布局,後端采用分層結構,分為Controller層,Service層,Dao層,

采用SpringBoot+SpringMvc+Mybatis來實作,達到在設計上的高内聚低耦合。

SSM——使用者資訊管理系統
SSM——使用者資訊管理系統

3 資料庫表設計

drop database if exists usermanager;
create DATABASE if not exists usermanager character set utf8;
use usermanager;

drop table if exists usermessage;
create table `usermessage` (
`id` INT PRIMARY KEY auto_increment,
`name` varchar (60),
`username` varchar (60) default 'bit',
`password` varchar (60) default '123456',
`gender` varchar (4),
`age` int,
`address` varchar (90),
`qq` varchar (20),
`email` varchar (30)
);

INSERT INTO usermessage VALUES(1,'張飛','zhangfei','123','男',18,'成
都','1262913815','[email protected]');
INSERT INTO usermessage VALUES(2,'關羽','guanyu','1234','男',18,'陝
西','1262913816','[email protected]');
INSERT INTO usermessage VALUES(3,'張三','zhangsan','1235','女',19,'陝
西','1262913817','[email protected]');
           

4 建立實體類(POJO)

User: 使用者資訊

@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String username;
    private String password;
    private String gender;
    private int age;
    private String address;
    private String qq;
    private String email;
}
           

PageBean:用來傳回給前端資訊

@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageBean<T> {
    private int totalCount; //總記錄數
    private int totalPage; //總頁碼
    private List<T> list; //每頁中的資料
    private int currentPage;//目前頁碼
    private int rows; //每頁的記錄數
}
           

5 UserMapper接口

@Service
public interface UserMapper {
    //注冊
    int register(User registerUser);
    
    //登入
    User login(User loginUser);
    
   //增加使用者
    int add(User addUser);
    
    //删除
    int delete( int id);
    
   //根據id查找
    User find(int id);
    
    //更新
    int update(User updateUser);

    //查詢共有多少條記錄
    int findAllRecord(HashMap<String,Object> map);

    //分頁查詢 map:包含:currentPage、rows、name、address、email
    List<User> findByPage(HashMap<String,Object> map);

}

           

6 編寫UserMapper.xml

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
        
<mapper namespace="com.glp.dao.UserMapper">

    <!--注冊-->
    <insert id="register" parameterType="user">
        insert into usermessage(name,username,password,gender,age,address,qq,email) values(#{name},#{username},#{password},#{gender},#{age},#{address},#{qq},#{email})
    </insert>
    
    <!--分頁查詢-->
    <!--select * from usermessage where 1=1 and name like ? and address like ? and email like ?
    limit ?,?-->
    <select id="findByPage" parameterType="map" resultType="user">
        select * from usermessage
        <where>
            <if test="name!=null">
                name like concat('%',#{name},'%')
            </if>
            <if test="address!=null">
                and address like concat('%',#{address},'%')
            </if>
            <if test="email!=null">
                and email like concat('%',#{email},'%')
            </if>
        </where>
        limit #{startIndex},#{rows}
    </select>
</mapper>
           

注:

  • 分頁查詢時采用了動态SQL,并且這裡需要注意一下模糊查詢時的sql注入問題,

    編寫動态SQL時,最好先将原SQL寫出來。

  • 為了友善分頁查詢時的傳參,這裡采用了HashMap進行傳參

7 配置SpringBoot (application.properties)

debug=true
# 設定列印日志的級别,及列印sql語句
logging.level.root=INFO
logging.level.druid.sql.Statement=ERROR
logging.level.com.glp=DEBUG

#springmvc配置參數
spring.mvc.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.date-format=yyyy-MM-dd HH:mm:ss
spring.jackson.time-zone=GMT+8

#配置資料庫連接配接池初始化參數
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/usermanager?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=mysql

#給實體類起别名,别名預設為原名小寫
mybatis.type-aliases-package = com.glp.pojo
#指明mapper.xml檔案在哪裡
mybatis.mapper-locations=classpath:mapper/*.xml 

#自定義根路徑
server.servlet.context-path:/usermanagers

           

8 service層設計

service層不僅是對Dao層的直接引用,在這裡一般需要做一些邏輯上的處理。

(1)service層接口

service層接口:UserService

@Service
public interface UserService {
    //注冊
    int register(User registerUser);

    //登入
    User login(User loginUser);

    //增加使用者
    int add(User addUser);

    //删除
    int delete(int id);

    //根據id查找,用來判斷user是否存在,如果存在,就繼續執行下面的returnFront,及update
    User find(int id);

    //負責将find查到的user,通過session傳給前端,在controller中進行處理

    //更新
    int update(User updateUser);

    //查詢共有多少條記錄
    int findAllRecord(HashMap<String,Object> map);

    //分頁查詢 map:包含:currentPage、rows、name、address、email
    PageBean<User> findAllByPage(HashMap<String,Object> map);
}
           

其他的接口基本上都和Dao層接口類似,是以直接調用dao層的接口即可。是以這裡我們隻讨論分頁查詢部分,這裡采用分頁查詢時,我們采用

findAllByPage

對dao層的結果進行邏輯處理.

(2)UserServiceImpl

service層實作類:UserServiceImpl

@Service
public class UserServiceImpl implements UserService{
    @Resource
    private UserMapper userMapper;

    @Override
    public int register(User registerUser) {
        return userMapper.register(registerUser);
    }

    @Override
    public User login(User loginUser) {
        return userMapper.login(loginUser);
    }

    @Override
    public int findAllRecord(HashMap<String,Object> map) {
        return userMapper.findAllRecord(map);
    }

    //在service層做邏輯整合
    @Override
    public PageBean<User> findAllByPage(HashMap<String,Object> map) {
        PageBean<User> pageBean=new PageBean<>();

        int rows = (int)map.get("rows");
        int currentPage = (int)map.get("currentPage");

        //查詢目前搜尋中共有多少條記錄
        int allRecord = findAllRecord(map);

        //計算總共的頁數
        int totalPage;
        if(allRecord%rows==0){
            totalPage=allRecord/rows;
        }else{
            totalPage=allRecord/rows+1;
        }

        //分頁查詢:傳回使用者資料,及總頁數,目前頁數,一頁的行數。
        int start=(currentPage-1)*rows;
        map.put("startIndex",start);
        List<User> users = userMapper.findByPage(map);
        pageBean.setCurrentPage(currentPage);
        pageBean.setList(users);
        pageBean.setRows(rows);
        pageBean.setTotalCount(allRecord);
        pageBean.setTotalPage(totalPage);
        return pageBean;
    }
}
           

通過Dao層的

findAllRecord(map);

來根據前端得到的name,address,email進行模糊查詢,用來查出目前條件下查詢出的總條數。

這裡需要進行邏輯處理,是因為分頁查詢時,需要知道分頁

limit

的 起始點startIndex。

同時我們需要計算 總頁數 ,以及将分頁查詢的所有User封裝到pageBean中,以在controller層傳給前端。

9 Controller層設計

(1)注冊,登入,添加,删除單個使用者

比較簡單,不做讨論

@Controller
public class UserController {
    @Resource
    private UserServiceImpl userService;

    //注冊使用者
    @RequestMapping("/registerServlet")
    public void register(HttpServletRequest req, HttpServletResponse resp,User u) throws IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=utf-8");
        Writer writer = resp.getWriter();
        int ret =userService.register(u);
        if(ret == 0) {
            System.out.println("注冊失敗!");
            writer.write("<h2> 注冊失敗 </h2>" );
        }else {
            System.out.println("注冊成功!");
            resp.sendRedirect("/usermanagers/login.html");
        }
    }
     }
           

(2)修改使用者

SSM——使用者資訊管理系統

修改使用者時,在list.html中通過點選修改頁面,通路

/findUserServlet

,查詢使用者是否存在,如果存在則将使用者寫入Session中。

//檢視要修改的對象是否存在,如果存在就将該對象存入session中
    @RequestMapping("/findUserServlet")
    public String findIfNeedUpdate(HttpServletRequest req,HttpServletResponse resp,int id) throws UnsupportedEncodingException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("application/json;charset=utf-8");
        User user = userService.find(id);
        if(user == null) {
            System.out.println("沒有要修改的對象!");
        }else {
            //将要修改的對象存入session中
            req.getSession().setAttribute("updateUser",user);
            return "redirect:/update.html"; //通過update.html調用updateServlet
        }
        return "redirect:/list.html";
    }
           
SSM——使用者資訊管理系統

如果存在該使用者,就通過重定向轉到update.html頁面,在update.html頁面通過ajax通路

/returnServlet

,拿到sessiong中的user資訊,将資訊傳回給前端:

SSM——使用者資訊管理系統
//在更新使用者的時候,通過通路returnServlet拿到要修改的user對象,并将該對象填入前端界面中
    @RequestMapping("/returnServlet")
    public void returnFront(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("application/json;charset=utf-8");

        Object updateUser = req.getSession().getAttribute("updateUser");

        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resp.getWriter(),updateUser);
    }
           
SSM——使用者資訊管理系統

當點選送出按鈕時,會觸發ajax通路

/updateServlet

,進行真正的修改操作:

//如果該使用者存在,就可以通過update.html,進入/updateServlet
    @RequestMapping("/updateServlet")
    public void updateUser(HttpServletRequest req,HttpServletResponse resp,User user) throws IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("application/json;charset=utf-8");

        //還要從session中拿到要修改的id
        User sessionUser = (User)req.getSession().getAttribute("updateUser");
        int id = sessionUser.getId();
        user.setId(id);

        int ret = userService.update(user);
        Map<String,Object> return_map=new HashMap<>();
        if (ret==1){
            return_map.put("msg",true);
        }else{
            return_map.put("msg",false);
        }
        ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),return_map);
    }

           

(3)批量删除使用者:

在controller層中直接寫(不在service層處理),删除選中的所有使用者,也是通過service中的delete方法,會将前端傳過來的id數組,逐個删除。

@RequestMapping("/deleteSelectedServlet")
    public void deleteAllSelect(HttpServletRequest req,HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("utf-8");
        resp.setContentType("application/json;charset=utf-8");

        //擷取數組id
        String[] values = req.getParameterValues("id[]");

        int sum=0;
        Map<String,Object> map=new HashMap<>();
        for(int i=0;i<values.length;i++){
            int j = Integer.parseInt(values[i]);
            //調用Service層方法删除
            int delete = userService.delete(j);
            sum=sum+delete;
        }
        if(sum==values.length){
            //證明删除成功
            map.put("msg",true);
        }else {
            map.put("msg",false);
        }
        ObjectMapper mapper = new ObjectMapper();
        mapper.writeValue(resp.getWriter(),map);
    }
           
SSM——使用者資訊管理系統
SSM——使用者資訊管理系統

查詢操作結束後,将選中的id儲存到Array數組中.通過ajax函數傳回給後端,在controller層通過

req.getParameterValues("id[]");

擷取id數組,然後調用service層的delete方法,對每個id對應的使用者進行删除。

(4)分頁模糊查詢

//分頁+模糊查詢
    @RequestMapping("/findByPageServlet")
    public void findUserByPage(HttpServletRequest req, HttpServletResponse resp) throws IOException {
        req.setCharacterEncoding("UTF-8");
        resp.setContentType("text/html; charset=utf-8");

        //rows,currentPage,name,address,email
        String rows = req.getParameter("rows");
        String currentPage = req.getParameter("currentPage");
        String name = req.getParameter("name");
        String address = req.getParameter("address");
        String email = req.getParameter("email");

        Integer rowsInt = Integer.valueOf(rows);
        Integer currentPageInt = Integer.valueOf(currentPage);

        HashMap<String,Object> map = new HashMap<String,Object>();
        map.put("rows",rowsInt);
        map.put("currentPage",currentPageInt);
        map.put("name",name);
        map.put("address",address);
        map.put("email",email);
        
        PageBean<User> allByPage = userService.findAllByPage(map);

        //傳給前端
        ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),allByPage);
    }

}
           
SSM——使用者資訊管理系統

這裡通過map的方式将前端擷取的資料傳給service層的

findAllByPage

方法;

點選查詢按鈕時的操作:

SSM——使用者資訊管理系統

一開始進入list.html頁面時會預設調用下面這個函數,5代表一頁的行數,1代表目前頁。

SSM——使用者資訊管理系統

注:

調用完Service層的findAllByPage(map)方法後,會得到前端需要的pageBean目前頁面資訊,包括使用者資訊

list<User>

,總頁數totalPage,總記錄數totalCount,目前頁currentPage,每頁行數rows。這裡我們通過

ObjectMapper

以json形式傳遞給前端。

ObjectMapper mapper=new ObjectMapper();
        mapper.writeValue(resp.getWriter(),allByPage);
           

10 使用者登入狀态攔截——攔截器

項目布置完後,發現我們不用登入也可以直接通路後面的list.html等内容,為此我們選擇在項目中增加一個登入驗證的部分——攔截器。

SSM——使用者資訊管理系統

(1)LoginInterceptor

攔截到請求後,檢查是否登入過(通過使用者的Session資訊),登入過則直接傳回ture,允許繼續通路;沒有登入則直接跳轉到登入頁面。

package com.glp.config;
@Component  //注冊到Spring容器中
public class LoginInterceptor implements HandlerInterceptor {
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        try{
            HttpSession session = request.getSession();
            User user = (User)session.getAttribute("user");
            if(user!=null){
                return true;
            }
            //登入不成功,直接跳轉到登入頁面
            response.sendRedirect(request.getContextPath()+"/login.html");
        }catch (IOException o){
            o.printStackTrace();
        }
        return false;
    }
}
           

(2)MyConfig

package com.glp.config;
@Configuration
public class MyConfig implements WebMvcConfigurer {
    @Autowired
    private  LoginInterceptor loginInterceptor;

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        //添加一個攔截器
        registry.addInterceptor(loginInterceptor).
        		 // 攔截配置
        		addPathPatterns("/**").
        		
        		// 排除配置
                excludePathPatterns("/**/loginServlet").
                excludePathPatterns("/**/registerServlet").
                excludePathPatterns("/**/login.html").
                excludePathPatterns("/**/register.html").
              
                excludePathPatterns("/**/*.js")
                .excludePathPatterns("/**/*.css").
                excludePathPatterns("/**/*.png").
                excludePathPatterns("/**/*.jpg");
    }
           

addInterceptor

:添加一個攔截器,将攔截下來的路徑交給它來處理

addPathPatterns

: 攔截配置

excludePathPatterns:

排除配置

排除配置中主要将登入和注冊的靜态頁面Html以及servlet請求中的動态頁面都給放行,對于其他的頁面都要進行攔截。

SSM——使用者資訊管理系統

注意我們在攔截時采用了

addPathPatterns("/**")

.,即所有的内容都給攔截包括靜态内容,為了簡單起見,在這裡我們直接采用暴力的方法,對我們所要用到的靜态内容,js,css,png,jpg等都給放行,