1. 程式人生 > >ORM框架--mybatis的基本工作流程

ORM框架--mybatis的基本工作流程

ORM:Object Relation Mapping:物件關係對映,通俗理解就是將一個物件相關屬性和資料庫資料進行關聯(對映),傳統我們對資料庫資料的操作可以通過ORM框架轉移到對物件的操作上來,這無疑有利於提高程式的開發效率和專案的可維護性,本質是對傳統的JDBC操作高階封裝

工作流程:mybatis通過sqlSessionFactory建立sqlSession,
sqlSession表示應用程式與資料庫的會話,當用戶使用mapper.xml檔案中配置的的方法時,mybatis首先會解析sql動態標籤為對應資料庫sql的形式,並將其封裝進MapperStatement物件,然後通過executor將sql注入資料庫執行,並返回結果

常見ORM框架:hibernate、mybatis

mybatis主要通過兩個配置檔案(sqlMapConfig.xml和Mapper.xml),來配置資料庫和物件的關係

sqlMapConfig.xml:

Mybatis的全域性配置檔案,主要配置mybatis的環境引數、對映物件執行引數。
mybatis的環境引數:資料來源配置、事務控制
對映物件執行引數:對映物件的別名設定、對映物件配置檔案載入

案例:

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration> <!-- 載入資料庫屬性檔案:db.properties --> <properties resource="db.properties"/> <!-- typeAliases:別名設定 package:mybatis自動掃描polo類,自動建立別名(型別名) --> <typeAliases> <typeAlias type="com.zhiwei.domain.User" alias="user"/> <package name="com.zhiwei.domain"
/>
</typeAliases> <!-- 和spring整合environment配置將拋棄 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事務管理 --> <transactionManager type="JDBC"/> <!-- 資料連線池 :mybatis管理--> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.user}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!-- 載入對映檔案 resource:每次只能載入一個檔案 class:只能mapper代理物件執行(mapper介面名和mapper.xml檔名一致,並且在同一個目錄) package:批量載入:name為mapper檔案所在的包名 --> <mappers> <mapper resource="com/zhiwei/domain/UserMapper.xml"/> </mappers> </configuration>

mapper.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 namespace="test">
<!-- 對映檔案配置sql語句 :select執行資料庫查詢
id:sql語句封裝mappedStatement的id
#{id}:佔位符,表示接受輸入的引數:id,如果輸入引數型別為簡單型別,
#{}中的引數名可以任意,
resultType:返回結果型別
-->
<select id="findUserById" parameterType="int" resultType="user">
select *from user where id=#{id}
</select>

<delete id="deleteUserById" parameterType="int">
delete from user where id=#{id}
</delete>

<!-- 如果輸入的引數為pojo型別,佔位符名稱使用pojo的屬性 -->
<update id="updateUser" parameterType="com.zhiwei.domain.User">
update  user set name=#{name},passwd=#{passwd} where id=#{id}
</update>

<insert id="addUser" parameterType="com.zhiwei.domain.User">
insert into user(id,name,passwd) values(#{id},#{name},#{passwd})
</insert>
</mapper>

mapper.xml對應的物件:

package com.zhiwei.domain;
public class User {
    private int id;
    private String name;
    private String passwd;

    public User(){}
    public User(int id, String name, String passwd) {
        super();
        this.id = id;
        this.name = name;
        this.passwd = passwd;
    }

    public int getId() {
        return id;
    }
    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getPasswd() {
        return passwd;
    }
    public void setPasswd(String passwd) {
        this.passwd = passwd;
    }
    @Override
    public String toString() {
        return "User [id=" + id + ", name=" + name + ", passwd=" + passwd + "]";
    }
}

sqlSession工具類:

package com.zhiwei.tool;

import java.io.IOException;
import java.io.InputStream;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * Mybatis工具類
 * @author Yang Zhiwei
 */
public final class MybatisTool {

    private static InputStream is=null;
    private static SqlSession sqlSession=null;

    /**
     * 獲取Mybstis SqlSession會話
     * @return
     */
    public static SqlSession getSession(){

     try {
        is=Resources.getResourceAsStream("SqlMapConfig.xml");
    } catch (IOException e) {
        e.printStackTrace();
    }

    /**本質通過呼叫DefaultSqlSessionFactory建立sqlSession
     *DefaultSqlSession:與資料庫進行JDBC操作的類
     *   MappedStatement:與JDBC操作的StateMent類類似,封裝sql資訊,
     *   mybatis的動態sql標籤在提交給資料庫之前會進行sql的規範化,控制檯日誌顯示
     *   executor:真正和資料庫進行互動的執行者
     *   configuration:mybatis配置檔案資訊的封裝類
     *部分原始碼:
     *   @Override
          public int update(String statement, Object parameter) {
            try {
              dirty = true;
              MappedStatement ms = configuration.getMappedStatement(statement);
              return executor.update(ms, wrapCollection(parameter));
            } catch (Exception e) {
              throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
            } finally {
              ErrorContext.instance().reset();
            }
          }
     *   
     * */
    //通過mybatis的控制檔案建立sqlSessionFactory
    SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is);
    sqlSession=sqlSessionFactory.openSession(); 
    return sqlSession;
    }

    /**
     * 關閉mybatis SqlSession會話
     */
    public static void resourceClosing(){
        try{
        if(sqlSession!=null){
            sqlSession.close();
        }
        if(is!=null){
           is.close();
        }
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

物件的操作方法介面(方法名必須與Mapper.xml檔案中sql的Id對應,mybatis無法正確解析):

package com.zhiwei.service;

import org.apache.ibatis.session.SqlSession;

import com.zhiwei.domain.User;
import com.zhiwei.tool.MybatisTool;

/***
 * 基礎服務類
 * @author Yang Zhiwei
 */
public  class BasicServiceImp{

    private static SqlSession sqlSession=null;

    //SqlSession初始化
    static{
        sqlSession=MybatisTool.getSession();
    }

    /**
     * 通過Id查詢使用者資訊
     * test:表示名稱空間  
     * findUserById:mapper.xml檔案的動態sql id
     * test.findUserById:指明訪問動態sql地址--->對應:<mapper namespace="test">
     * @param id
     * @return
     */
    public static User findUserById(int id) {
        return sqlSession.selectOne("test.findUserById", id);
    }

    /**
     * 更新使用者資訊
     * @param user
     */
    public static void updateUser(User user) {
        sqlSession.update("test.updateUser",user);
        sqlSession.commit();
        MybatisTool.resourceClosing();
    }

    /**
     * 刪除使用者資訊
     * @param id
     */
    public static void deleteUserById(int id) {
        sqlSession.delete("test.deleteUserById", id);
        sqlSession.commit();
        MybatisTool.resourceClosing();
    }

    /**
     * 新增使用者資訊
     * @param user
     */
    public static void addUser(User user) {
        sqlSession.insert("test.addUser",user);
        sqlSession.commit();   
        MybatisTool.resourceClosing();
    }
}

測試類:

package com.zhiwei.test;

import com.zhiwei.domain.User;
import com.zhiwei.service.BasicServiceImp;

public class BasicTest {

    public static void main(String[] args) {

        User user=BasicServiceImp.findUserById(1);
        System.out.println(user);
    }
}

結果:

DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.log4j.Log4jImpl' adapter.
DEBUG [main] - Class not found: org.jboss.vfs.VFS
DEBUG [main] - JBoss 6 VFS API is not available in this environment.
DEBUG [main] - Class not found: org.jboss.vfs.VirtualFile
DEBUG [main] - VFS implementation org.apache.ibatis.io.JBoss6VFS is not valid in this environment.
DEBUG [main] - Using VFS adapter org.apache.ibatis.io.DefaultVFS
DEBUG [main] - Find JAR URL: file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain
DEBUG [main] - Not a JAR: file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain
DEBUG [main] - Reader entry: User.class
DEBUG [main] - Reader entry: UserMapper.xml
DEBUG [main] - Listing file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain
DEBUG [main] - Find JAR URL: file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain/User.class
DEBUG [main] - Not a JAR: file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain/User.class
DEBUG [main] - Find JAR URL: file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain/UserMapper.xml
DEBUG [main] - Not a JAR: file:/D:/BaiduYunDownload/mybatis/bin/com/zhiwei/domain/UserMapper.xml
DEBUG [main] - Reader entry: <?xml version="1.0" encoding="utf-8"?>
DEBUG [main] - Checking to see if class com.zhiwei.domain.User matches criteria [is assignable to Object]
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Openning JDBC Connection
DEBUG [main] - Created connection 1211076369.
DEBUG [main] - ooo Using Connection [com.mysql.jdbc.JDBC4Connection@482f8f11]
DEBUG [main] - ==>  Preparing: select *from user where id=? 
DEBUG [main] - ==> Parameters: 1(Integer)
User [id=1, name=zhangsan, passwd=zhangsan]

結果分析:

從Log4J的控制檯日誌可以清楚看到,mybatis的本質就是JDBC操作,
對資料庫資料的操作就可以直接通過像呼叫普通方法一樣進行,非常方便

資料庫資料:
這裡寫圖片描述

缺陷:
mybatis使用比較靈活,如果每個人都按照自己的想法靈活構建,專案過大,mybatis的配置檔案將很難維護,因此實際專案mybatis開發過程中會有一些規範,後續列出

部落格中的程式碼都可正常執行,希望能夠給學習mybatis的同學提供幫助