MyBatis 前身為 Apache iBATIS,2010 年遷移至 Google Code 並更名,2013 年遷移至 GitHub。它是一款優秀的持久層框架,支援普通 SQL、存儲過程、高級映射,幾乎消除所有 JDBC 樣板代碼,透過簡單 XML 或註解配置實現 POJO 與資料表記錄的映射。
users(id, name, age) 並插入測試數據public class User {
private int id;
private String name;
private int age;
// 建構子、getter/setter、toString()...
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://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://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>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.mybatis.userMapper">
<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>
<insert id="insertUser" parameterType="com.mybatis.User">
insert into users (name, age) value(#{name}, #{age})
</insert>
<delete id="deleteUser" parameterType="int">
delete from users where id=#{id}
</delete>
<update id="updateUser" parameterType="com.mybatis.User">
update users set name=#{name}, age=#{age} where id=#{id}
</update>
</mapper>
public class MyBatisTest {
private SqlSessionFactory sessionFactory;
private SqlSession sqlSession;
{
String resource = "mybatisConfig.xml";
Reader reader = Resources.getResourceAsReader(resource);
sessionFactory = new SqlSessionFactoryBuilder().build(reader);
sqlSession = sessionFactory.openSession(true); // 自動提交
}
public void testSelectUser() {
User user = sqlSession.selectOne("com.mybatis.userMapper.getUser", 1);
System.out.println(user);
}
// 其他 CRUD 測試...
}
定義 Mapper 介面,使用 @Select、@Insert、@Update、@Delete 註解:
public interface IUserMapper {
@Insert("insert into users (name, age) value(#{name}, #{age})")
int add(User user);
@Delete("delete from users where id=#{id}")
int deleteById(int id);
@Update("update users set name=#{name}, age=#{age} where id=#{id}")
int update(User user);
@Select("select * from users where id=#{id}")
User getById(int id);
@Select("select * from users")
List<User> getAll();
}
在 mybatisConfig.xml 中註冊:<mapper class="com.mybatis.IUserMapper"/>
db.properties 存放連線資訊,配置中用 <properties resource="db.properties"/> 引入,再用 ${driverClass} 等佔位符<typeAliases><typeAlias type="com.mybatis.User" alias="_User"/></typeAliases>,映射文件中直接用 _User資料表 orders(order_id, order_no, order_price) 對應實體 Order(id, no, price):
方案一:SQL 別名
<select id="getOrder" resultType="Order">
SELECT order_id id, order_no no, order_price price FROM orders WHERE order_id=#{id}
</select>
方案二:resultMap 映射(推薦,功能更強)
<resultMap id="getOrder2Map" type="Order">
<id property="id" column="order_id"/>
<result property="no" column="order_no"/>
<result property="price" column="order_price"/>
</resultMap>
<select id="getOrder2" resultMap="getOrder2Map">
SELECT * FROM orders WHERE order_id=#{id}
</select>
使用 <association> 標籤,支援聯合查詢與嵌套查詢兩種方式:
<!-- 聯合查詢 -->
<resultMap id="ClassesMap" type="Classes">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" javaType="Teacher">
<id property="id" column="t_id"/>
<result property="name" column="t_name"/>
</association>
</resultMap>
<!-- 嵌套查詢 -->
<resultMap id="ClassesMap2" type="Classes">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" column="teacher_id" select="getTeacher"/>
</resultMap>
使用 <collection> 標籤,ofType 指定集合元素類型:
<resultMap id="ClassesMap" type="Classes">
<id property="id" column="c_id"/>
<result property="name" column="c_name"/>
<association property="teacher" javaType="Teacher">...</association>
<collection property="students" ofType="Student">
<id property="id" column="s_id"/>
<result property="name" column="s_name"/>
</collection>
</resultMap>
| 緩存層級 | 作用域 | 存儲 | 生命周期 |
|---|---|---|---|
| 一級緩存 | Session | PerpetualCache (HashMap) | Session flush/close 時清空 |
| 二級緩存 | Mapper (Namespace) | PerpetualCache / Ehcache 等自定義 | C/U/D 操作後清空對應 namespace 緩存 |
<beans ...>
<context:property-placeholder location="classpath:db.properties"/>
<!-- 數據源 -->
<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>
<!-- SqlSessionFactory -->
<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>
<!-- Mapper 掃描器(推薦) -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.luoxn28.test"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<!-- 事務管理(可選) -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>
<tx:annotation-driven transaction-manager="transactionManager"/>
</beans>
public interface UserDao {
int insert(User user);
int update(User user);
int delete(int id);
User getById(int id);
List<User> getAll();
}
@Test
public void testGetAll() {
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
UserDao dao = ctx.getBean(UserDao.class);
System.out.println(dao.getAll());
}
整合完成後,DAO 層零實現類,完全面向介面開發,事務管理聲明式配置,極大提升開發效率。