1. 程式人生 > 實用技巧 >狂神說Java【SMBMS】——SMBMS超市訂單管理系統(六) ——使用者管理功能實現

狂神說Java【SMBMS】——SMBMS超市訂單管理系統(六) ——使用者管理功能實現


1.匯入分頁工具類



檢視一下這個工具類的原始碼


​ OOP的3大特性:封裝、繼承、多型,其中封裝 = 屬性私有+屬性的get/set() + 在set中限制一些不安全的賦值操作(這一步可以留到service層再做,但是在封裝的時候做更好,這樣減少了service層的程式碼,且體現了封裝的特性)

2.使用者列表頁面匯入

​ 首先是HTML檔案




分析:

  • Dao層使用聚合函式COUNT(*)查詢使用者表一共多少條記錄
  • service層用於統計總共有多少條資料
  • servlet層用於向前端返回總共的資料條數

3.獲取使用者數量

1、UserDao介面

​ 因為是獲取使用者的數量,所以和使用者表有關,那這個介面方法就放在前面已經建立好的UserDao中

​ 方法定義的時候需要哪些引數?

​ 檢視前端素材:

​ 可見,查詢介面我們需要實現按照使用者名稱查詢、按照角色名稱查詢和整表查詢

​ 再去看看資料庫中的資料表

聯表查詢的基本SQL語句

SELECT COUNT(1)
FROM smbms_user u,smbms_role r
WHERE u.userRole = r.id;

​ 這是MYSQL的方言版內連線查詢,內連線兩張表的地位平等,只要我們加了WHERE過濾笛卡爾積,那麼輸出的結果就只包含有主外來鍵關聯的欄位

但是從前面的需求我們可以看出,前端素材提供了按照姓名查詢、按照職位查詢和整表查詢,所以我們需要在上面聯表查詢的基礎上再新增一些篩選條件,新增的手段就是使用"AND 條件"來實現

在Java中實現我們可以使用StringBuffer來實現sql語句的拼接

package com.thhh.dao.user;

import com.thhh.pojo.User;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;

public interface UserDao {
    /**
     * 1、得到要進行登陸的使用者
     * @param conn:資料庫連線物件
     * @param userCode:通過使用者的使用者名稱userCode查詢使用者資料
     * @return
     */
    public User getLoginUserInfo(Connection conn,String userCode);

    /**
     * 2、修改使用者密碼
     * @param conn:資料庫連線物件
     * @param id:修改密碼的使用者的ID
     * @param newPwd:新密碼
     * @return:影響行數
     */
    public int updatePwd(Connection conn,String newPwd,int id);

    /**
     * 3、用於獲取資料庫中使用者總數
     * @param conn:資料庫連線物件
     * @param userName:使用者名稱,這個引數主要用於按照使用者名稱稱查詢使用者資訊
     * @param userRole:使用者角色,這個引數主要用於按照使用者角色查詢使用者資訊
     * @return :查詢到的行數
     */
    public int getUserCount(Connection conn, String userName, int userRole) throws SQLException;
}

​ 只看方法3

2、UserDaoImpl介面實現

//3、根據使用者名稱/角色名獲取使用者總數
@Override
public int getUserCount(Connection conn, String userName, int userRole) throws SQLException {
    PreparedStatement pstmt = null;
    ResultSet rs = null;
    int count = 0;
    if (conn!=null){
        StringBuffer sql = new StringBuffer();//使用字串緩衝區,這樣就可以動態的在sql後面追加AND條件了
        sql.append("SELECT COUNT(1) COUNT FROM smbms_user u,smbms_role r WHERE u.userRole = r.id");//基本的聯表查詢SQL語句
        List<Object> list = new ArrayList<Object>();//建立一個list來儲存我們要拼接的篩選條件,由於我們不能限制傳入的引數的資料型別,所以泛型指定為object
        if (!StringUtils.isNullOrEmpty(userName)){//判斷傳入的使用者名稱是不是空,如果不是空表明前端指定了按照姓名查詢的引數
            sql.append("AND userName like ?");
            list.add("%"+userName+"%");
        }
        if (userRole>0){
            sql.append("AND userRole = ?");
            list.add(userRole);
        }
        Object[] params = list.toArray();//獲得BaseDao中為pstmt物件設定引數的引數列表
        rs = BaseDao.executeQuery(sql.toString(), params, conn, pstmt, rs);//呼叫查詢定義好的查詢方法
        if (rs.next()){//獲取查詢結果
            count = rs.getInt("COUNT");//COUNT是在SQL語句中為查詢結果取的別名
        }
        BaseDao.close(null,pstmt,rs);//關閉資源
    }
    return count;
}

​ 注意回顧知識點:

  • StringBuffer類:一個專門用來彌補String內容不可修改的類,呼叫這個類物件的append()可以實現在字串的末尾加上新字串且不會產生新的字串物件(String物件的拼接操作其實在底層就是產生了新的String物件)
  • 使用List集合來儲存引數,這樣做的好處就在於我們可以動態的向集合中新增引數,而不是像前面使用陣列那樣固定了陣列長度;其實集合也是用來彌補陣列長度不可修改的缺陷而出現的,使用集合儲存資料即使資料很多也不會產生新的集合物件,而陣列不一樣,陣列一經建立長度就固定了;而針對上面要實現的需求我們不知道到底前端要進行哪一種操作,所以我們不能定義一個定長的陣列,即使按照最大需求量定義陣列,雖然可以滿足要求,但是在不能充分使用的時候就是資源的浪費
  • 上面使用的動態的拼接SQL語句的做法很明智:既使用了StringBuffer物件控制SQL語句在提交之前可變,又使用了List集合來儲存引數,在提交的時候才將其轉為陣列

3、UserService介面

package com.thhh.service.user;

import com.thhh.pojo.User;

public interface UserService {
    /**
     * 1、獲取登陸使用者物件,對使用者登陸身份進行驗證
     * @param userCode:使用者賬號
     * @param userPassword:使用者密碼,注意,密碼判斷我們在service層進行;
     *                      在Dao層只是簡單的操作資料庫,沒有其他的邏輯程式碼;在servlet層中只是接收和轉發請求以及控制檢視跳轉
     *                      而對於業務層(service)就是用來實現業務邏輯程式碼的
     * @return
     */
    public User login(String userCode,String userPassword);

    /**
     * 2、根據使用者ID修改使用者密碼
     * @param newPwd:新密碼
     * @param id:使用者ID
     * @return
     */
    public boolean updatePwd(String newPwd, int id);

    /**
     * 3、獲取使用者總數
     * @param userName:按照使用者姓名查,查到的使用者總數
     * @param userRole:按照使用者角色查,查到的使用者總數
     * @return:返滬對應查詢條件查到的使用者總數
     */
    public int getUserCount(String userName, int userRole) ;
}

​ 只看方法3

4、UserServiceImpl介面實現

/**
 * 3、按照條件查詢符合條件的使用者總數
 * @param userName:按照使用者姓名查,查到的使用者總數
 * @param userRole:按照使用者角色查,查到的使用者總數
 * @return
 */
@Override
public int getUserCount(String userName, int userRole) {
    Connection conn = null;
    int rs = 0;

    try {
        conn = BaseDao.getConnection();//獲取資料庫連線物件
        rs = userDao.getUserCount(conn,userName,userRole);//業務層呼叫Dao層獲取業務結果
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally {
        BaseDao.close(conn,null,null);//關閉資源
    }
    return rs;//業務層將業務結果返回給servlet
}

5、測試

​ bug1:

4.獲取使用者列表

1、UserDao介面

/**
 * 4、使用者獲取使用者列表
 * @param conn:資料庫連線物件
 * ===========後面兩個引數用於條件查詢使用者資料
 * @param userName:按照使用者名稱查詢
 * @param userRole:按照角色名稱查詢
 * ===========後面兩個引數用於對按照上面條件查詢出來的結果進行分頁處理
 * @param currentPageNo:翻到第多少頁
 * @param pageSize:每一頁多少條資料
 * @return:返回滿足條件的user物件集合
 */
public List<User> getUserList(Connection conn, String userName, int userRole, int currentPageNo, int pageSize) throws SQLException;

2、UserDaoImpl介面實現

    //4、獲取滿足條件的使用者物件集合
    @Override
    public List<User> getUserList(Connection conn, String userName, int userRole, int currentPageNo, int pageSize) throws SQLException {
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        List<User> userList = null;
        if (conn!=null){
            userList = new ArrayList<User>();
            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> temp = new ArrayList<Object>();
            if (userName!=null){
                sql.append(" AND u.userName LIKE ?");
                temp.add("%"+userName+"%");
            }
            if (userRole>0){
                sql.append(" AND u.userRole = ?");
                temp.add(userRole);
            }

            sql.append(" ORDER BY u.creationDate DESC LIMIT ?,?");//在sql最後追加一個排序和分頁
            //5
            //1     5
            //2     10
            //3     15
            currentPageNo = (currentPageNo-1)*pageSize;//減一的原因就是MYSQL分頁的index從0開始

            temp.add(currentPageNo);//從哪一個下標開始
            temp.add(pageSize);//從currentPageNo連續取幾個

            Object[] params = temp.toArray();
            rs = BaseDao.executeQuery(sql.toString(),params,conn,pstmt,rs);
            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"));//這個屬性是在POJO中新加入的,資料表中沒有
                userList.add(_user);//將查到的這個物件分裝為物件並存入List集合中
            }
            BaseDao.close(null,pstmt,rs);
        }
        return userList;
    }

3、UserService介面

/**
 * 4、根據使用者名稱/使用者角色名稱來查詢資料,返回一個User物件集合,而currentPageNo+pageSize用於前端做分頁操作
 * @param userName
 * @param userRole
 * @param currentPageNo
 * @param pageSize
 * @return:滿足條件+limit的User物件集合
 */
public List<User> getUserList(String userName, int userRole, int currentPageNo, int pageSize);

4、Userservice介面實現

/**
 * 4、根據使用者名稱/使用者角色名稱來查詢資料,返回一個User物件集合,而currentPageNo+pageSize用於前端做分頁操作
 * @param userName
 * @param userRole
 * @param currentPageNo
 * @param pageSize
 * @return:滿足條件+limit的User物件集合
 */
@Override
public List<User> getUserList(String userName, int userRole, int currentPageNo, int pageSize) {
    Connection conn = null;
    List<User> userList = null;

    try {
        conn = BaseDao.getConnection();//獲取連線
        userList = userDao.getUserList(conn,userName,userRole,currentPageNo,pageSize);//業務層呼叫Dao層獲取業務結果
    } catch (SQLException throwables) {
        throwables.printStackTrace();
    }finally {
        BaseDao.close(conn,null, null);//關閉資源
    }
    return userList;//業務層將業務結果返回給servlet
}

5、測試

@Test
public void test(){
    List userList = new UserServiceImpl().getUserList(null,0,2,5);
    //(3-1)*5 = 10,所以展示的是10~14條資料,但是一共只有12條,注意:MYSQL中結果index從0開始
    for (Object o : userList) {
        System.out.println(((User)o).getUserName());
    }
}



測試完成!