關於Mybatis
Mybatis是Apache項目的一個開源框架,前名爲ibatis,2010年更名爲mybatis.它是一個輕量級的持久層框架。之所以說它是一個輕量級的持久層框架主要是它區別於其他持久層框架比如(Hibernate、EJB)等,它強調的是使用SQL,而其它框架需要自定義查詢語言,比如HQL、EJB QL等。
設計理念
- 簡單:其被廣泛的認爲是可用的最簡單的持久層框架之一
- 快速開發:其理念是盡一切可能,以方便超快速開發
- 可移植性:其幾乎可以應用於任何語言或平臺,比如java、Ruby、C#、.Net等
- 獨立性: 其提供獨立於數據庫的接口和API,幫助應用程序其餘部分獨立於任何持久性相關的資源
- 開源:其實自由和開放源碼項目
優點
- 支持存儲過程:SQL封裝以存儲過程的形式,使業務邏輯保持在數據庫之外,應用程序更易於部署和測試,更便於移植
- 支持內嵌的SQL:預編譯器不是必需的,並有完全訪問所有的SQL語句的特性
- 支持動態SQL: 提供基於參數動態生成SQL查詢
- 支持O / RM:支持許多相同的功能作爲一個O / RM工具,如延遲加載,連接抓取,緩存,運行時代碼生成和繼承
配置 增刪改查
準備
- 下載iBATIS的最新版本 下載iBATIS.
- 解壓下載的文件,從包中提取.jar文件並將其保存在相應的lib目錄下。
數據庫
創建數據庫、表等。
配置文件
在項目資源文件的根目錄下創建SqlMapConfig.xml,可以從下載的mybatis資源文件中找到相關的示例將配置文件拷出修改即可。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMapConfig
PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings useStatementNamespaces="true"/>
<transactionManager type="JDBC">
<dataSource type="SIMPLE">
<property name="JDBC.Driver"
value="com.mysql.jdbc.Driver"/>
<property name="JDBC.ConnectionURL"
value="jdbc:mysql://localhost:3306/testdb"/>
<property name="JDBC.Username" value="root"/>
<property name="JDBC.Password" value="root"/>
</dataSource>
</transactionManager>
<sqlMap resource="Employee.xml"/>
</sqlMapConfig>
在對應的Employee類的相同目錄下創建對應的映射文件Employee.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE sqlMap
PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN"
"http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="Employee">
<insert id="insert" parameterClass="Employee">
insert into EMPLOYEE(first_name, last_name, salary)
values (#first_name#, #last_name#, #salary#)
<selectKey resultClass="int" keyProperty="id">
select last_insert_id() as id
</selectKey>
</insert>
</sqlMap>
測試插入
import com.ibatis.common.resources.Resources;
import com.ibatis.sqlmap.client.SqlMapClient;
import com.ibatis.sqlmap.client.SqlMapClientBuilder;
import java.io.*;
import java.sql.SQLException;
import java.util.*;
public class IbatisInsert{
public static void main(String[] args)
throws IOException,SQLException{
Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);
/* This would insert one record in Employee table. */
System.out.println("Going to insert record.....");
Employee em = new Employee("Zara", "Ali", 5000);
smc.insert("Employee.insert", em);
System.out.println("Record Inserted Successfully ");
}
}
測試讀取
在Employee.xml中加入
<select id="getAll" resultClass="Employee">
SELECT * FROM EMPLOYEE
</select>
Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);
/* This would read all records from the Employee table. */
System.out.println("Going to read records.....");
List <Employee> ems = (List<Employee>)
smc.queryForList("Employee.getAll", null);
Employee em = null;
for (Employee e : ems) {
System.out.print(" " + e.getId());
System.out.print(" " + e.getFirstName());
System.out.print(" " + e.getLastName());
System.out.print(" " + e.getSalary());
em = e;
System.out.println("");
}
測試更新
在Employee.xml中加入
<update id="update" parameterClass="Employee">
UPDATE EMPLOYEE
SET first_name = #first_name#
WHERE id = #id#
</update>
Employee rec = new Employee();
rec.setId(1);
rec.setFirstName( "Roma");
smc.update("Employee.update", rec );
測試刪除
<delete id="delete" parameterClass="int">
DELETE FROM EMPLOYEE
WHERE id = #id#
</delete>
int id = 1;
smc.delete("Employee.delete", id );
存儲過程調用
我們已經在MySQL下有EMPLOYEE表:
CREATE TABLE EMPLOYEE (
id INT NOT NULL auto_increment,
first_name VARCHAR(20) default NULL,
last_name VARCHAR(20) default NULL,
salary INT default NULL,
PRIMARY KEY (id)
);
讓我們在MySQL數據庫中創建以下存儲過程。
DELIMITER $$
DROP PROCEDURE IF EXISTS `testdb`.`getEmp` $$
CREATE PROCEDURE `testdb`.`getEmp`
(IN empid INT)
BEGIN
SELECT * FROM EMPLOYEE
WHERE ID = empid;
END $$
DELIMITER;
在這裏,我們將修改Employee.xml文件介紹<procedure></procedure>和<parameterMap></parameterMap>標記。這裏<procedure></procedure>標籤將有一個id,我們會用我們的應用程序來調用存儲過程。
Employee.xml配置文件中:
<!-- To call stored procedure. -->
<procedure id="getEmpInfo" resultClass="Employee"
parameterMap="getEmpInfoCall">
{ call getEmp( #acctID# ) }
</procedure>
<parameterMap id="getEmpInfoCall" class="map">
<parameter property="acctID" jdbcType="INT"
javaType="java.lang.Integer" mode="IN"/>
</parameterMap>
int id = 1;
System.out.println("Going to read employee name.....");
Employee e = (Employee)smc.queryForObject
("Employee.getEmpInfo", id);
動態SQL
用動態查詢是mybatis一個非常強大的功能。有時你需要根據你的參數對象的狀態來改變where字句。在這種情況下的mybtais提供了一組可以映射語句中使用,以提高SQL語句的重用性和靈活性的動態SQL標籤。
所有的邏輯是使用一些額外的標籤放在:XML文件。下面是一個例子,其中的SELECT語句將努力在兩個方面:
如果想傳遞一個ID,然後它會返回所有與該ID的記錄,否則,將返回所有僱員ID爲NULL的記錄。
<sqlMap namespace="Employee">
<select id="findByID" resultClass="Employee">
SELECT * FROM EMPLOYEE
<dynamic prepend="WHERE ">
<isNull property="id">
id IS NULL
</isNull>
<isNotNull property="id">
id = #id#
</isNotNull>
</dynamic>
</select>
</sqlMap>
MYBATIS OGNL 表達式
提供了強大的基於OGNL的表達式來消除其他元素。這個只做簡單介紹,需要的時候再查相關資料深入研究。
- if 語句
- choose, when, otherwise 語句
- where 語句
- foreach 語句
調試Log4j
假設你要使用Log4J,這是最好用的日誌記錄。繼續操作之前,需要交叉檢查以下幾點:
Log4J JAR 文件 (log4j-{version}.jar) 應在CLASSPATH中。
必須在CLASSPATH中提供log4j.properties。
下面是一個log4j.properties文件。請注意,某些行被註釋掉了。你可以取消他們,如果你需要額外的調試信息。
# Global logging configuration
log4j.rootLogger=ERROR, stdout
log4j.logger.com.ibatis=DEBUG
# shows SQL of prepared statements
#log4j.logger.java.sql.Connection=DEBUG
# shows parameters inserted into prepared statements
#log4j.logger.java.sql.PreparedStatement=DEBUG
# shows query results
#log4j.logger.java.sql.ResultSet=DEBUG
#log4j.logger.java.sql.Statement=DEBUG
# Console output
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
部分示例代碼
public class IbatisUpdate{
static Logger log = Logger.getLogger(
IbatisUpdate.class.getName());
public static void main(String[] args)
throws IOException,SQLException{
Reader rd = Resources.getResourceAsReader("SqlMapConfig.xml");
SqlMapClient smc = SqlMapClientBuilder.buildSqlMapClient(rd);
/* This would insert one record in Employee table. */
log.info("Going to update record.....");
log.debug("Going to read records.....");
Mybatis和Hibernate區別
mybatis和Hibernate之間有着較大的差異,但兩者解決方案很好,因爲他們有特定的領域。我個人建議使用iBATIS的,如果:
- 你想創建自己的SQL,並願意維持他們
- 你的環境是由關係數據模型驅動的
- 你的項目工作有複雜架構的
簡單地要使用Hibernate,如果:
- 你的環境是由對象模型驅動的,並希望自動生成的SQL
要計算的一些區別:
mybatis:
- 簡單
- 更快的開發時間
- 靈活
- 封裝尺寸更小
Hibernate:
- 爲你生成SQL,這意味着你不用花時間在SQL上。
- 提供了許多更先進的高速緩存
- 高可擴展性
另一個區別是,mybatis利用SQL語句可能是依賴數據庫,使用Hibernate的HQL是相對獨立於數據庫,它是更容易改變數據庫。
Hibernate映射的Java作爲POJO對象,mybatis將ResultSet映射,從JDBC API給出POJO OBJETS的數據庫表。
如果您使用存儲過程,那麼在Hibernate中可以做到這一點,但它在mybatis比較有點困難。作爲一種替代的解決方案mybatis的映射結果集對象,所以沒必要去關心表結構。這非常適用於存儲過程,非常適用於報表應用程序等
最後,Hibernate和mybatis的都是開源的對象關係映射(ORM)在同行業中可用的工具。使用這些工具的取決於你。Hibernate和mybatis兩者也有來自Spring框架的良好支持,以便它不應該是一個問題,選擇其中之一。