MyBatis 本是apache的一個開源項目iBatis, 2010年這個項目由apache software foundation 遷移到了google code,並且改名為MyBatis 。2013年11月遷移到Github。iBATIS一詞來源於“internet”和“abatis”的組合,是一個基於Java的持久層框架。
MyBatis是支持普通SQL查詢,存儲過程和高級映射的優秀持久層框架。MyBatis消除了幾乎所有的JDBC代碼和參數的手工設置以及對結果集的檢索封裝。MyBatis可以使用簡單的XML或注解用於配置和原始映射,將接口和Java的POJO(Plain Old Java Objects,普通的Java對象)映射成數據庫中的記錄。
首先需要加入需要的jar包,構建Spring環境請參考:Spring學習之第一個hello world程序。這裡我們需要加入mybatis包和MySQL驅動包,使用IDEA環境來開發程序,最後工程加入的包如下圖所示:

然後需要在test數據庫中新建測試表user,sql語句如下所示:
create table users (
id int primary key auto_increment,
name varchar(20),
age int
);
insert into users (name, age) values('Tom', 12);
insert into users (name, age) values('Jack', 11);
public class User {
private int id;
private String name;
private int age;
public User() { }
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
mybatisConfig.xml文件,該文件是在src目錄下新建的。
<?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">
<!-- development:開發環境 work:工作模式 -->
<environment id="development">
<transactionManager type="JDBC" />
<!-- 數據庫連接方式 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://192.168.1.150/test" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<!-- 注冊表映射文件 -->
<mappers>
<mapper resource="com/mybatis/userMapper.xml"/>
</mappers>
</configuration>
userMapper.xml文件,該配置文件在com.mybatis包下,user表對應的實體類User也在com.mybatis包下。
<?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="com.mybatis.userMapper">
<!-- 根據id查詢一個User對象 -->
<select id="getUser" parameterType="int" resultType="com.mybatis.User">
select * from users where id=#{id}
</select>
<select id="getUserAll" resultType="com.mybatis.User">
select * from users
</select>
<!-- 插入一個User對象 -->
<insert id="insertUser" parameterType="com.mybatis.User">
insert into users (name, age) value(#{name}, #{age})
</insert>
<!-- 刪除一個User對象 -->
<delete id="deleteUser" parameterType="int">
delete from users where id=#{id}
</delete>
<!-- 更新一個User對象-->
<update id="updateUser" parameterType="com.mybatis.User">
update users set name=#{name}, age=#{age} where id=#{id}
</update>
</mapper>
測試代碼如下:
public class mybaitstest {
SqlSessionFactory sessionFactory = null;
SqlSession sqlSession = null;
{
String resource = "mybatisConfig.xml";
// 加載mybatis的配置文件(它也加載關聯的映射文件)
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace();
}
// 構建sqlSession的工廠
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 創建能執行映射文件中sql的sqlSession,默認是手動提交事務的,使用自動提交的話加上參數 true
sqlSession = sessionFactory.openSession(true);
}
public void testSelectUser() {
// 映射sql的標識字符串
String statement = "com.mybatis.userMapper" + ".getUser";
// 執行查詢返回一個唯一user對象的sql
User user = sqlSession.selectOne(statement, 1);
System.out.println(user);
}
public void testSelectAll() {
List<User> users = sqlSession.selectList("com.mybatis.userMapper.getUserAll");
System.out.println(users);
}
public void testInsertUser(User user) {
int insert = sqlSession.insert("com.mybatis.userMapper.insertUser", user);
// 如果不是自動提交的話,需要使用 sqlSession。commit()
System.out.println(insert);
}
public void testDeleteUser(int id) {
int delete = sqlSession.delete("com.mybatis.userMapper.deleteUser", id);
System.out.println(delete);
}
public void testUpdateUser(User user) {
int update = sqlSession.update("com.mybatis.userMapper.updateUser", user);
System.out.println(update);
}
public static void main(String[] args) throws IOException {
new mybaitstest().testSelectUser();
}
}
最後輸出結果為:

基於注解的方式使用MyBatis,首先定義對應表的sql映射接口。
public interface IUserMapper {
@Insert("insert into users (name, age) value(#{name}, #{age})")
public int add(User user);
@Delete("delete from users where id=#{id}")
public int deleteById(int id);
@Update("update users set name=#{name}, age=#{age} where id=#{id}")
public int update(User user);
@Select("select * from users where id=#{id}")
public User getById(int id);
@Select("select * from users")
public List<User> getAll();
}
然後在mybatisConfig.xml配置文件中注冊該接口:
<!-- 注冊表映射文件 -->
<mappers>
<mapper class="com.mybatis.IUserMapper"/>
</mappers>
測試示例:
/**
* 使用注解測試的方法
*/
public void test() {
IUserMapper userMapper = sqlSession.getMapper(IUserMapper.class);
User user = userMapper.getById(1);
System.out.println(user);
}
以上兩個程序示例都是直接在配置文件中寫連接數據庫的信息,其實還可以專門把數據庫連接信息寫到一個db.proteries文件中,然後由配置文件來讀取該db.properies文件信息。db.proteries文件內容如下:
user=root password=123456 driverClass=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql://192.168.1.150/test
然後在mybatisConfig.xml配置文件中將數據庫環境信息更改為如下所示:
<properties resource="db.properties"/>
<environments default="development">
<!-- development:開發環境 work:工作模式 -->
<environment id="development">
<transactionManager type="JDBC" />
<!-- 數據庫連接方式 -->
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${jdbcUrl}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
配置表對應的sql映射文件時,可以使用別名來簡化配置,在mybatisConfig.xml中添加如下配置,在userMapper中parameterType就可以配置為"_User"。
<typeAliases>
<typeAlias type="com.mybatis.User" alias="_User"/>
</typeAliases>
新建表和數據,在test數據庫中執行以下SQL語句:
create table orders (
order_id int primary key auto_increment,
order_no varchar(20),
order_price float
);
insert into orders (order_no, order_price) values('aaa', 12);
insert into orders (order_no, order_price) values('bbb', 13);
insert into orders (order_no, order_price) values('ccc', 14);
創建對應表的類:

mybaitsConfig.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>
<properties resource="db.properties"/>
<typeAliases>
<typeAlias type="com.mybatis.Order" alias="Order"/>
</typeAliases>
<environments default="development">
<!-- development:開發環境 work:工作模式 -->
<environment id="development">
<transactionManager type="JDBC" />
<!-- 數據庫連接方式 -->
<dataSource type="POOLED">
<property name="driver" value="${driverClass}" />
<property name="url" value="${jdbcUrl}" />
<property name="username" value="${user}" />
<property name="password" value="${password}" />
</dataSource>
</environment>
</environments>
<!-- 注冊表映射文件 -->
<mappers>
<mapper resource="com/mybatis/orderMapper.xml"/>
</mappers>
</configuration>
接下來配置orderMapper.xml:

測試用例:
public class MyBaitsMain {
SqlSessionFactory sessionFactory = null;
SqlSession sqlSession = null;
{
String resource = "mybatisConfig.xml";
// 加載mybatis的配置文件(它也加載關聯的映射文件)
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
} catch (IOException e) {
e.printStackTrace();
}
// 構建sqlSession的工廠
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 創建能執行映射文件中sql的sqlSession,默認是手動提交事務的,使用自動提交的話加上參數 true
sqlSession = sessionFactory.openSession(true);
}
public static void main(String[] args) {
String statement = "com.mybatis.orderMapper.getOrder";
String statement2 = "com.mybatis.orderMapper.getOrder2";
Order order = new MyBaitsMain().sqlSession.selectOne(statement, 2);
System.out.println(order);
order = new MyBaitsMain().sqlSession.selectOne(statement2, 2);
System.out.println(order);
}
}
輸出結果為:

這裡實現班級id查詢班級信息,班級信息中包括老師信息。首先創建表結構:

定義表對應的實體類:


定義sql映射文件,需要在mybatisConfig.xml中注冊該表映射文件。

測試類:

輸出結果:

這裡實現班級id查詢班級信息,班級信息中包括老師信息和學生信息。首先創建表結構:
CREATE TABLE student(
s_id INT PRIMARY KEY AUTO_INCREMENT,
s_name VARCHAR(20),
class_id INT
);
INSERT INTO student(s_name, class_id) VALUES('xs_A', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_B', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_C', 1);
INSERT INTO student(s_name, class_id) VALUES('xs_D', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_E', 2);
INSERT INTO student(s_name, class_id) VALUES('xs_F', 2);
定義表對應的實體類:

定義sql映射文件,需要在mybatisConfig.xml中注冊該表映射文件。

測試類:

輸出結果:

正如大多數持久層框架一樣,MyBatis 同樣提供了一級緩存和二級緩存的支持
Spring集成MyBatis,開發環境為IDEA,打開IDEA,新建工程,工程名為spring-mybatis。注意,這裡我選擇的是帶有Web功能的工程,其實在Spring集成MyBatis示例中並沒有用到Web功能,這個可選可不選。

1、添加工程所需的jar包,比如MySQL驅動包、Spring包、commons-logging包等,最後添加的包結構圖如下:

最後整個工程文件如下所示:

2、然後需要在test數據庫中新建測試表user,sql語句如下所示:
create table users (
id int primary key auto_increment,
name varchar(20),
age int
);
insert into users (name, age) values('Tom', 12);
insert into users (name, age) values('Jack', 11);
3、定義表對應的實體類和表操作接口。
package com.luoxn28.test;
public class User {
private int id;
private String name;
private int age;
public User() {
}
public User(int id, String name, int age) {
this.id = id;
this.name = name;
this.age = age;
}
public User(String name, int age) {
this.name = name;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", age=" + age +
'}';
}
}
package com.luoxn28.test;
import java.util.List;
public interface UserDao {
public int insert(User user);
public int update(User user);
public int delete(int id);
public User getById(int id);
public List<User> getAll();
}
4、定義表映射配置文件userDao.xml和MyBatis配置文件mybatisConfig.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="com.luoxn28.test.UserDao">
<insert id="insert" parameterType="com.luoxn28.test.User">
INSERT users (name, age) VALUES (#{name}, #{age})
</insert>
<update id="update" parameterType="com.luoxn28.test.User">
UPDATE users set name=#{name}, age=#{age} where id=#{id}
</update>
<delete id="delete" parameterType="int">
DELETE FROM users where id=#{id}
</delete>
<select id="getById" parameterType="int" resultType="com.luoxn28.test.User">
SELECT * FROM users WHERE id=#{id}
</select>
<select id="getAll" resultType="com.luoxn28.test.User">
SELECT * FROM users
</select>
</mapper>
<?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>
<mappers>
<mapper resource="com/luoxn28/test/userMapper.xml"/>
</mappers>
</configuration>
5、配置Spring的applicationContext.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">
<!-- 0.導入外部配置文件 -->
<context:property-placeholder location="classpath:db.properties"/>
<!-- 1.配置數據源 DriverManagerDataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="username" value="${user}"/>
<property name="password" value="${password}"/>
<property name="driverClassName" value="${driverClass}"/>
<property name="url" value="${jdbcUrl}"/>
</bean>
<!-- 2.mybatis的SqlSession工廠 SqlSessionFactoryBean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="typeAliasesPackage" value="com.luoxn28.test"/> <!-- 實體類包名,自動將實體類的簡單類名映射成為別名 -->
<property name="configLocation" value="classpath:mybatisConfig.xml"/>
</bean>
<!-- 3.mybatis自動掃描加載sql映射文件 MapperScannerConfigurer
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.luoxn28.test"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean> -->
<!-- 4.事務管理
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean> -->
<!-- 5.聲明式事務 transaction-manager引用定義的事務管理器
<tx:annotation-driven transaction-manager="transactionManager"/> -->
<bean id="userDao" class="org.mybatis.spring.mapper.MapperFactoryBean">
<property name="mapperInterface" value="com.luoxn28.test.UserDao"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
</beans>
6、編寫測試類SMTest
package com.luoxn28.test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.testng.annotations.BeforeTest;
import org.testng.annotations.Test;
public class SMTest {
private ApplicationContext context = null;
private UserDao userDao = null;
@BeforeTest
public void init() {
context = new ClassPathXmlApplicationContext("applicationContext.xml");
userDao = (UserDao) context.getBean("userDao");
}
@Test
public void testInsert() {
System.out.println(userDao.insert(new User("luoxn28", 23)));
}
@Test
public void testUpdate() {
System.out.println(userDao.update(new User(10, "luoxn28", 22)));
}
@Test
public void testDelete() {
System.out.println(userDao.delete(10));
}
@Test
public void testGetById() {
System.out.println(userDao.getById(10));
}
@Test
public void getGetAll() {
System.out.println(userDao.getAll());
}
}
輸出結果(這是測試的是getGetAll方法):

參考資料:
1、尚硅谷-MyBatis學習視頻
2、Spring學習之AOP總結帖