Mybatis常用使用分析
Mybatis是一種常用的JDBC框架,能夠幫助我們更好地操作資料庫,通過mybatis配置好資料庫連線,我們只需要在相關的配置檔案中編寫業務需要的SQL語句,直接呼叫使用即可。其中的使用過程,框架已經幫我們都完成了封裝。
相對於hibernate來說,他們都是JDBC框架,mybatis是操作資料庫的過程層次化更明顯,並且符合面對介面程式設計的思路。mybatis更廣為開發者使用。本篇文章將介紹mybatis的基本使用方法和技巧。可供入門參考。
目錄:
一:執行簡介、配置檔案與搭建
二:增刪改查的使用、一對多等對應關係的使用
三:動態SQL標籤
四:註解方式
五:事務管理、快取、延遲載入、逆向工程、二級快取等相關概念的介紹
一:執行簡介、配置檔案與搭建
1. 執行簡介:
mybatis的執行主要分為三步:
首先,編寫mybatis的主配置檔案,mybatis-config.xml。配置資料庫連線、資料來源、資料類型別名掃描、SQL對映檔案掃描、事務管理等工作;
其次,編寫SQL對映檔案:xxxx.xml,編寫SQL;
最後,獲取sqlsessionfactory,獲取sqlsession,使用該物件呼叫相關方法呼叫SQL的id完成資料庫操作。
注: 可以使用面對介面的方式呼叫SQL,即sqlsession物件呼叫getMapper(UserMapper.class)方法,引數為mapper介面的類名。獲取一個UserMapper物件,呼叫該物件的方法即可呼叫SQL(要注意方法名與SQLID一直,SQL.xml檔案的namespace為mapper的類路徑)。
2. 建立工程,匯入jar包。
以eclipse為例,建立一個java project,並匯入相關jar包,主要使用一下兩個jar包。
3. src下建立編寫配置檔案,mybatis-config.xml
<typeAliases>為自動掃描的實體類,主要用作SQL對映檔案中的引數和返回值的別名使用。下面配置檔案使用的是自動掃描自動生成別名,例如,pojo包中的User類,會自動配置別名User。
<?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> <typeAliases> <package name="pojo"/> </typeAliases> <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://localhost:3306/test"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="mybatis/User.xml"/> <!--對映SQL.xml檔案--!> </mappers> </configuration>
還可以使用如下
<typeAliases>
<typeAlias alias="User" type="pojo.User"/>
</typeAliases>
的方式分別給每個類配置別名,此配置可以寫在總配置檔案中,也可以寫在每個SQL的對映檔案中。此種方式的別名可自行定義。
4. 呼叫
建立test類,完成呼叫SQL。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
User u2 = new User();
u2 = session.selectOne("getUserByid",5); //通過id為5查詢user物件。
//使用mapper的方式呼叫SQL
UserMapper mapper = session.getMapper(UserMapper.class);
User u1 = new User();
u1.setName("尚yan茹");
u1.setUserName("syr");
u1.setPassWord("lovelovelove");
mapper.addUser(u1);
二:增刪改查的使用、對應關係介紹
配置完成了mybatis的配置檔案,現在距離介紹增刪蓋查操作資料庫。有兩種方式完成,一種直接呼叫SQLID,一種使用mapper介面完成呼叫,這裡再增加中介紹兩種方式,其他只介紹mapper介面方式。
1. 新增User。
直接呼叫:執行,即可完成資料庫插入
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
User u1 = new User();
u1.setName("尚yan茹");
u1.setUserName("syr");
u1.setPassWord("lovelovelove");
session.insert("addUser");
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">
<typeAliases>
<typeAlias alias="uuu" type="pojo.User"/>
</typeAliases>
<mapper namespace="mapper.UserMapper">
<insert id="addUser" parameterType="pojo.User">
insert into user_1
(
username,
password,
name
)
values
(
#{userName},
#{passWord},
#{name}
)
</insert>
</mapper>
通過mapper介面,建立UserMapper介面,新增addUser方法。
package mapper;
public interface UserMapper {
void addUser(User user);
}
在測試類中:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User u1 = new User();
u1.setName("尚yan茹");
u1.setUserName("syr");
u1.setPassWord("lovelovelove");
mapper.addUser(u1);
2. 查詢:
//user.xml
<select id="userList" resultType="pojo.User">
select * from user_1
</select>
//mapper介面
List<User> userList();
//測試類
List<User> lu = mapper.userList();
for (User user : lu) {
System.out.println(user.getName());
}
3. 刪除、修改的方式如出一轍,不再贅述。此時介紹到這裡,相信小夥伴們已經知道如何使用mybatis來操作資料庫了。
mybatis是如何通過獲取mapper從而通過呼叫介面方法的方式完成SQL語句的呼叫的呢?
首先,測試類會讀取主配置檔案,載入資料庫連線,載入SQL對映檔案,測試類通過sqlsession物件的getMapper,載入我們已經建立的mapper介面,此時,mybatis會自動尋找該mapper介面中方法名,優先查詢所對應sql.xml的namespace為該介面的類路徑,然後將方法名與SQLID完成匹配注入,相當於實現了該介面方法。所以,呼叫介面方法時,會呼叫SQL語句。
4. 一對多的關係:
一個分類對應多個產品,該方式的主要實現過程為通過一個resultMap的對映關係,將查詢出來的資料通過別名分別對映到相關的實體類屬性中去。然後返回這個實體。
表結構中,每個產品都相應的有個cid為分類id,可以關聯分類表的id;
實體類中,分類類有一個集合屬性,為產品集合。
我們查詢一個分類,並獲取該分類的所有產品。
SQL.xml寫法如下:通過配置對映配合SQL語句查詢,最終將查詢結果顯示出來。
<resultMap type="Category" id="categoryBean">
<id column="cid" property="id" />
<result column="cname" property="name" />
<!-- 一對多的關係 -->
<!-- property: 指的是集合屬性的值, ofType:指的是集合中元素的型別 -->
<collection property="products" ofType="Product">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" />
</collection>
</resultMap>
<!-- 關聯查詢分類和產品表 -->
<select id="listCategory" resultMap="categoryBean">
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
</select>
5. 多對一,多個產品對應一個分類:
<resultMap type="Product" id="productBean">
<id column="pid" property="id" />
<result column="pname" property="name" />
<result column="price" property="price" />
<!-- 多對一的關係 -->
<!-- property: 指的是屬性名稱, javaType:指的是屬性的型別 -->
<association property="category" javaType="Category">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</association>
</resultMap>
<!-- 根據id查詢Product, 關聯將Orders查詢出來 -->
<select id="listProduct" resultMap="productBean">
select c.*, p.*, c.id 'cid', p.id 'pid', c.name 'cname', p.name 'pname' from category_ c left join product_ p on c.id = p.cid
</select>
三:動態SQL標籤
所謂動態SQL標籤,就是在sql.xml中通過一些特定的功能標籤,輔助完成一些複雜的SQL操作。常用的標籤有
if、where、forEach、set、trim、bind 等。使用方式分別介紹一下:
1. if使用if標籤可以用來在SQL中完成條件的過濾。如下,當user的name不為空時,也就是呼叫SQL時傳入了引數值,則執行對該name的模糊查詢,否則不滿足條件則查詢所有。 其中if中的test為固定用法,意為判斷條件。 concat為字串拼接用法。
<select id="listUser" resultType="User">
select * from user_
<if test="name!=null">
where name like concat('%',#{name},'%')
</if>
</select>
2. where、set、trim用法
where會自動會if進行判斷,如果都不滿足則不執行,如果有一個滿足則會去掉and和or關鍵字,如下;其實可以通過加上where1=1再結合if完成判斷,不必使用where。
<select id="listUser" resultType="User">
select * from user_
<where>
<if test="name!=null">
and name like concat('%',#{name},'%')
</if>
<if test="price!=null and price!=0">
and price > #{price}
</if>
</where>
</select>
set,用於update操作,類似where標籤,用法如下:
<update id="update" parameterType="User" >
update user
<set>
<if test="name != null">name=#{name},</if>
<if test="price != null">price=#{price}</if>
</set>
where id=#{id}
</update>
trim標籤,可完成需要的定製功能。如下:prefix代表字首詞、suffixOverrides代表分隔符(trim會自動根據條件把分隔符去除掉多餘的 分隔符)。
<update id="update" parameterType="User" >
update user
<trim prefix="SET" suffixOverrides=",">
<if test="name != null">name=#{name},</if>
<if test="price != null">price=#{price}</if>
</trim>
where id=#{id}
</update>
3.forEach標籤,遍歷迴圈。
通常用在oracle中的in用法、批量刪除新增等操作中,可以將引數傳遞進來的集合型別進行遍歷。如下;
item為遍歷是每個元素的名、index為遍歷的位置、collection有三個值:list、array{陣列型別}、map,這裡為list,代表這是一個List集合、
open為開始符號(,close為結束符號)、separator :分隔符,表示遍歷時每個元素之間以什麼分隔。
<select id="list" resultType="User">
SELECT * FROM user
WHERE ID in
<foreach item="item" index="index" collection="list"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
四:註解方式
通過寫註解,就可以免去寫SQL.xml對映檔案了,不過一般還是用xml檔案的多,使用註解雖然省了一步,但對於複雜的SQL查詢並不方便。下面介紹如何使用註解。
1. mapper介面中新增SQL註解:
public interface UserMapper {
@Insert(" insert into user ( name ) values (#{name}) ")
public int add(Category category);
@Delete(" delete from user where id= #{id} ")
public void delete(int id);
@Update("update user set name=#{name} where id=#{id} ")
public int update(Category category);
@Select(" select * from user ")
public List<Category> list();
}
2. 在mybatis-config.xml中宣告該對映類。
<configuration>
<mappers>
<mapper resource="User.xml"/>
<mapper class="mapper.UserMapper"/>
</mappers>
</configuration>
3. 編寫測試類:至此完成。
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User u= mapper.get(8);
u.setName("修改了的user名字");
mapper.update(u);
session.commit();
session.close();
五:事務管理、快取、延遲載入等相關概念的介紹
1. 事務管理:
在mybatis-config.xml配置檔案中,配置
<transactionManager type="JDBC"/> 代表JDBC開啟事務管理。
開啟後,在測試類中提交sqlsession.commit()之後,提交事務,此時如果提交的資料庫操作中有一個操作失敗了,則所有的操作均不會成功,只有都成功才會生效。這就代表著事務啟動成功。
2. 延遲載入:
mybatis預設是積極載入的,即沒有延遲載入。查詢一個物件時,如果該物件中有集合屬性並且做了對映,則查詢該物件時集合屬性也會一起被查詢出來。
如何設定延遲載入:在mybatis-config.xml中新增延遲載入設定:
<settings>
<!-- 開啟延遲載入的開關 -->
<setting name="lazyLoadingEnabled" value="true" />
<!-- 將積極載入改為訊息載入即按需載入 -->
<setting name="aggressiveLazyLoading" value="false"/>
</settings>
3. 二級快取與一級快取
mybatis的二級快取與hibernate的二級快取基本一致,一級快取查詢過後的資料時將快取存在 sqlsession中的,二級快取的快取是存在sqlsessionFactory中的。
4. mybatis的逆向工程:
可以自動生成程式碼的jar包工具類。
新增jar包:mybatis-generator-core-1.3.5.jar
src下新建配置檔案:generatorConfig.xml,內容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<!--資料庫驅動-->
<!--
如果IDE(eclipse或者idea) 專案裡匯入了jar包,那麼就不需要配置了jar包的絕對路徑了
<classPathEntry location="e:/project/mybatis/lib/mysql-connector-java-5.0.8-bin.jar"/>
-->
<context id="DB2Tables" targetRuntime="MyBatis3">
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="false"/>
</commentGenerator>
<!--資料庫連結地址賬號密碼-->
<jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost/test" userId="root" password="root">
</jdbcConnection>
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--生成Model類存放位置-->
<javaModelGenerator targetPackage="pojo" targetProject="src">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!--生成對映檔案存放位置-->
<sqlMapGenerator targetPackage="mybatis" targetProject="src">
<property name="enableSubPackages" value="true"/>
</sqlMapGenerator>
<!--生成Dao類存放位置-->
<javaClientGenerator type="XMLMAPPER" targetPackage="mapper" targetProject="src">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!--生成對應表及類名-->
<table tableName="category_" domainObjectName="Category" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="true" selectByExampleQueryId="false">
<property name="my.isgen.usekeys" value="true"/>
<generatedKey column="id" sqlStatement="JDBC"/>
</table>
</context>
</generatorConfiguration>
自動生成檔案類:
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
InputStream is= TestMybatisGenerator.class.getClassLoader().getResource("generatorConfig.xml").openStream();
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(is);
is.close();
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
System.out.println("生成程式碼成功,重新整理專案,檢視檔案");
}
執行之後,相應程式碼自動生成,呼叫方法就可完成資料庫操作了。
以上就是mybatis的基本介紹,關於mybatis的使用更多的是結合其他框架技術完成專案的搭建。