1. 程式人生 > 實用技巧 >mybatis 詳細學習記錄

mybatis 詳細學習記錄

MyBatis是什麼?

MyBatis 本是apache的一個開源專案iBatis, 2010年這個專案由apache software foundation 遷移到了google code,並且改名為MyBatis,實質上Mybatis對ibatis進行一些改進。 目前mybatis在github上託管。 git(分散式版本控制,當前比較流程)
  MyBatis是一個優秀的持久層框架,它對jdbc的操作資料庫的過程進行封裝,使開發者只需要關注 SQL 本身,而不需要花費精力去處理例如註冊驅動、建立connection、建立statement、手動設定引數、結果集檢索等jdbc繁雜的過程程式碼。
  Mybatis通過xml或註解的方式將要執行的各種statement(statement、preparedStatemnt、CallableStatement)配置起來,並通過java物件和statement中的sql進行對映生成最終執行的sql語句,最後由mybatis框架執行sql並將結果對映成java物件並返回。

mybatis架構

搭建開發環境

(1)導包

(2)匯入配置檔案

這裡我在工程檔案下新建了一個和src平級的檔案,把有關mybatis配置檔案和src檔案分離,看去介面更加清晰,因為在ssh開發中你肯定還要配置其它配置檔案

這裡的log4j.properties主要是為了在後臺輸出是更加看的清楚執行流程,這個可要可不要.

(3)配需相關檔案屬性

User.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名稱空間,為了對sql語句進行隔離,方便管理 ,mapper開發dao方式,使用namespace有特殊作用 -->
<mapper namespace="test">
<!-- 在mapper.xml檔案中配置很多的sql語句,執行每個sql語句時,封裝為MappedStatement物件
mapper.xml以statement為單位管理sql語句
 -->
    <!-- 根據id查詢使用者資訊 -->
    <!-- 
        id:唯一標識 一個statement
        #{}:表示 一個佔位符,如果#{}中傳入簡單型別的引數,#{}中的名稱隨意
        parameterType:輸入 引數的型別,通過#{}接收parameterType輸入 的引數
        resultType:輸出結果 型別,不管返回是多條還是單條,指定單條記錄對映的pojo型別
     -->
    <select id="findUserById" parameterType="int" resultType="com.study.model.User">
        SELECT * FROM USER WHERE id= #{id}
    </select>
    
    <!-- 根據使用者名稱稱查詢使用者資訊,可能返回多條
    ${}:表示sql的拼接,通過${}接收引數,將引數的內容不加任何修飾拼接在sql中。
     -->
    <select id="findUserByName" parameterType="java.lang.String" resultType="com.study.model.User">
        select * from user where username like '%${value}%'
    </select>
    
    <!-- 新增使用者
    parameterType:輸入 引數的型別,User物件 包括 username,birthday,sex,address
    #{}接收pojo資料,可以使用OGNL解析出pojo的屬性值
    #{username}表示從parameterType中獲取pojo的屬性值
    selectKey:用於進行主鍵返回,定義了獲取主鍵值的sql
    order:設定selectKey中sql執行的順序,相對於insert語句來說
    keyProperty:將主鍵值設定到哪個屬性
    resultType:select LAST_INSERT_ID()的結果 型別
     -->
    <insert id="insertUser" parameterType="com.study.model.User">
        <selectKey keyProperty="id" order="AFTER" resultType="int">
            select LAST_INSERT_ID()
        </selectKey>
        INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
    </insert>
    
    <!-- 使用者刪除  -->
    <delete id="deleteUser" parameterType="int">
     delete from user where id=#{id}
    </delete>
    <!-- 使用者更新 
    要求:傳入的user物件中包括 id屬性值
    -->
    <update id="updateUser" parameterType="com.study.model.User">
        update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
</mapper>

SqlMapConfig.xml

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!-- 和spring整合後 environments配置將廢除-->
    <environments default="development">
        <environment id="development">
        <!-- 使用jdbc事務管理-->
            <transactionManager type="JDBC" />
        <!-- 資料庫連線池-->
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>
    <!-- 載入mapper.xml -->
    <mappers>
        <mapper resource="sqlmap/User.xml" />
    </mappers>
</configuration>

User.java

public class User {
    private int id;
    private String username;// 使用者姓名
    private String sex;// 性別
    private Date birthday;// 生日
    private String address;// 地址
   /*
    *提供set和get方法,和toString方法
    *
    */
}
MybatisFirst 測試類,進行增刪改查
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;

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.Before;
import org.junit.Test;

import com.guigu.model.User;

public class MybatisFirst {
    // 會話工廠
    private SqlSessionFactory sqlSessionFactory;
    // 建立工廠
    @Before  //before在text標籤之前執行,所以會建立好sqlSessionFactory物件
    public void init() throws IOException {
        // 配置檔案(SqlMapConfig.xml)
        String resource = "SqlMapConfig.xml";
        // 載入配置檔案到輸入 流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 建立會話工廠
        sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    }
   
    
    // 根據id查詢使用者(得到單條記錄)
    @Test
    public void testFindUserById() {
        // 通過sqlSessionFactory建立sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
        // 通過sqlSession操作資料庫
        // 第一個引數:statement的位置,等於namespace+statement的id
        // 第二個引數:傳入的引數
        User user = sqlSession.selectOne("test.findUserById", 16);
       
            sqlSession.close();
        
        System.out.println(user);
    }

    // 模糊查詢(可能是單條也可能是多條)
    @Test
    public void testFindUserByName() {
        // 通過sqlSessionFactory建立sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
       
        //selectList代表著返回是list集合
        List<User>  list = sqlSession.selectList("test.findUserByName", "小明");
      
            sqlSession.close();
     
        System.out.println(list.get(0).getUsername());
    }

    // 新增使用者
    @Test
    public void testInsertUser() {
        // 通過sqlSessionFactory建立sqlSession
        SqlSession sqlSession = sqlSessionFactory.openSession();
     
        User user = new User();
        user.setUsername("小小徐");
        user.setAddress("杭州市餘杭區未來科技城");
        user.setBirthday(new Date());
        user.setSex("1");
           //insert代表插入
            sqlSession.insert("test.insertUser", user);
 
            //檢視是不需要提交事物的,但是插入和修改是需要提交事物的
            sqlSession.commit();
            sqlSession.close();
           //這裡輸出的id竟然是0,有哪位大神解釋下嗎?
        System.out.println("使用者的id=" + user.getId());
    }
// 根據id刪除使用者 @Test public void testDeleteUser() { // 通過sqlSessionFactory建立sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // delete代表刪除使用者 sqlSession.delete("test.deleteUser", 29); sqlSession.commit(); sqlSession.close(); } // 根據id更新使用者 @Test public void testUpdateUser() { // 通過sqlSessionFactory建立sqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); // 建立更新資料物件,要求必須包括 id User user = new User(); user.setId(40); user.setUsername("小小鐘"); user.setAddress("杭州餘杭區東西大道"); //user.setBirthday(new Date()); user.setSex("1"); //update更新資料 sqlSession.update("test.updateUser", user); sqlSession.commit(); sqlSession.close(); System.out.println("使用者的id=" + user.getId()); } }

mybatis與hibernate重要區別

  企業開發進行技術選型 ,考慮mybatis與hibernate適用場景。
    mybatis:入門簡單,程式容易上手開發,節省開發成本 。mybatis需要程式設計師自己編寫sql語句,是一個不完全 的ORM框架,對sql修改和優化非常容易實現 。
      mybatis適合開發需求變更頻繁的系統,比如:網際網路專案。
    hibernate:入門門檻高,如果用hibernate寫出高效能的程式不容易實現。hibernate不用寫sql語句,是一個 ORM框架。
      hibernate適合需求固定,物件資料模型穩定,中小型專案,比如:企業OA系統。
  總之,企業在技術選型時根據專案實際情況,以降低成本和提高系統 可維護性為出發點進行技術選型。
總結
  SqlMapConfig.xml
    是mybatis全域性配置檔案,只有一個,名稱不固定的,主要mapper.xml,mapper.xml中配置 sql語句
  mapper.xml
    mapper.xml是以statement為單位進行配置。(把一個sql稱為一個statement),satatement中配置 sql語句、parameterType輸入引數型別(完成輸入對映)、resultType輸出結果型別(完成輸出對映)。還提供了parameterMap配置輸入引數型別(過期了,不推薦使用了),還提供resultMap配置輸出結果型別(完成輸出對映)
  #{}
    表示一個佔位符,向佔位符輸入引數,mybatis自動進行java型別和jdbc型別的轉換。程式設計師不需要考慮引數的型別,比如:傳入字串,mybatis最終拼接好的sql就是引數兩邊加單引號。#{}接收pojo資料,可以使用OGNL解析出pojo的屬性值
  ${}
    表示sql的拼接,通過${}接收引數,將引數的內容不加任何修飾拼接在sql中。${}也可以接收pojo資料,可以使用OGNL解析出pojo的屬性值
    缺點:不能防止sql注入。
  selectOne
    用於查詢單條記錄,不能用於查詢多條記錄,否則異常:
      org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: 4
  selectList
    用於查詢多條記錄,可以用於查詢單條記錄的。

以上為雨點的聲音原創