這篇文章我們學(xué)習(xí)一下Mybatis,希望大家提出寶貴的建議。
一:什么是Mybatis?
MyBatis 是一個基于Java的持久層框架。它提供的持久層框架包括SQL Maps和Data Access Objects(DAO)。
MyBatis 是支持普通 SQL查詢,存儲過程和高級映射的優(yōu)秀持久層框架。MyBatis 消除了幾乎所有的JDBC代碼和參數(shù)的手工設(shè)置以及結(jié)果集的檢索。MyBatis 使用簡單的 XML或注解用于配置和原始映射,將接口和 Java 的POJO(Plain Old Java Objects,普通的 Java對象)映射成數(shù)據(jù)庫中的記錄。
每個MyBatis應(yīng)用程序主要都是使用SqlSessionFactory實例的,一個SqlSessionFactory實例可以通過SqlSessionFactoryBuilder獲得。SqlSessionFactoryBuilder從一個xml配置文件或者一個預(yù)定義的配置類的實例獲得配置信息。
二:Mybatis的運行流程與原理?
我更喜歡用自己的圖來表達(dá)Mybatis的整個的執(zhí)行流程。如下圖所示:
a.流程圖

b.原理詳解:
MyBatis應(yīng)用程序根據(jù)XML配置文件創(chuàng)建SqlSessionFactory,
SqlSessionFactory在根據(jù)配置,配置來源于兩個地方,一處是配置文件,一處是Java代碼的注解,獲取一個SqlSession。SqlSession包含了執(zhí)行sql所需要的所有方法,可以通過SqlSession實例直接運行映射的sql語句,完成對數(shù)據(jù)的增刪改查和事務(wù)提交等,用完之后關(guān)閉SqlSession。
c.mybatis配置詳解
1、SqlMapConfig.xml,此文件作為mybatis的全局配置文件,配置了mybatis的運行環(huán)境等信息。
mapper.xml文件即sql映射文件,文件中配置了操作數(shù)據(jù)庫的sql語句。此文件需要在SqlMapConfig.xml中加載。
2、 通過mybatis環(huán)境等配置信息構(gòu)造SqlSessionFactory即會話工廠
3、 由會話工廠創(chuàng)建sqlSession即會話,操作數(shù)據(jù)庫需要通過sqlSession進(jìn)行。
4、 mybatis底層自定義了Executor執(zhí)行器接口操作數(shù)據(jù)庫,Executor接口有兩個實現(xiàn),一個是基本執(zhí)行器、一個是緩存執(zhí)行器。
5、 Mapped Statement也是mybatis一個底層封裝對象,它包裝了mybatis配置信息及sql映射信息等。mapper.xml文件中一個sql對應(yīng)一個Mapped Statement對象,sql的id即是Mapped statement的id。
6、 Mapped Statement對sql執(zhí)行輸入?yún)?shù)進(jìn)行定義,包括HashMap、基本類型、pojo,Executor通過 Mapped Statement在執(zhí)行sql前將輸入的java對象映射至sql中,輸入?yún)?shù)映射就是jdbc編程中對preparedStatement設(shè)置參數(shù)。
7、 Mapped Statement對sql執(zhí)行輸出結(jié)果進(jìn)行定義,包括HashMap、基本類型、pojo,Executor通過 Mapped Statement在執(zhí)行sql后將輸出結(jié)果映射至java對象中,輸出結(jié)果映射過程相當(dāng)于jdbc編程中對結(jié)果的解析處理過程。
8、Sqlsession:對應(yīng)著一次數(shù)據(jù)庫會話。由于數(shù)據(jù)庫回話不是永久的,因此Sqlsession的生命周期也不應(yīng)該是永久的,相反,在你每次訪問數(shù)據(jù)庫時都需要創(chuàng)建它(當(dāng)然并不是說在Sqlsession里只能執(zhí)行一次sql,你可以執(zhí)行多次,當(dāng)一旦關(guān)閉了Sqlsession就需要重新創(chuàng)建它)。創(chuàng)建Sqlsession的地方只有一個,那就是SqlsessionFactory的openSession方法。
三:案例演示
例1:
1、創(chuàng)建User.java
private Integer id;//主鍵
private String username;//用戶名
private String password;//密碼
private String email;//郵箱
private String mobile;//手機(jī)號
private Integer age;//年齡
private String birth;//出生日期
(set,get 方法省略...........)
2、SqlMapConfig.xml
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/test" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>
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">
<mapper namespace="User">
<!-- 按id號查詢用戶信息 -->
<!--
id就是statement的id
parameterType:輸入?yún)?shù)的數(shù)據(jù)類型
resultType:輸出參數(shù)的類型
#{}寫什么。。如果是基本類型,可以統(tǒng)一用value
-->
<select id="queryById" parameterType="int" resultType="com.aiyin.mybatis01.entity.User">
select * from user where id=#{value}
</select>
<!-- 查詢名字有“五”字的用戶信息 -->
<select id="queryByUserName" parameterType="java.lang.String" resultType="com.aiyin.mybatis01.entity.User">
SELECT * FROM USER WHERE username like '%${value}%'
</select>
</mapper>
4、Test.java
public class TestMyBatis {
@Test
public void queryById() {
// 使用類加載器加載mybatis的配置文件(它也加載關(guān)聯(lián)的映射文件)
InputStream is = TestMyBatis.class.getClassLoader()
.getResourceAsStream("SqlMapConfig.xml");
// 構(gòu)建sqlSession的工廠SqlSessionFactory
SqlSessionFactoryBuilder sessionFactory = new SqlSessionFactoryBuilder();
SqlSessionFactory sf = sessionFactory.build(is);
// 先獲取SqlSession
SqlSession session = sf.openSession();
// 執(zhí)行查詢返回一個唯一user對象的sql
/**
* 映射sql的標(biāo)識字符串, User是User.xml文件中mapper標(biāo)簽的namespace屬性的值,
* queryById是select標(biāo)簽的id屬性值,通過select標(biāo)簽的id屬性值就可以找到要執(zhí)行的SQL
*/
User user = session.selectOne("User.queryById", 1);
System.out.println(user);
}
@Test
public void queryByUserName() {
// 使用類加載器加載mybatis的配置文件(它也加載關(guān)聯(lián)的映射文件)
InputStream is = TestMyBatis.class.getClassLoader()
.getResourceAsStream("SqlMapConfig.xml");
// 構(gòu)建sqlSession的工廠
SqlSessionFactoryBuilder sessionFactory = new SqlSessionFactoryBuilder();
SqlSessionFactory sf = sessionFactory.build(is);
// 先獲取SqlSession
SqlSession session = sf.openSession();
// 執(zhí)行查詢返回一個唯一user對象的sql
/**
* 映射sql的標(biāo)識字符串, User是User.xml文件中mapper標(biāo)簽的namespace屬性的值,
* queryById是select標(biāo)簽的id屬性值,通過select標(biāo)簽的id屬性值就可以找到要執(zhí)行的SQL
*/
List<User> userList = session.selectList("User.queryByUserName","劉");
System.out.println(userList);
}
queryById()方法即可查詢出數(shù)據(jù)庫User表中Id為1 的用戶信息。
queryByUserName()方法查詢出User表中姓名含有“劉”字的所有用戶信息。
一個小屬性
typeAiases(類型別名)
<!--
批量定義別名
name是全路徑名
別名必須是類名(可以首字母小寫)
-->
<!--<typeAlias type="com.aiyin.mybatis01.entity.User" alias="user"/> -->
批量指定別名 <package name="com.aiyin.mybatis.entity"/>
</typeAliases>
resultType="com.aiyin.mybatis01.entity.User"------>resultType="user"
例二:拓展帶入if where等標(biāo)簽
<sql id="queryAllInfo">
select id,username,password,email,mobile,age,birth from user
</sql>
<!-- 查詢年齡大于20,名字有'強(qiáng)'字的用戶信息
ongl找到對應(yīng)的User類中的屬性 -->
<select id="queryByAge" parameterType="user" resultType="user">
<include refid="queryAllInfo"></include>
where age>#{age} and username like '%${username}%'
</select>
@Test
public void queryByAge(){
SqlSession sqlSession=TestMyBatis2.newInstance();
User user=new User();
user.setAge(25);
user.setUsername("強(qiáng)");
List<Regist> list= sqlSession.selectList("User.queryByAge",user);
log.debug(list);
}
下次詳解:基于Mapping映射的Dao開發(fā)