HZERO多语言维护及源码解析

一、实现

1.多语言的保存

多语言Entity实体类

实体类上添加@MultiLanguage注解,多语言字段添加@MultiLanguageField注解标记

package org.wms.mdm.domain.entity;


import com.fasterxml.jackson.annotation.JsonInclude;
import io.choerodon.mybatis.annotation.ModifyAudit;
import io.choerodon.mybatis.annotation.MultiLanguage;
import io.choerodon.mybatis.annotation.MultiLanguageField;
import io.choerodon.mybatis.annotation.VersionAudit;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.*;
import lombok.experimental.FieldNameConstants;
import org.hzero.export.annotation.ExcelColumn;
import org.hzero.export.annotation.ExcelSheet;
import org.wms.mdm.domain.render.CustomerFlagValueRenderer;
import org.wms.mdm.utils.dto.WmsDto;

import javax.persistence.Table;
import javax.persistence.Transient;

/*
 * 客户信息
 * @date 2019/12/20
 * @author 潘顾昌 
 * @version 0.0.1
 * @copyright Copyright (c) 2019, Hand
 */
@ToString
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@FieldNameConstants(prefix = "FIELD_")
@ApiModel("客户信息")
@VersionAudit
@ModifyAudit
@JsonInclude(value = JsonInclude.Include.NON_NULL)
@ExcelSheet(zh = "客户", en = "customer")
@Table(name = "wmdm_customer")
@MultiLanguage
public class Customer extends WmsDto {

    public static final String FIELD_ID = "id";
    //
    // 业务方法(按public protected private顺序排列)
    // ------------------------------------------------------------------------------

    //
    // 数据库字段
    // ------------------------------------------------------------------------------
    @MultiLanguageField
   @ApiModelProperty(value = "客户名称")
    private String customerName;
    @MultiLanguageField
    @ApiModelProperty(value = "客户全称")
	@ExcelColumn(zh = "客户全称", en = "customerFullname")
    private String customerFullname;
    @MultiLanguageField
    @ExcelColumn(zh = "客户简称", en = "customerSegment")
    @ApiModelProperty(value = "客户简称")
    private String customerSegment;


	//
    // 非数据库字段
    // ------------------------------------------------------------------------------
	@Transient
	@ApiModelProperty(value = "客户id")
	private Long customerId;
}

数据库设计

在这里插入图片描述

wmdm_customer_tl主要记录customer的多语言字段

注意:字段和原字段保持一致,例如wmdm_customer中的多语言字段为customer_name,则wmdm_customer_tl中也要有该字段,字段名必须也为customer_name

HZERO多语言维护及源码解析_第1张图片

直接利用内置的insertSelective保存

 @ApiOperation(value = "创建客户信息")
    @Permission(level = ResourceLevel.ORGANIZATION)
    @PostMapping
    public ResponseEntity<Customer> create(
            @ApiParam(value = "租户id", required = true) @PathVariable("organizationId") Long organizationId,
            @RequestBody Customer customer) {
        //validObject(customer);
        customer.setTenantId(organizationId);
        validObject(customer);
        customerService.insertCustomer(organizationId,customer);
        return Results.success(customer);
    }
customerRepository.insertSelective(customer);

2.多语言的查询

使用平台通用Mapper语句,底层已经关联多语言表进行查询

注意:使用自定义Mapper查询,需要自定义关联多语言表进行查询

 <!--查询供应商信息-->
    <select id="queryVendorList" resultMap="BaseResultMap" parameterType="org.wms.mdm.domain.entity.Vendor" >
        <bind name="lang" value="@io.choerodon.mybatis.helper.LanguageHelper@language()"/>
    SELECT
        hcu.country_name,
        hr1.region_name province_name,
        hr2.region_name city_name,
        hr3.region_name district_name,
        t.id,
        t.id vendorId,
        t.vendor_code,
        t.vendor_name,
        t.vendor_fullname,
        t.vendor_status,
        t.license,
        t.contact,
        t.mobile,
        t.tel,
        t.email,
        t.fax,
        t.zip_code,
        t.country_id,
        t.country,
        t.province_id,
        t.province,
        t.city_id,
        t.city,
        t.district_id,
        t.district,
        t.address,
        t.enabled_flag,
        t.start_date,
        t.end_date,
        t.remark,
        t.tenant_id,
        t.object_version_number,
        t.creation_date,
        t.created_by,
        t.last_updated_by,
        t.last_update_date,
        t.ATTRIBUTE_CATEGORY,
        t.ATTRIBUTE1,
        t.ATTRIBUTE2,
        t.ATTRIBUTE3,
        t.ATTRIBUTE4,
        t.ATTRIBUTE5,
        t.ATTRIBUTE6,
        t.ATTRIBUTE7,
        t.ATTRIBUTE8,
        t.ATTRIBUTE9,
        t.ATTRIBUTE10,
        t.ATTRIBUTE11,
        t.ATTRIBUTE12,
        t.ATTRIBUTE13,
        t.ATTRIBUTE14,
        t.ATTRIBUTE15,
        t.freight_forwarder_flag,
        t.customs_broker_flag,
        t.source_org_id,
        t.source_id,
        t.source_system_code
    FROM
        wmdm_vendor t
        LEFT JOIN wmdm_vendor_tl tt ON t.id = tt.id AND tt.lang = #{lang}
        LEFT JOIN hzero_platform.hpfm_country hcu ON hcu.country_id = t.COUNTRY_ID
        LEFT JOIN hzero_platform.hpfm_region hr1 ON hr1.region_id = t.PROVINCE_ID
        LEFT JOIN hzero_platform.hpfm_region hr2 ON hr2.region_id = t.CITY_ID
        LEFT JOIN hzero_platform.hpfm_region hr3 ON hr3.region_id = t.DISTRICT_ID
	WHERE t.tenant_id = #{tenantId}
        <if test="id != null">
            AND t.id = #{id}
        </if>
        <if test="vendorCode != null">
            AND t.vendor_code LIKE '%${vendorCode}%'
        </if>
        <if test="vendorName != null">
            AND t.vendor_name LIKE '%${vendorName}%'
        </if>
    </select>

二、原理

核心原理:采用Mybatis拦截器io.choerodon.mybatis.language.MultiLanguageInterceptor,对sql语句进行拦截,然后根据不同情况做出不同处理。

1.首先在io.choerodon.mybatis.MybatisMapperAutoConfiguration配置拦截器sqlSessionFactory.getConfiguration().addInterceptor(new MultiLanguageInterceptor());

/**
     * 配置支持的数据库方言以及分页、排序插件
     *
     * @param dataSource        dataSource
     * @param sqlSessionFactory sqlSessionFactory
     * @return Dialect
     * @throws SQLException SQLException
     */
    @Bean
    public Dialect dialect(DataSource dataSource, SqlSessionFactory sqlSessionFactory) throws SQLException {
        Dialect dialect = null;
        Connection connection = dataSource.getConnection();
        try {
            String productName = connection.getMetaData().getDatabaseProductName();
            if (DatabaseProductName.SQL_SERVER.value().equals(productName)) {
                dialect = new SqlServerDialect();
            } else if (DatabaseProductName.ORACLE.value().equals(productName)
                    || DatabaseProductName.GAUSS.value().equals(productName)) {
                dialect = new OracleDialect();
            } else if (DatabaseProductName.MYSQL.value().equals(productName)
                    || DatabaseProductName.HDB.value().equals(productName)) {
                dialect = new MySqlDialect();
            } else {
                logger.warn("未知数据库类型,默认使用MySQL方言。");
                dialect = new MySqlDialect();
            }
            DialectHelper.setDialect(dialect);
            PageInterceptor pageInterceptor = new PageInterceptor(dialect);
            pageInterceptor.setProperties(new Properties());
            sqlSessionFactory.getConfiguration().addInterceptor(pageInterceptor);

            sqlSessionFactory.getConfiguration().addInterceptor(new MultiLanguageInterceptor());
            sqlSessionFactory.getConfiguration().addInterceptor(new SecurityTokenInterceptor());
            sqlSessionFactory.getConfiguration().addInterceptor(new DataSecurityInterceptor());
            sqlSessionFactory.getConfiguration().addInterceptor(new CrossSchemaInterceptor());

            //配置JdbcTypeForNull, oracle数据库必须配置,解决插入null的时候报错问题
            sqlSessionFactory.getConfiguration().setJdbcTypeForNull(JdbcType.NULL);
        } catch (SQLException e) {
            logger.info("[sql exception]" + e);
        } finally {
            connection.close();
        }
        return dialect;
    }

2.当执行SQL语句时进行拦截操作

HZERO多语言维护及源码解析_第2张图片

你可能感兴趣的:(HZERO)