MyBatis快速上手增刪改查

MyBatis入門到CURD

做爲一個快樂的小碼農,在每個階段每每都在重複寫着不一樣版本的,學生管理,用戶管理,註冊登陸,從 JavaSE 的控制檯版,或者 GUI 版,再到 JavaWeb的 JSP版,再到純粹使用 HTML 做爲前端展現的版本,以及使用一個更新的技術,在此其中,咱們用過 txt 作數據庫,用 XML 也能夠,到如今經常使用的 MySQL,增刪改查一直是咱們必不可少的一部份內容,即便你不懂原理,即便你對這個技術的理解不是很深入,拿出你的增刪改查,噼裏啪啦就是一段亂敲,好歹仍是能讓你着手先作起來(固然,對技術的理解仍是很重要的),今天就和你們聊一聊 MyBatis 這門技術的 CURD (增刪改查)前端

優化測試方法

在測試方法中,讀取配置文件,生產 SqlSession,釋放資源等等,在每一測試方法的時候,都是重複的,因此咱們徹底能夠提出出這一部分,防止大量的重複代碼java

@Before
    public  void init() throws Exception{
        //讀取配置文件
        inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        //建立SqlSessionFactory工廠
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);

        //使用工廠生產SqlSession對象
        sqlSession= factory.openSession();
        //使用SqlSession建立Mapper接口的代理對象
        userMapper = sqlSession.getMapper(UserMapper.class);
    }
@After
    public void destroy() throws Exception{
        sqlSession.close();
        inputStream.close();
    }

在這兩個方法上增長 @Before 和 @Aftrer 註解,就能夠保證,init() 和 destory() 這兩個方法,分別在咱們真正被測試的方法的先後執行sql

(一) 增添操做

(1) 編寫代碼

首先,在 UserMapper 接口中 增長對應的方法數據庫

public interface UserMapper {
    /**
     * 增長用戶
     * @param user
     */
    void addUser(User user);
}

接着,在SQL映射文件中,增長新增的映射配置,這些有關內容放在 <insert></insert>標籤對中,具體代碼以下微信

<insert id="addUser" parameterType="cn.ideal.domain.User">
    insert into                           user(username,telephone,birthday,gender,address)values(#{username},#    {telephone},#{birthday},#{gender},#{address})
</insert>

(2) 說明:

一、id 屬性,天然是對應的方法名,而因爲這裏,咱們並不須要拿到返回信息,因此這裏並無返回參數 resultType,而方法中的參數又爲一個 JavaBean 類,也就是User實體類,因此須要在標籤屬性中,添加一個 parameterType 屬性,其中須要指定這個實體類app

二、在文本中書寫插入的SQL語句,因爲實體類中已經快捷生成了對應的 get set 方法,所一可使用 #{}的方式表明對應的值dom

三、提示,數據庫中id爲自增,因此並不須要設置 idide

(3) 注意:

因爲添加是更新類的語句,因此在執行插入語句後,須要提交事務,也就是執行對應的 commit方法,以提交更新操做,若沒有這一句,即便不會報錯,也沒法正常存入,會被回滾,且這個id被佔用測試

(4) 測試代碼:

/**
     * 測試新增用戶
     * @throws Exception
     */
    @Test
    public void testUpdateUser() throws Exception{
        User user = new User();
        user.setId(17);
        user.setUsername("修改");
        user.setTelephone("18899999999");
        user.setBirthday(new Date());
        user.setGender("女");
        user.setAddress("廣州");

        //執行方法
        userMapper.updateUser(user);

    }

(5) 執行結果:

控制檯:優化

(6) 獲取新增用戶的id值

首先對於 MySQL自增主鍵來講,在執行 insert語句以前,MySQL 會自動生成一個自增主鍵,insert執行後,經過 SELECT LAST_INSERT_ID() 能夠獲取這條剛插入記錄的自增主鍵

在 SQL 映射配置文件中,須要藉助 <selectKey></selectKey> 標籤,有一個屬性比較特殊,order 屬性,它表明着相對於插入操做的執行時間,before-以前,after-以後

注:該標籤插入到 <select></select>

<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
    SELECT LAST_INSERT_ID();
</selectKey>

測試一下

@Test
public void testAddUser() throws Exception{
    User user = new User();
    user.setUsername("增長");
    user.setTelephone("12266660000");
    user.setBirthday(new Date());
    user.setGender("男");
    user.setAddress("珠海");
    System.out.println("執行插入前" + user);
    //執行方法
    userMapper.addUser(user);
    System.out.println("執行插入後" + user);
}

執行效果

(二) 修改操做

(1) 編寫代碼

在 UserMapper 接口中增長修改方法

public interface UserMapper {
    /**
     * 更新用戶
     * @param user
     */
    void updateUser(User user);
}

在 SQL 映射文件中增長語句,內容包括在 <update></update> 中,須要注意的基本與添加操做是一致的

<update id="updateUser" parameterType="cn.ideal.domain.User">
    update user set username=#{username},telephone=#{telephone},birthday=#{birthday},gender=#{gender},address=#{address} where id=#{id}
</update>

(2) 測試代碼

/**
     * 測試新增用戶
     * @throws Exception
     */
    @Test
    public void testAddUser() throws Exception{
        User user = new User();
        user.setUsername("增長");
        user.setTelephone("12266668888");
        user.setBirthday(new Date());
        user.setGender("女");
        user.setAddress("成都");

        //執行方法
        userMapper.addUser(user);

    }

(3) 執行效果

(三) 刪除操做

(1) 編寫代碼

接口中增長刪除方法

public interface UserMapper {
    /**
     * 刪除用戶
     * @param uid
     */
    void deleteUser(Integer uid);
}

在SQL映射文件中,使用 <delete></delete> 標籤對進行內容的書寫,須要注意的是,因爲咱們傳入的參數是一個 Integer類型的用戶id,因此參數類型的值爲 parameterType

<delete id="deleteUser" parameterType="java.lang.Integer">
    delete from user where id=#{id}
</delete>

(2) 測試代碼

/**
 * 測試刪除用戶
 * @throws Exception
 */
@Test
public void testDeleteUser() throws Exception{
    //執行方法
    userMapper.deleteUser(17);
}

(3) 執行效果

(四) 模糊查詢

因爲查詢所有很是簡單,這裏就不展現了,基本流程都是同樣的

(1) 編寫代碼

在 UserMapper 接口中編寫方法

public interface UserMapper {
    /**
     * 經過姓名模糊查詢
     * @param username
     * @return
     */
    List<User> findByName(String username);
}

在 SQL 映射文件中新增查詢語句

<select id="findByName" parameterType="java.lang.String" resultType="cn.ideal.domain.User">
    select * from user where username like #{username}
</select>

(2) 測試代碼

/**
 * 測試模糊查詢
 * @throws Exception
 */
@Test
public void testFindByName() throws Exception{
    List<User> users = userMapper.findByName("%張%");
    for (User user : users){
        System.out.println(user);
    }
}

(3) 注意

在使用模糊查詢的時候,咱們須要在查詢條件的兩側拼接兩個 「%」 字符串,這個時候有兩種解決方案,一種就是像在我上述代碼中,在測試時將字符串補充完整,還有一種方式就是 使用 ${} ,它在 SQL配置文件中表明一個 「拼接符號」 ,也就是說能夠這樣寫 SQL語句

select * from user where username like '%{value}'

可接受的類型有,普通類型(此狀況下{}內部只能寫value),JavaBean,HashMap

可是使用 %{} 拼接字符串的時候,會引發 SQL注入,因此不是很推薦使用

(4) 執行效果

(五) 自定義包裝類做爲查詢條件

Mapper 的輸入映射樣例中,咱們對於基本數據類型和基本數據包裝類,都有了必定的瞭解,而下面咱們來聊一聊關於相對複雜的一種狀況,那就是自定義包裝類

先講一個需求:仍是關於用戶的查詢,可是查詢條件複雜了一些,不只僅侷限於用戶的信息,並且可能還包括訂單,購物車,或者與用戶一些行爲相關的信息,那麼如何實現這樣一種需求呢?

那咱們想,可不能夠,在 User 類中增長一些咱們須要的信息

  • 從代碼的角度來看,在 User 中添加的字段與數據庫不必定能對應起來,在原來的基礎上作修改,就會影響 User 做爲數據庫映射對象的功能,因此咱們能夠建立一個 UserInstance 類,繼承 User類就能夠在其中爲某些業務添加一些不屬於數據庫的字段了

(1) 定義包裝類

package cn.ideal.domain;

public class QueryUserVo {
    private UserInstance userInstance;

    public UserInstance getUserInstance() {
        return userInstance;
    }

    public void setUserInstance(UserInstance userInstance) {
        this.userInstance = userInstance;
    }

    //其餘查詢條件,例如訂單,購物車等等
}

(2) 配置 Mapper 文件

咱們這裏使用用戶的性別以及對姓名的模糊查詢,來寫SQL 固然,你也能夠本身經過別的信息寫SQL

<select id="findUserByVo" parameterType="cn.ideal.domain.QueryUserVo" resultType="cn.ideal.domain.UserInstance">
    select * from user where user.gender=#{userInstance.gender} and user.username like #{userInstance.username}
</select>

在QueryUserVo 中,封裝的是查詢信息的各類對象,爲何上述代碼能夠直接經過 userInstance.gender 直接取出對應的屬性,這種方式叫作 OGNL 表達式,在類中 咱們的寫法一般是 user.getUsername 但在寫法上,OGNL 表達式將get給省略了

(3) 測試代碼

/**
 * 包裝對象做爲查詢參數
 * @throws Exception
 */
@Test
public void testFindUserByVo() throws Exception{
    //建立包裝對象,設置查詢條件
    QueryUserVo queryUserVo = new QueryUserVo();
    UserInstance userInstance = new UserInstance();
    userInstance.setGender("女");
    userInstance.setUsername("%張%");
    queryUserVo.setUserInstance(userInstance);

    //調用 UserMapper 的方法
    List<UserInstance> userInstances 
          = userMapper.findUserByVo(queryUserVo);
    for (UserInstance u : userInstances){
        System.out.println(u);
    }
}

(4) 執行效果

結尾

若是文章中有什麼不足,歡迎你們留言指正,感謝你們的支持!

若是能幫到你的話,那就來關注我吧!若是您更喜歡微信文章的閱讀方式,能夠關注個人公衆號

在這裏的咱們素不相識,卻都在爲了本身的夢而努力 ❤

一個堅持推送原創開發技術文章的公衆號:理想二旬不止

相關文章
相關標籤/搜索