天天看點

商城項目(store)學習小結(2)——注冊登入的持久層建立

3.2 建立持久層

3.2.1 準備工作

  1. 在src/test/java下的com.cy.store.StoreApplicationTests測試類中編寫并執行“擷取資料庫連接配接”的單元測試,以檢查資料庫連接配接的配置是否正确。
@Autowired
private DataSource dataSource;

@Test
public void getConnection() throws Exception {
	System.out.println(dataSource.getConnection());
}
           
  1. 執行測試方法,檢查配置環境是否正常

3.2.2 規劃需要執行的SQL語句

  1. 使用者注冊的本質是向使用者表中插入資料,需要執行的SQL語句大緻是:
    INSERT INTO t_user (除了uid以外的字段清單) VALUES (比對的值清單)
               
  2. 由于資料表中使用者名字段被設計為UNIQUE,在執行插入資料之前,還應該檢查該使用者名是否已經被注冊,是以需要有“根據使用者名查詢使用者資料”的功能。需要執行的SQL語句大緻是:
    SELECT * FROM t_user WHERE username=?
               

3.2.3 接口與抽象方法

  1. 建立com.cy.store.mapper.UserMapper接口,并在接口中添加抽象方法。
    package com.cy.store.mapper;
    
    import com.cy.store.entity.User;
    import org.apache.ibatis.annotations.Mapper;
    
    /**
     * 使用者子產品的持久層接口
     */
    @Mapper
    public interface UserMapper {
    
        /**
         * 插入使用者的資料(使用者注冊)
         * @param user 使用者的資料
         * @return 受影響的行數(增删改受影響的行數作為傳回值,可根據傳回值判斷是否執行成功)
         */
        Integer insertUser(User user);
    
        /**
         * 根據使用者名來查詢使用者的資料
         * @param username 使用者名
         * @return 如果找到使用者就傳回使用者資料,沒找到傳回null
         */
        User findByUsername(String username);
    }
               
  2. MyBatis與Spring整合後需要實作實體和資料表的映射關系。

    需要在接口上面直接添加 @Mapper 注解,或者在啟動類上标注 @MapperScan(“com.cy.store.mapper”) 注解,裡面填持久層接口所在的包

    商城項目(store)學習小結(2)——注冊登入的持久層建立
    商城項目(store)學習小結(2)——注冊登入的持久層建立

3.3 配置 sql 映射檔案

  1. 在src/main/resources下建立mapper檔案夾,并在該檔案夾下建立UserMapper.xml映射檔案,進行以上兩個抽象方法的映射配置。

    (經典注釋比代碼多,有很多基礎,我隻能說很細)

    <?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屬性:用于指定目前的映射檔案和哪個接口進行映射-->
    <mapper namespace="com.cy.store.mapper.UserMapper">
    
        <!--resultMap标簽來完成自定義映射規則,屬性:
            id:唯一辨別
            type:表示資料庫查詢的結果和指定的實體類進行結果集的映射
           -->
        <resultMap id="UserEntityMap" type="com.cy.store.entity.User">
            <!--在定義映射規則時主鍵是不可以省略的-->
            <id column="uid" property="uid"/>
            <!--完成名稱不一緻的映射
                column屬性:表示表中字段名稱
                property屬性:表示類中的屬性名稱-->
            <result column="is_delete" property="isDelete"/>
            <result column="created_user" property="createdUser"/>
            <result column="created_time" property="createdTime"/>
            <result column="modified_user" property="modifiedUser"/>
            <result column="modified_time" property="modifiedTime"/>
        </resultMap>
    
        <!-- 插入使用者資料:Integer insertUser(User user) -->
        <!--屬性:
            useGeneratedKeys:表示開啟某個字段(一般是主鍵)的值遞增
            keyProperty:表示将表中的那個字段作為主鍵進行自增
        -->
        <insert id="insertUser" useGeneratedKeys="true" keyProperty="uid">
            INSERT INTO
                t_user (username, password, salt, phone, email, gender, avatar, is_delete, created_user, created_time, modified_user, modified_time)
            VALUES
                (#{username}, #{password}, #{salt}, #{phone}, #{email}, #{gender}, #{avatar}, #{isDelete}, #{createdUser}, #{createdTime}, #{modifiedUser}, #{modifiedTime})
        </insert>
    
        <!-- 根據使用者名查詢使用者資料:User findByUsername(String username) -->
        <!--select語句在執行的時候查詢的是一個對象或者多個對象-->
        <!--屬性:
            resultType:表示查詢結果集類型,需要指定對應映射類的類型
            resultMap:目前的資料庫字段和和類的對象的屬性名稱不一緻時,自定義的查詢結果集的映射規則
        -->
        <select id="findByUsername" resultMap="UserEntityMap">
            SELECT
                *
            FROM
                t_user
            WHERE
                username = #{username}
        </select>
    
    </mapper>
               
  2. 由于這是項目中第一次使用SQL映射,是以需要在application.properties中添加mybatis.mapper-locations屬性的配置,以指定XML檔案的位置。
    mybatis.mapper-locations=classpath:mapper/*.xml
               

3.4 完成單元測試

完成後及時執行單元測試,檢查以上開發的功能是否可正确運作。在src/test/java下建立com.cy.store.mapper.UserMapperTests單元測試類,在測試類的聲明之前添加@SpringBootTest注解,并在測試類中聲明持久層對象,通過自動裝配來注入值。(細節全在注釋中)

package com.cy.store.mapper;

import com.cy.store.entity.User;
import org.junit.jupiter.api.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

/**
 * @author 且聽風吟
 * @version 1.0
 * @description: 每個獨立的層編寫完成後需要編寫單元測試方法,測試目前功能
 *       SpringBootTest注解:表示目前類是一個測試類,不會随同項目一塊打包
 * @date 2022/4/12 0012 23:11
 */
@SpringBootTest
public class UserMapperTests {

    //報錯原因:idea有檢測的功能,接口是不能直接建立Bean的(spring用動态代理技術來解決)
    //接口上使用@Mapper不會報錯,主類上使用@MapperScan會報錯
    @Autowired
    UserMapper userMapper;

    /**
     *  單元測試方法:可以單獨運作,不用啟動整個項目,可以做單元測試,提升了代碼的測試效率
     * 1.必須被@Test直接修飾
     * 2.傳回值必須是void
     * 3.方法的參數清單不指定任何類型
     * 4.方法的通路修飾符必須是public
     */
    @Test
    public void insertUser(){
        User user = new User();
        user.setUsername("jim");
        user.setPassword("123");
        Integer rows = userMapper.insertUser(user);
        System.out.println(rows);
    }

    @Test
    public void findByUsername(){
        User jim = userMapper.findByUsername("jim");
        System.out.println(jim);
    }
}
           

繼續閱讀