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的同學提供幫助