3.9.11. MyBatis 集成
MyBatis 框架,与 ORM 本地查询或QueryRunner相比,提供了更广泛的执行 SQL 和将查询结果映射到对象的功能。
按照下面的步骤在 CUBA 项目中集成 MyBatis。
在 core 模块的根 java 包创建处理 UUID 类型的类。
import com.haulmont.cuba.core.global.UuidProvider;
import org.apache.ibatis.type.JdbcType;
import org.apache.ibatis.type.TypeHandler;
import java.sql.*;
public class UUIDTypeHandler implements TypeHandler {
@Override
public void setParameter(PreparedStatement ps, int i, Object parameter, JdbcType jdbcType) throws SQLException {
ps.setObject(i, parameter, Types.OTHER);
}
@Override
public Object getResult(ResultSet rs, String columnName) throws SQLException {
String val = rs.getString(columnName);
if (val != null) {
return UuidProvider.fromString(val);
} else {
return null;
}
}
@Override
public Object getResult(ResultSet rs, int columnIndex) throws SQLException {
String val = rs.getString(columnIndex);
if (val != null) {
return UuidProvider.fromString(val);
} else {
return null;
}
}
@Override
public Object getResult(CallableStatement cs, int columnIndex) throws SQLException {
String val = cs.getString(columnIndex);
if (val != null) {
return UuidProvider.fromString(val);
} else {
return null;
}
}
}
在 core 模块的 spring.xml 文件所在目录创建
mybatis.xml
配置文件,在文件内正确引用UUIDTypeHandler
:<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="lazyLoadingEnabled" value="false"/>
</settings>
<typeHandlers>
<typeHandler javaType="java.util.UUID"
handler="com.company.demo.core.UUIDTypeHandler"/>
</typeHandlers>
</configuration>
将下面的 bean 都添加到
spring.xml
文件以便在项目中使用 MyBatis:<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="cubaDataSource"/>
<property name="configLocation" value="com/company/demo/mybatis.xml"/>
<property name="mapperLocations" value="com/company/demo/core/sqlmap/*.xml"/>
</bean>
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com/company/demo.core.dao"/>
<property name="sqlSessionFactory" ref="sqlSessionFactory"/>
</bean>
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
sqlSessionFactory
bean 包含了指向mybatis.xml
的引用。MapperLocations
参数定义了mapperLocations
映射文件的路径(根据 Spring 中ResourceLoader
接口的资源解析规则)。最后,在 build.gradle 中的
core
模块添加 MyBatis 的依赖:compile('org.mybatis:mybatis:3.2.8')
compile('org.mybatis:mybatis-spring:1.2.5')
下面是一个映射文件的示例,用于加载 订单(Order)
的实例以及相关的 客户(Customer)
和 订单商品(order item)
集合:
<?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.sample.sales">
<select id="selectOrder" resultMap="orderResultMap">
select
o.ID as order_id,
o.DATE as order_date,
o.AMOUNT as order_amount,
c.ID as customer_id,
c.NAME as customer_name,
c.EMAIL as customer_email,
i.ID as item_id,
i.QUANTITY as item_quantity,
p.ID as product_id,
p.NAME as product_name
from
SALES_ORDER o
left join SALES_CUSTOMER c on c.ID = o.CUSTOMER_ID
left join SALES_ITEM i on i.ORDER_ID = o.id and i.DELETE_TS is null
left join SALES_PRODUCT p on p.ID = i.PRODUCT_ID
where
c.id = #{id}
</select>
<resultMap id="orderResultMap" type="com.sample.sales.entity.Order">
<id property="id" column="order_id"/>
<result property="date" column="order_date"/>
<result property="amount" column="order_amount"/>
<association property="customer" column="customer_id" javaType="com.sample.sales.entity.Customer">
<id property="id" column="customer_id"/>
<result property="name" column="customer_name"/>
<result property="email" column="customer_email"/>
</association>
<collection property="items" ofType="com.sample.sales.entity.Item">
<id property="id" column="item_id"/>
<result property="quantity" column="item_quantity"/>
<association property="product" column="product_id" javaType="com.sample.sales.entity.Product">
<id property="id" column="product_id"/>
<result property="name" column="product_name"/>
</association>
</collection>
</resultMap>
</mapper>
以下代码可用于获取上面示例中的查询结果:
try (Transaction tx = persistence.createTransaction()) {
SqlSession sqlSession = AppBeans.get("sqlSession");
Order order = (Order) sqlSession.selectOne("com.sample.sales.selectOrder", orderId);
tx.commit();