更新時間:2021-07-16 16:32:26 來源:動力節(jié)點 瀏覽1125次
MyBatis本是apache的一個開源項目iBatis,2010年這個項目由apache software foundation遷移到了google code,并且改名為MyBatis。2013年11月遷移到Github。
MyBatis是支持定制化SQL、存儲過程以及高級映射的優(yōu)秀的持久層框架。MyBatis避免了幾乎所有的JDBC代碼和手工設(shè)置參數(shù)以及抽取結(jié)果集。MyBatis使用簡單的XML或注解來配置和映射基本體,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數(shù)據(jù)庫中的記錄。簡單來說,mybatis就是一個持久層的框架,mybatis讓程序?qū)⒅饕Ψ旁趕ql上,通過mybatis提供的映射方式,自由靈活生成滿足需要的sql語句,mybatis可以將向preparedStatement中的輸入?yún)?shù)自動進行輸入映射,將查詢結(jié)果集靈活映射成java對象。
1.加載配置文件:配置來源于兩個地方,一個是配置文件,一個是java代碼的注解,將sql的配置信息加載成為一個個MappedStatement對象(包括了傳入?yún)?shù)映射配置、執(zhí)行的SQL語句、結(jié)果映射配置),存儲在內(nèi)存中。
2.SQL解析:當(dāng)api接口層接收到調(diào)用請求時,會接收到傳入slq的id和傳入對象(可以是map或者基本數(shù)據(jù)類型),mybatis會根據(jù)sql的id找到對應(yīng)的MappedStatement,然后根據(jù)傳入?yún)?shù)對象對MappedStatement進行解析,解析后可以得到最終要執(zhí)行的sql語句和參數(shù)。
3.SQL執(zhí)行:將最終得到的SQL和參數(shù)拿到數(shù)據(jù)庫進行執(zhí)行,得到操作數(shù)據(jù)庫的結(jié)果。
4.結(jié)果映射:將操作數(shù)據(jù)庫的結(jié)果按照映射的配置進行轉(zhuǎn)換,可以轉(zhuǎn)換成HashMap、JavaBean或者基本數(shù)據(jù)類型,并將最終結(jié)果返回。
接著,小編結(jié)合demo來具體介紹一下,需求如下:
根據(jù)用戶id查詢用戶信息;
根據(jù)用戶名稱模糊查詢用戶信息;
添加、刪除、更新用戶。
第一步、建立各種包和類,工程目錄如下所示:
第二步、編寫SqlMapConfig.xml中的內(nèi)容,配置mybatis的運行環(huán)境,數(shù)據(jù)源,事務(wù)等。代碼如下所示:
<span style="font-family:Comic Sans MS;font-size:18px;"><?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>
<!-- 將spring整合后environments配置將廢除 -->
<environments default="developent">
<!-- 使用jdbc事務(wù)管理,事務(wù)控制由mybatis -->
<transactionManager type="JDBC"/>
<!-- 數(shù)據(jù)庫連接池,由mybatis管理 -->
<dataSource type="POLLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environments>
<!-- 加載 映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>
</configuration>
</span>
第三步、編寫User.java中的內(nèi)容,如下所示:
<span style="font-family:Comic Sans MS;font-size:18px;">package cn.itcast.mybatis.po;
import java.util.Date;
/**
*
* <p>Title: User</p>
* <p>Description:用戶po </p>
* @author 丁國華
* @date 2016年7月31日 15:39:04
* @version 1.0
*/
public class User {
//屬性名和數(shù)據(jù)庫表的字段對應(yīng)
private int id;
private String username;// 用戶姓名
private String sex;// 性別
private Date birthday;// 生日
private String address;// 地址
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex
+ ", birthday=" + birthday + ", address=" + address + "]";
}
}
</span>
第四步、實現(xiàn)增刪改查的功能,首先編寫User.xml中的內(nèi)容,如下所示:
<span style="font-family:Comic Sans MS;font-size:18px;"><?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進行分類化管理,理解sql隔離
注意:使用mapper代理方法開發(fā),namespace有特殊重要的作用-->
<mapper namespace="test">
<!-- 在 映射文件中配置很多sql語句 -->
<!-- 需求:通過id查詢用戶表的記錄 -->
<!-- 通過 select執(zhí)行數(shù)據(jù)庫查詢
id:標(biāo)識 映射文件中的 sql
將sql語句封裝到mappedStatement對象中,所以將id稱為statement的id
parameterType:指定輸入 參數(shù)的類型,這里指定int型
#{}表示一個占位符號
#{id}:其中的id表示接收輸入 的參數(shù),參數(shù)名稱就是id,如果輸入 參數(shù)是簡單類型,#{}中的參數(shù)名可以任意,可以value或其它名稱
resultType:指定sql輸出結(jié)果 的所映射的java對象類型,select指定resultType表示將單條記錄映射成的java對象。
-->
<select id="findUserById" parameterType="int" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE id=#{value}
</select>
<!-- 根據(jù)用戶名稱模糊查詢用戶信息,可能返回多條
resultType:指定就是單挑記錄所映射的java對象類型
${}:表示拼接sql串,將接收到參數(shù)的內(nèi)容不加任何修飾拼接到sql中。
使用${}拼接sql,引起sql注入
${value}:接收輸入?yún)?shù)的內(nèi)容,如果傳入類型是簡單類型,${}中只能使用value -->
<select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User">
SELECT * FROM USER WHERE username LIKE '%${value}%'
</select>
<!-- 添加用戶
parameterType:指定輸入?yún)?shù)類型是pojo(包括用戶信息)
#{}中指定pojo的屬性名,接收到pojo對象的屬性值,mybatis通過OGNL獲取對象的屬性值 -->
<insert id="insertUser" parameterType="cn.itcast.mybatis.po.User">
<!-- 將插入數(shù)據(jù)的主鍵返回,返回到user對象中
SELECT LAST_INSERT_ID():得到剛剛insert進去記錄的主鍵值,只適用于自增主鍵
keyProperty:將查詢得到主鍵值設(shè)置到parameterType指定的對象的那個屬性
order:SELECT LAST_INSERT_ID()執(zhí)行順序,相對于insert語句來說她的執(zhí)行順序
resultType:指定SELECT LAST_INSERT_ID()的結(jié)果類型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
SELECT LAST_INSER_ID()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
<!-- 使用mysql的uuid()函數(shù)生成主鍵
執(zhí)行過程,首先通過uuid得到主鍵,將主鍵設(shè)置到user對象的id屬性中
其次,在insert執(zhí)行的時候,從user對象中,取出id屬性值 -->
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
SELECT uuid()
</selectKey>
insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address});
</insert>
<!-- 刪除用戶
根據(jù)id刪除用戶,需要輸入id值 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id=#{id}
</delete>
<!-- 根據(jù)id更新用戶
分析:
需要傳入用戶的id
需要傳入用戶的更新信息
parameterType指定user對象,包括 id和更新信息,注意:id必須存在
#{id}:從輸入 user對象中獲取id屬性值
-->
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address}
where id=#{id}
</update>
</mapper></span>
第五步、編寫具體的方法,如下所示:
<span style="font-family:Comic Sans MS;font-size:18px;">package cn.itcast.mybatis.first;
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.Test;
import cn.itcast.mybatis.po.User;
public class MybatisFirst {
// 根據(jù)id查詢用戶信息,得到一條記錄結(jié)果
@Test
public void findUserByIdTest() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創(chuàng)建會話工廠,傳入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 通過工廠得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 通過SqlSession操作數(shù)據(jù)庫
// 第一個參數(shù):映射文件中statement的id,等于=namespace+"."+statement的id
// 第二個參數(shù):指定和映射文件中所匹配的parameterType類型的參數(shù)
// sqlSession.selectOne結(jié)果 是與映射文件中所匹配的resultType類型的對象
// selectOne查詢出一條記錄
User user = sqlSession.selectOne("test.findUserById", 1);
System.out.println(user);
// 釋放資源
sqlSession.close();
}
//根據(jù)用戶名稱模糊查詢用戶列表
@Test
public void findUserByNameTest() throws IOException{
//mybatis配置文件
String resource ="SqlMapConfig.xml";
//得到配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//創(chuàng)建會話工廠,傳入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通過工廠得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//List中的user和映射文件中德resultType所指定的類型一致
List<User> list = sqlSession.selectList("test.findUserByName","小明");
System.out.println(list);
sqlSession.close();
}
public void insertUserTest() throws IOException{
//mybatis配置文件
String resource ="SqlMapConfig";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//創(chuàng)建會話工廠,傳入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通過工廠得到sqlsession
SqlSession sqlSession = sqlSessionFactory.openSession();
//插入用戶對象
User user = new User();
user.setUsername("丁國華");
user.setBirthday(new Date());
user.setSex("1");
user.setAddress("安徽合肥");
//list中的user和映射文件中的resultType所指定的類型一直
sqlSession.insert("test.insertUser",user);
//提交事物
sqlSession.commit();
//關(guān)閉會話
sqlSession.close();
}
//根據(jù)id刪除用戶信息
@Test
public void deleteUserTest() throws IOException{
//mybatis配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//創(chuàng)建工廠,傳入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通過工廠得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
//傳入id刪除用戶
sqlSession.delete("test.deleteUser",39);
//提交事物
sqlSession.commit();
//關(guān)閉會話
sqlSession.close();
}
// 更新用戶信息
@Test
public void updateUserTest() throws IOException {
// mybatis配置文件
String resource = "SqlMapConfig.xml";
// 得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
// 創(chuàng)建會話工廠,傳入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
// 通過工廠得到SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 更新用戶信息
User user = new User();
//必須設(shè)置id
user.setId(41);
user.setUsername("丁國華");
user.setBirthday(new Date());
user.setSex("2");
user.setAddress("安徽合肥");
sqlSession.update("test.updateUser", user);
// 提交事務(wù)
sqlSession.commit();
// 關(guān)閉會話
sqlSession.close();
}
}
</span>
優(yōu)點:
1.易于上手和掌握。
2.sql寫在xml里,便于統(tǒng)一管理和優(yōu)化。
3.解除sql與程序代碼的耦合。
4.提供映射標(biāo)簽,支持對象與數(shù)據(jù)庫的orm字段關(guān)系映射
5.提供對象關(guān)系映射標(biāo)簽,支持對象關(guān)系組建維護
6.提供xml標(biāo)簽,支持編寫動態(tài)sql。
1.sql工作量很大,尤其是字段多、關(guān)聯(lián)表多時,更是如此。
2.sql依賴于數(shù)據(jù)庫,導(dǎo)致數(shù)據(jù)庫移植性差。
3.由于xml里標(biāo)簽id必須唯一,導(dǎo)致DAO中方法不支持方法重載。
4.DAO層過于簡單,對象組裝的工作量較大。
5.緩存使用不當(dāng),容易產(chǎn)生臟數(shù)據(jù)。
相同點:Hibernate和mybatis都可以是通過SessionFactoryBuilder由xml配置文件生成SessionFactory,然后由SessionFactroy生成Session,最后由Session來開啟執(zhí)行事物和SQL語句,其中SessionFactoryBuider、SessionFactory、Session的生命周期都是差不多的。
不同點:
mybatis:小巧、方便、高效、簡單、直接、半自動;
hibernate:強大、方便、高效、復(fù)雜、繞彎子、全自動;
mybatis:
1.入門簡單,即學(xué)即用,提供了數(shù)據(jù)庫查詢的自動對象綁定功能,而且延續(xù)了很多的SQL使用經(jīng)驗,對于沒有那么高的對象模型要求的項目來說,堪稱perfect。
2.可以進行更為細致的SQL優(yōu)化,可以減少查詢字段。
3.缺點就是框架還是比較簡陋,功能尚有缺失,雖然簡化了數(shù)據(jù)綁定代碼,但是整個底層數(shù)據(jù)庫查詢實際還是要自己寫的,工作量也比較大,而且不太容易適應(yīng)快速數(shù)據(jù)庫修改。
4.二級緩存機制不佳。
以上就是動力節(jié)點小編介紹的"Mybatis的原理入門教程",希望對大家有幫助,想了解更多可查看Mybatis視頻教程。動力節(jié)點在線學(xué)習(xí)教程,針對沒有任何Java基礎(chǔ)的讀者學(xué)習(xí),讓你從入門到精通,主要介紹了一些Java基礎(chǔ)的核心知識,讓同學(xué)們更好更方便的學(xué)習(xí)和了解Java編程,感興趣的同學(xué)可以關(guān)注一下。
初級 202925
初級 203221
初級 202629
初級 203743