天天看點

spring+springMVC+mybatis的整合 part4

SSM架構執行個體--管理系統--登入注冊的功能分析

分析:

登入和注冊,都是使用者的行為,也是開發中常說的某個行為對應的業務。

注冊使用者:意味着添加使用者,添加了使用者後,才有登入功能的繼續執行的可能。

使用者登入:也是使用者資訊的查找和比對過程。一般來說使用者先把資訊送出給程式,然後程式按照流程執行後送出資料給伺服器(流程中程式可能會産生一些業務邏輯的判斷),伺服器收到資料并進行資料對比,當使用者資訊存在且帳号和密碼比對才能登入成功,否則前面的任意條件不滿足即為登入失敗。

可以依靠單一的使用者表來實作使用者的登入資料擷取和注冊資訊的添加。

功能大概分析完畢後,就可以考慮下如何實作這些功能。大概圖示如下:

ssm架構經典三層分析

首先使用者資訊需要存儲,需要資料庫的支撐。

有了資料庫的支撐後,需要先測試使用者資訊的添加和查找,也就是去資料庫的增删改查。就是

Dao

層。

Dao

層拿到想要的資料,需要

Service

層将

Dao

層的操作作為服務提供給控制器,再由控制器提供給前台頁面。

同樣的使用者需要擷取某個資料,先是浏覽器擷取到使用者請求→

web

層→

Service

Dao

層,再接着重複上面的操作。

上面一張圖用模型已經很好的說明了

Java web

後端各層的關系,下面一張圖是經典三層對照MVC的描述。

ssm架構經典三層分析對照Mvc

上面圖中,可以看到一部分MVC設計和圖中标記的類似,但是這隻是一種MVC模式的栗子。

關于更加詳細的MVC,我們可以

百度百科

檢視。

SSM架構執行個體--管理系統--注冊、登入的功能模拟實作

是以在開發的時候需要先考慮

Dao

層的實作,畢竟有了

Dao

層對資料的封裝,才可以有後面的操作。

一切都是按照Dao→Service→Controller→View這樣的一個步驟來實作。

使用者注冊功能的Dao層實作。

資料庫基本操作為:增删改查。

根據資料庫正常操作的類型,分别對其進行抽象,是以産生了Dao.java這個接口對象的基本模型。代碼如下:

使用泛型,<T> 泛型用于解耦,同時避免寫重複代碼

public interface Dao<T> {
    /**
     * 添加某個對象
     * @param t 待添加的對象
     * @return  傳回受影響的行數
     */
    int add(T t);

    /**
     * 删除某個對象,在企業開發中,我們一般不做實體删除,隻是添加某個字段對其資料進行可用控制
     * @param t 待删除對象
     * @return 傳回受影響的條數
     */
    int  delete(T t);

    /**
     * 更新某個對象
     * @param t 待更新對象
     * @return 傳回受影響的條數
     */
    int update(T t);

    /**
     * 通過ID查找一個對象
     * @param Id    待查詢的對象的ID
     * @return  傳回該ID對應的對象
     */
    T findOneById(Serializable Id);

    /**
     * 查找對象集合
     * @return  傳回對象集合
     */
    List<T> findAll();
}
           

建立使用者實體類,需要封裝一個使用者對象,直接在domain包下面建立類

User

實作

Serializable

接口是為了序列化。友善網絡傳輸等,傳遞對象的時候,序列化

public class User implements Serializable{
    private String name;    //名字
    private String sex; //性别
    private String loginId; //登陸ID
    private String pwd;    //密碼
    private String duty;    //職務
    private int age;    //年齡
    private String cellNumber;  //手機号
    private String photoUrl;    //頭像位址
    private boolean used = true;   //是否可用,預設值是true
    private String nextUrl; //下一步的的操作位址  
    //省略get、set和toString
}
           

sessionId

不需要封裝在實體類中

資料庫中對應的使用者表

user

CREATE TABLE `user` (
`login_id` varchar(20) NOT NULL COMMENT '登陸ID',
`pwd` varchar(20) NOT NULL COMMENT '使用者密碼',
`name` varchar(100) NOT NULL COMMENT '使用者姓名',
`age` int(3) NOT NULL COMMENT '使用者年齡',
`sex` varchar(3) NOT NULL COMMENT '性别',
`duty` varchar(15) COMMENT '職務',
`cell_number` varchar(15) COMMENT '手機号',
`photo_url` varchar(75) COMMENT '頭像位址',
`used` boolean NOT NULL COMMENT '賬号是否可用',
`session_id` varchar(45) COMMENT '目前登入的sessionId',
PRIMARY KEY (`login_id`)
) ENGINE=InnoDB AUTO_INCREMENT=1000 DEFAULT CHARSET=utf8 COMMENT='使用者表';
           

對user表進行操作封裝的接口

UserDao

接口,繼承

DAO

接口,在

dao

包下

public interface UserDao extends Dao<User>{
    int add(User user);

    int delete(User user);

    int update(User user);

    User findOneById(Serializable Id);

    void updateLoginSession(@Param("sessionId") String sessionId, @Param("loginId")  String loginId);

}
           

在傳統的jdbc操作中,需要手動管理資料庫連接配接的開關,資料庫資源通路的開關等等,采用了

Mybatis

Druid

這兩個架構,那麼我們可以完全不必理會資料庫連接配接等等的控制,隻需要更加專注于業務實作的開發。

完成

UserDao

的封裝後,傳統的操作這一步需要自己手動實作

UserDao

Impl

,并實作對資料庫的操作等等。而我們使用

Mybatis

後,

UserDao

Impl

Mybatis

mapper

檔案夾中指定為

xml

Dao

檔案除了資料庫操作的語句其他的都無需關注,那麼剩下的資料庫操作什麼的我們都無需關心,畢竟

Mybatis

druid

都把其他的事情幫我們做了。

UserDao.xml:

注意:

namespace

要指定到對應dao的位置,不然無法找到

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace指定我們的到具體的bean -->
<mapper namespace="pjb.ssm.dao.UserDao">

    <!--查找-->
    <select id="findOneById" resultType="User" parameterType="String">
    SELECT
    *
    FROM
    `user`
    WHERE
    login_id = #{userId}
    </select>

    <!--增加語句-->
    <insert id="add" parameterType="User">
        INSERT INTO
        `user`
        (`login_id`,`name`,`age`,`sex`,`duty`,`cell_number`,`photo_url`,`pwd`,`used`)
        VALUES
        (#{loginId},#{name},#{age},#{sex},#{duty},#{cellNumber},#{photoUrl},#{pwd},#{used})
    </insert>

    <!-- 删除 -->
    <update id="delete" parameterType="User">
        UPDATE
        `user`
        SET
        `used`=FALSE
        WHERE
        `login_id`=#{loginId};
    </update>

    <!-- 更新使用者資訊 -->
    <update id="update" parameterType="User">
        UPDATE
        `user`
        SET
        `name`=#{name}, `age`=#{age}, `sex`=#{sex}, `duty`=#{duty}, `cell_number`=#{cellNumber}, `photo_url`=#{photoUrl}
        WHERE
        `login_id`=#{loginId};
    </update>
    <!--更新session的id-->
    <update id="updateLoginSession">
        UPDATE
        `user`
        SET
        `session_id`=#{sessionId}
        WHERE
        `login_id`=#{loginId};
    </update>
</mapper>
           

mapper

下面的

UserDao.xml

已經完成,這就意味着我們的

UserDao

基本完成,下面做的是來編寫測試類

先在

test

目錄下建好對應的目錄,建好如下

Paste_Image.png

按照我們程式設計的原則,一次編碼處處運作,我們可以把這些注解放到

BaseTest

中,後面所有的單元測試都繼承

BaseTest

即可避免大量重複編碼。

BaseTest是主測試類

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({"classpath:spring/spring-*.xml"})
public class BaseTest {
}
           

@RunWith(SpringJUnit4ClassRunner.class)

是為了讓測試在Spring容器環境下執行。

@ContextConfiguration({"classpath:spring/spring-*.xml"})

用于指定配置檔案所在的位置

代碼非常簡單,用與dao,service測試類繼承用

UserDaoTest

,每個

@Test

單獨測試,由于測試結果不復原,可以在資料庫看到測試是否成功

public class UserDaoTest extends BaseTest {
    @Autowired
    private UserDao userDao;

    @Test
    public void testAdd() {
        User user = new User();
        user.setLoginId("2015081040");
        user.setName("意識流");
        user.setPwd("123456");
        user.setSex("不知道");
        int result = 0; //受影響的行數預設為0
        try {
            result = userDao.add(user);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("添加使用者失敗");
        }
        if (result>0)
            System.out.println("添加使用者成功");
    }

    @Test
    public void testFindOneId() throws Exception {
        User user = new User();
        user.setLoginId("2015081040");
        User result = null; //受影響的行數預設為0
        try {
            result = userDao.findOneById(user.getLoginId());
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("查找使用者失敗");
        }
        if (null!=result)
            System.out.println("查找使用者成功\n"+result.toString());
    }

    @Test
    public void testDelete() {
        User user = new User();
        user.setLoginId("2015081040");
        int result = 0; //受影響的行數預設為0
        try {
            result = userDao.delete(user);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("删除使用者失敗");
        }
        if (result>0)
            System.out.println("删除使用者成功");
    }

    @Test
    public void testUpdate() {
        User user = new User();
        user.setLoginId("2015081040");
        user.setName("pjb");
        user.setPwd("123456");
        user.setSex("男");
        int result = 0; //受影響的行數預設為0
        try {
            result = userDao.update(user);
        } catch (Exception e) {
            e.printStackTrace();
            System.out.println("更新使用者資訊使用者失敗");
        }
        if (result>0)
            System.out.println("更新使用者資訊使用者成功");

    }
}
           

**在測試的時候可能會發現

userDao

顯示

Could not autowire, No beans of 'UserDao' type found

**

但程式的編譯和運作都是沒有問題的,這個錯誤提示并不會産生影響。但紅色的錯誤提示在有些有強迫症的程式員眼裡,多多少少有些不太舒服。

原因

  

spring auto scan

配置,在編輯情況下,無法找不到對應的

bean

,于是提示找不到對應

bean

的錯誤。常見于

mybatis

mapper

,如下:

<!-- 4.配置掃描Dao接口包,動态實作Dao接口,注入到spring容器中 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <!-- 注入sqlSessionFactory -->
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/>
        <!-- 給出需要掃描Dao接口包 -->
        <property name="basePackage" value="pjb.ssm.dao"/>
    </bean>
           
  1. 解決方案

    降低

    Autowired

    檢測的級别,将

    Severity

    的級别由之前的

    error

    改成

    warning

    或其它可以忽略的級别。

    在project→settings中設定

    Autowired

    檢測的級别

    設定完後可以發現

    userDao

    的紅線消失了

主要參考于大牛

Clone丶記憶

的SSM內建之路