试图找出是否有办法在一个查询中重用相同的片段。
考虑一下:
<sql id="personFields">
per.id person_id,
per.created_at person_created_at,
per.email_address person_email_address,
per.first_name person_first_name,
per.last_name person_last_name,
per.middle_name person_middle_name
</sql>
“per。”别名用于在使用多个连接表的查询中使用时避免列名冲突。 它包括在内:
SELECT
<include refid="com.acme.data.mapper.PersonMapper.personFields"/>
FROM Person per
问题是每个查询不能多次使用它,因为我们有“per”。别名。
拥有这样的东西会很棒:
<sql id="personFields">
#{alias}.id #{alias}_person_id,
#{alias}.created_at #{alias}_person_created_at,
#{alias}.email_address #{alias}_person_email_address,
#{alias}.first_name #{alias}_person_first_name,
#{alias}.last_name #{alias}_person_last_name,
#{alias}.middle_name #{alias}_person_middle_name
</sql>
并将其包括在内:
SELECT
<include refid="com.acme.data.mapper.PersonMapper.personFields" alias="per1"/>,
<include refid="com.acme.data.mapper.PersonMapper.personFields" alias="per2"/>
FROM Person per1
JOIN Person per2 ON per2.parent_id = per1.id
答案 0 :(得分:6)
这是目前可行的(不确定自哪个版本):
定义它:
<sql id="AddressFields">
${alias}.id ${prefix}id,
${alias}.created_at ${prefix}created_at,
${alias}.street_address ${prefix}street_address,
${alias}.street_address_two ${prefix}street_address_two,
${alias}.city ${prefix}city,
${alias}.country ${prefix}country,
${alias}.region ${prefix}region,
${alias}.sub_region ${prefix}sub_region,
${alias}.postal_code ${prefix}postal_code
</sql>
选择它:
<sql id="PurchaseSelect">
SELECT
purchase.*,
<include refid="foo.bar.mapper.entity.AddressMapper.AddressFields">
<property name="alias" value="billing_address"/>
<property name="prefix" value="billing_address_"/>
</include>,
<include refid="foo.bar.mapper.entity.AddressMapper.AddressFields">
<property name="alias" value="shipping_address"/>
<property name="prefix" value="shipping_address_"/>
</include>
FROM purchase
LEFT JOIN address billing_address ON purchase.billing_address_id = billing_address.id
LEFT JOIN address shipping_address ON purchase.shipping_address_id = shipping_address.id
</sql>
映射:
<resultMap id="PurchaseResult" type="foo.bar.entity.sales.Purchase">
<id property="id" column="id"/>
<!-- any other purchase fields -->
<association property="billingAddress" columnPrefix="billing_address_" resultMap="foo.bar.mapper.entity.AddressMapper.AddressResult"/>
<association property="shippingAddress" columnPrefix="shipping_address_" resultMap="foo.bar.mapper.entity.AddressMapper.AddressResult"/>
</resultMap>
答案 1 :(得分:5)
很遗憾,你不能这样做,其他人已经尝试过(请参阅一些问题here或here)。包含内联并且不带参数。
我头顶的一个解决方案就是这样:
<sql id="fragment">
<foreach collection="list" separator="," item="alias">
${alias}.id ${alias}_person_id,
${alias}.created_at ${alias}_person_created_at,
${alias}.email_address ${alias}_person_email_address,
${alias}.first_name ${alias}_person_first_name,
${alias}.last_name ${alias}_person_last_name,
${alias}.middle_name ${alias}_person_middle_name
</foreach>
</sql>
只包括一次:
<select id="getPersons" parameterType="java.util.List" ... >
SELECT
<include refid="fragment"/>
FROM Person per1
JOIN Person per2 ON per2.parent_id = per1.id
</select>
并从映射器界面发送parameterType="java.util.List"
:
public interface PersonMapper {
public List<String> getPersons(List<String> aliases);
// called with aliases = ["per1", "per2"]
}
这很难看,因为你的(更高级别)代码必须知道(下层)查询中使用的别名,并且还使用字符串替换片段(${...}
而不是#{...}
)如果处理不当会很危险......但如果你能忍受......
答案 2 :(得分:3)
此功能要求实施超过2年(https://code.google.com/p/mybatis/issues/detail?id=652)。
可以在此fork中找到include中的静态参数:https://github.com/kmoco2am/mybatis-3
它完全正常工作,它具有与标准配置参数或静态变量相同的语法:
<sql id="sometable">
${prefix}Table
</sql>
<select id="select" resultType="map">
select
field1, field2, field3
from
<include refid="sometable">
<placeholder name="prefix" value="Some"/>
</include>
</select>
希望很快就会接受主要的源代码库。