关于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框架的良好支持,以便它不应该是一个问题,选择其中之一。