Mybatis的增刪改查

Mybatis的增刪改查

  • 本人獨立博客:https://chenjiabing666.github.io/

增長數據<insert>

  • 在增長數據的時候,mybatis默認返回的是受影響的行數,所以不須要指定ResultType指定返回類型
  • UserMapper.java接口中添加方法
/**
    @param user User對象
*/
Integer reg(User user);
  • UserMapper.xml文件中添加<insert>節點java

    • #{}中填寫的是User對象的屬性名稱

<!-- 節點名稱取決於須要執行的操做 -->
    <!-- 例如增長操做應該使用insert節點 -->
    <!-- id屬性(*)的值是Java接口中的方法名稱 -->
    <!-- parameterType屬性的值是參數類型 
    -->
    <!-- 節點中間編寫SQL語句 -->
    <insert id="reg"
        parameterType="cn.tedu.spring.entity.User">
        INSERT INTO user (
            username, password
        ) VALUES (
            #{username}, #{password}
        )
    </insert>
  • 測試
@Test
    public void testReg() {
        //加載Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //獲取UserMapper的bean,這個是spring經過掃描mapper.xml文件自動爲mybatis自動建立的,首字母小寫
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        
        //新建User對象
        User user = new User();
        user.setUsername("Tom1");
        user.setPassword("123456");
        
        //調用reg(user),進行添加,返回的是受影響的行數
        Integer affectedRows
            = userMapper.reg(user);
        
        System.out.println(
            "affectedRows=" + affectedRows);
        ac.close();
    }

在Mybatis中增長數據時獲取自增主鍵的id

  • 首先mybatis在處理增長數據的功能時,只是返回受影響的行數,因此在持久層中並不會返回新增長的
  • 若是須要獲取自增主鍵Id,首先,在XML映射的<insert>節點中須要添加2個屬性
    • useGeneratedKeys :設置是否返回自增主鍵,若是爲true則返回,默認爲false
    • keyProperty : 配置自增主鍵在表中對應的字段 ,由於有時候在表中的自增主鍵的字段可能不是id,所以須要指定
<!-- 節點名稱取決於須要執行的操做 -->
    <!-- 例如增長操做應該使用insert節點 -->
    <!-- id屬性(*)的值是Java接口中的方法名稱 -->
    <!-- parameterType屬性的值是參數類型 
        useGeneratedKeys: 指定是否返回自增主鍵,默認爲false
        keyProperty:配置自增主鍵在表中對應的字段 
    -->
    <insert id="reg"
        parameterType="cn.tedu.spring.entity.User" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO user (
            username, password
        ) VALUES (
            #{username}, #{password}
        )
    </insert>
  • 此時的mybatis執行insert方法以後,便是調用reg(user),返回的仍是受影響的行數,並非此時的自增主鍵id的值。而是在調用這個方法的時候將id封裝到指定的方法參數中,便是封裝到user中了,所以只有調用者才能夠獲取id,而持久層沒法獲取
@Test
    public void testReg() {
        //加載Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //獲取UserMapper的bean,這個是spring經過掃描mapper.xml文件自動爲mybatis自動建立的,首字母小寫
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        
        //新建User對象,此時並無設置id的值
        User user = new User();
        user.setUsername("Tom1");
        user.setPassword("123456");
        
        //調用reg(user),進行添加,返回的是受影響的行數,可是此時已經將id封裝到參數User對象中了
        Integer affectedRows
            = userMapper.reg(user);
        
        System.out.println(
            "affectedRows=" + affectedRows);
        //直接獲取Uesr對象中的id值,這個是自增主鍵返回的值
        System.out.println("id = "+user.getId());
        ac.close();
    }

刪除數據<delete>

  • 在刪除數據的時候,自動會返回受影響的行數,不須要在delete節點中定義返回類型,只有在查詢數據的時候纔會定義返回類型git

  • UserMapper.java中添加一個接口方法github

//根據id刪除數據,返回受影響的行數,返回1,若是刪除失敗返回0
    Integer deleteUserById(int id);
  • UserMapper.xml中配置<delete>節點
<!-- 刪除用戶數據根據id
        Integer deleteUserById(int id)
        parameterType: 指定參數類型,這裏也能夠不須要指定
     -->
    <delete id="deleteUserById" parameterType="int">
        delete from user where id=#{id}
    </delete>
  • 刪除數據是不可逆的,一般不會真正的刪除數據,咱們會使用備份,日誌等手段來保存數據,在許多軟件上看到的刪除也許都是修改操做,一般在表中有一個字段is_deleted標記是否刪除,若是執行刪除,那麼就會設置其值爲true表示已經刪除了,那麼此時將不會顯示在客戶端,讓客戶覺得已經被刪除了

Mybaits參數規則

  • mybatis默認支持一個參數,便是定義的接口方法中只能有一個參數
  • 若是須要支持多個參數,那麼須要使用@Param()註解
  • 若是接口方法中的參數類型是基本類型的能夠不用parameterType指定類型,若是不是基本類型的,規範要求須要使用parameterType指定類型,可是能夠不寫

@Param()

  • mybatis默認支持一個參數,便是定義的接口方法中只能有一個參數
  • 在設計java接口方法時,若是須要指定多個參數,那麼必須使用@Param()
  • 若是想要支持多個參數,須要使用@Param()來指定參數,好比Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
    • 其中@Param("key")中的value在配置增刪改查的時候是使用#{key}表達式取出的
  • mybaits在處理過程當中,本質上是使用了Map對參數進行了封裝的。便是@Param("")註解中給出的參數值是Map中的key,調用方法時給出的參數值是Map中的value值,而最終在XML文件中使用#{}獲取值,實際上是使用Map中的get(key)方法獲取的

修改數據<update>

  • 在修改數據的時候,mybatis自動返回受影響的行數,所以咱們不須要定義返回類型,默認的返回數據就是受影響的行數spring

  • UserMapper.java接口中定義根據id修改數據的方法spring-mvc

    • 使用@Param()註解來標記多個參數

/**
     * 修改密碼
     * @param id  id
     * @param newPassword  新密碼
     * @return  受影響的行數
     */
    Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
  • UserMapper.xml中添加<update>節點mybatis

    • 其中#{}表達式中的字段爲@Param("value")中的value

<!-- 修改密碼
        Integer ChangePassword(@Param("id")Integer id,@Param("newPassword")String newPassword);
     -->
    <update id="ChangePassword">
        update user set password=#{newPassword} where id=#{id}
    </update>
  • 測試方法
@Test
    public void testChangePassword() {
        //加載Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //獲取UserMapper的bean,這個是spring經過掃描mapper.xml文件自動爲mybatis自動建立的,首字母小寫
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        //調用刪除的方法
        int affectRow=userMapper.ChangePassword(3, "12345895");
        System.out.println(affectRow);
        ac.close();
    }

案例:修改用戶密碼

用戶提供數據

  • 舊密碼:oldPassword
  • 新密碼:newPassword

步驟

  1. 經過id查找用戶信息
    1. 不可使用select * from user where id=? and password=?,由於這個是不區分大小寫的,咱們應該先根據id獲取用戶信息,再比較password
    2. UserserviceImpl中完成驗證邏輯,若是用戶不存在,那麼拋出用戶不存在的異常,若是存在就驗證原密碼和是否匹配
  2. 用戶信息存在,那麼就要驗證用戶輸入的oldPassword和用戶信息中的原密碼是否相同了,若是不相同,拋出密碼不匹配的異常,若是相同,那麼就能夠修改密碼
  3. 修改密碼

實現

  • 咱們編寫了一個UserService中編寫邏輯
public void ChangePasssword(Integer id, String oldPassword,
            String newPassword) throws UserNotFoundException, PasswordNotMatchException{
        User user=this.findUserById(id);  //獲取用戶信息
        if (user==null) {   //若是用戶信息不存在
                throw new UserNotFoundException("操做失敗,用戶信息不存在");
        }else { //用戶存在,則判斷原密碼
            if (user.getPassword().equals(oldPassword)) {//若是密碼匹配
                
                userMapper.ChangePassword(id, newPassword);  //修改密碼
            }else {   //原密碼不匹配
                    throw new PasswordNotMatchException("操做失敗,原密碼不正確");
            }
        }
    }
  • 那麼在Controller中若是要調用這個ChangePasssword將會經過處理異常來判斷哪裏是出錯了,並給出友好的提示

查詢數據<select>

單條數據的查詢

  • 根據id的查詢返回的查詢結果就是單條數據,好比:select * from user where id=1
  • 單條記錄的查詢在編寫接口方法的時候,只須要返回一個實體類對象便可
/**
     * 根據id查詢用戶信息
     * @param id  用戶id
     * @return 返回User對象
     */
    User findUserById(Integer id);
  • UserMapper.xml中配置<select>節點
    • 須要使用resultType指定返回的類型,由於參數是基本類型,所以不須要使用parameterType指定參數類型
<select id="findUserById" resultType="cn.tedu.spring.entity.User">
        select * from user where id=#{id}
    </select>

多條記錄的查找

  • 有些查找語句返回的是多條記錄,那麼咱們可使用List<>集合來接收返回的結果,不能直接使用實體類對象來接收
  • UserMapper.java中定義接口方法
/**
     * 根據密碼查找用戶
     * @param password 用戶密碼
     * @return 返回的是一個用戶的集合
     */
    List<User> findUserByPassword(String password);
  • UserMapper.xml中添加<select>節點
    • 這裏的resultType雖然返回的是User集合,可是這裏的類型仍是須要寫User類型
    • 因爲參數是基本類型,所以不須要使用parameterType
<!-- 
        List<User> findUserByPassword(String password);
        resultType: 雖然返回的是User集合,可是這裏的類型仍是須要寫User類型
     -->
     
     <select id="findUserByPassword" resultType="cn.tedu.spring.entity.User">
        select * from user where password=#{password}
     </select>
  • 測試
@Test
    public void testFindUserByPassword() {
        //加載Spring的配置文件
        AbstractApplicationContext ac
            = new ClassPathXmlApplicationContext(
                "spring-mvc.xml",
                "spring-dao.xml");
        
        //獲取UserMapper的bean,這個是spring經過掃描mapper.xml文件自動爲mybatis自動建立的,首字母小寫
        UserMapper userMapper
            = ac.getBean(
                "userMapper", UserMapper.class);
        //獲取User集合
        List<User> users=userMapper.findUserByPassword("12345895");
        System.out.println(users);
        ac.close();
    }

總結

  1. xxMapper.xml中配置的節點的id要和xxMapper.java中的方法名相同
  2. mybatis默認支持一個參數,可是咱們可使用@Param("")指定多個參數,不過在使用#{}取值的時候要和@Param("")中的參數一致
  3. 獲取自增主鍵並非做爲方法的返回值,而是在調用方法的時候將自增主鍵的值設置在方法參數的對象中,那麼此時的調用者就能夠獲取到自增主鍵的值
  4. 增長,修改,刪除,方法返回的永遠是受影響的行數
  5. **在定義實體類屬性的時候,儘可能使用包裝類,好比Integer age**
  6. 只要是<select>節點,那麼必須寫返回類型resultType,不管是基本型仍是其餘類型
相關文章
相關標籤/搜索