Mybatis實現數據庫增刪改查

MyBatis入門主要講解了Mybatis的基本配置。在這些配置裏面需要注意一下問題:

  • 持久層接口和持久層接口的映射配置文件必須在相同的包下。
    
  • 持久層接口配置文件中的mapper標籤的namespace屬性取值必須是持久層就看的全限定類名。
    
  • SQL語句的配置標籤中的id屬性值必須和持久層接口的方法名相同。例如上面的<select>標籤中的id屬性值findAll和UserDao接口中的方法名findAll相同。
    

接着MyBatis入門繼續深入瞭解,在UserDao接口裏面加入根據Id查詢用戶的方法

package com.liang.dao;

import com.liang.domain.User;

import java.util.List;

public interface UserDao{

    /**
     * 查詢所有用戶
     * @return
     */
    List<User> findAll();

    /**
     * 根據id查詢用戶
     * @param id
     * @return
     */
    User findById(int id);
    
}

同時需要在接口映射文件裏面添加相應的SQL語句:根據Id查詢用戶

<?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">
<mapper namespace="com.liang.dao.UserDao">
    <select id="findAll" resultType="com.liang.domain.User" >
        select *from user;
    </select>

    <!--根據id查詢用戶-->
    <select id="findById" resultType="com.liang.domain.User" parameterType="int">
        select *from user where id= #{userID};
    </select>
</mapper>

select標籤中需要掌握的是其屬性。

屬性名 屬性值
resultType 用於指定結果集的類型
parameterType 用於指定傳入參數的類型

**SQL語句中使用的#{}字符:**代表佔位符,相當於使用jdbc的prepareStatement時候SQL語句傳入的?,都是用於執行語句時候替換爲實際的數據。
由於在MyBatis入門中通過main方法進行的測試的,這給後面的測試會帶來很多不便,因此我做了在下面做了修改,使用了測試類進行測試,修改代碼如下,並且加上了通過id查詢用戶的方法。


import com.liang.dao.UserDao;
import com.liang.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;

public class TestMyBatis {

    private SqlSession sqlSession = null;
    private InputStream inputStream = null;
    private UserDao userDao = null;
    @Before
    public void init() throws IOException {
        inputStream = Resources.getResourceAsStream("SqlConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
        userDao = sqlSession.getMapper(UserDao.class);
    }
    @After
    public void destroy() throws IOException {
        sqlSession.close();
        inputStream.close();
    }

    /**
     * 查詢所有用戶信息
     */
    @Test
    public void testFindAll(){
        List<User> users = userDao.findAll();
        for (User user : users)
        {
            System.out.println(user.toString());
        }
    }

    /**
     * 通過ID查詢用戶
     */
    @Test
    public void testFindById(){
        User user = userDao.findById(41);
        System.out.println(user.toString());
    }
}

實現保存用戶信息
繼續在持久層接口UserDao.java中添加保存方法。

  /**
     * 保存用戶
     * @param user
     */
    void saveUser(User user);

相應的在其對應的接口映射文件中添加SQL語句。

   <!--注意此處傳入的參數類型是我們自定義的參數類型
      相應的#{}佔位符寫入的內容,也應該是自定義類型的屬性名。
      此處使用的都是apache提供的一種表達式語言 OGNL
      全稱:Object Graphic Navigation Language(對象圖導航語言)
    -->
    <insert id="saveUser" parameterType="com.liang.domain.User">
        insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex}, #{address});
    </insert>

在測試類中添加測試方法。

   @Test
    public void testSaveUser()
    {
        User user = new User();
        user.setUsername("娃哈啊");
        user.setSex("女");
        user.setBirthday(new Date());
        user.setAddress("陝西");
        userDao.saveUser(user);
        System.out.println("保存完畢");
    }

執行測試方法後,發現數據庫裏面並沒有添加成功,這裏和jdbc是相同的,在執行增刪改的時候要控制事務的提交,在Mybatis中通過SqlSession對象的commit()方法來提交事務。可以將提交事務的方法加入到 userDao.saveUser(user);後面,也可以加入到 @After裏面。

//在測試方法執行完成之後執行
 @After
    public void destroy() throws IOException {
        
        sqlSession.commit();
        
        sqlSession.close();
        inputStream.close();
    }

當添加提交方法後,在userDao.saveUser(user);後面打印用戶信息發現此時id值爲0,其實此處的id值是數據庫自增長實現的,因此需要在新增用戶後將自動增長的值進行獲取。修改接口映射文件如下:

 <insert id="saveUser" parameterType="com.liang.domain.User">
        <!--配置保存時,獲取插入的id
        keyColumn:  數據庫表對應的字段
        keyProperty:  User對象的屬性
        order: 執行順序
        -->
        <selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
            select last_insert_id();
        </selectKey>
        insert into user(username,birthday,sex,address) values (#{username},#{birthday},#{sex}, #{address});
    </insert>

修改後在userDao.saveUser(user);後面打印用戶信息發現id是我們需要的id.
添加更新用戶和以上步驟沒有任何區別。
在持久層添加更新方法:

   /**
     * 更新用戶
     * @param user
     */
    void updateUser(User user);

在持久層對應的映射文件添加SQL語句:

 <!--更新用戶-->
    <update id="updateUser" parameterType="com.liang.domain.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>

在測試類中添加測試方法:

  /**
     * 更新用戶
     */
    @Test
    public void testUpdateUser()
    {
        User user = userDao.findById(70);
        user.setUsername("wahaha");
        userDao.updateUser(user);
        System.out.println(user);
    }

添加刪除用戶也是相同的三步。
在持久層添加刪除方法:

    /**
     * 通過用戶ID刪除用戶
     * @param userId
     */
    void deleteUser(int userId);

在相應的配置文件添加SQL語句:

  <!--通過用戶id刪除用戶-->
    <delete id="deleteUser">
        delete from user where id= #{uid}
    </delete>

在測試類中添加測試方法:

   /**
     * 通過用戶ID刪除用戶
     */
    @Test
    public void testDeleteUser()
    {
        userDao.deleteUser(70);
        System.out.println("刪除成功");
    }

兩種模糊查詢的方式
兩種方式和上面的一樣,都需要三步完成。
方式一
在持久層接口中添加模糊查詢的方法

  /**
     * 根據名稱模糊查詢
     * @param name
     * @return
     */
    List<User>findByName(String name);

在映射文件中添加SQL語句

 <!--根據名稱模糊查詢-->
    <select id="findByName" parameterType="String" resultType="com.liang.domain.User">
        select *from user where username like #{username}
    </select>

添加測試方法

  /**
     * 根據名稱模糊查詢用戶
     */
    @Test
    public void testFindByName()
    {
        List<User> users = userDao.findByName("%小%");
        for (User user : users)
        {
            System.out.println(user);
        }
    }

方式二
在持久層接口中添加模糊查詢的方法,這一步不做任何改變。
在映射文件中添加SQL語句

  <!--根據名稱模糊查詢 
    需要注意問題:
            1.將#{}佔位符改爲${value}
            2.${value是固定寫法,不能該寫成其他}-->
    <select id="findByName" parameterType="String" resultType="com.liang.domain.User">
        select *from user where username like '%${value}%'
    </select>

添加測試方法

   /**
     * 根據名稱模糊查詢用戶
     */
    @Test
    public void testFindByName()
    {
        List<User> users = userDao.findByName("小");
        for (User user : users)
        {
            System.out.println(user);
        }
    }

以上兩種方式雖然執行結果相同,但是是有區別的,區別主要體現在執行SQL語句時。
#{}表示一個佔位符,相當於PreparedStatement,可以有效的防止SQL注入問題。而且#{}可以接收簡單類型的值和 POJO 屬性值。
SQLSQL{}表示拼接SQL,內容拼接不能有效防止SQL注入,{}也可以接收簡單類型值和 POJO 屬性值。如果parameterType傳遞耽擱簡單型參數${}括號中只能是value。
聚合函數的使用
在持久層接口中添加查詢總記錄條數的方法

    /**
     * 查詢總記錄條數
     * @return
     */
    int findTotal();

在映射文件中添加SQL語句

 <!--查詢總記錄條數-->
    <select id="findTotal" resultType="int">
        select count(*) from user
    </select>

添加測試方法

   /**
     * 查詢總記錄條數
     */
    @Test
    public void testFindTotal()
    {
        int res = userDao.findTotal();
        System.out.println(res);
    }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章