Spring+Thymeleaf多语言页面:数据库动态数据翻译方案咨询
数据库动态内容多语言翻译方案
方案一:数据库存储多语言字段(推荐)
直接在数据库表中为每种语言单独设置字段,比如FOO_NAME_ENG、FOO_NAME_ZH、FOO_CLASS_DESC_ENG、FOO_CLASS_DESC_ZH,查询时根据当前Locale动态选择对应的字段。
Service层改造
@Service @Slf4j public class SearchFooServiceImpl implements SearchFooService{ @Autowired private JdbcTemplate jdbcTemplate; @Override public HashMap<String,String> searchFoo() { HashMap<String,String> results = new HashMap<>(); Locale locale = LocaleContextHolder.getLocale(); // 根据语言选择对应字段 String nameColumn = "FOO_NAME_ENG"; String descColumn = "FOO_CLASS_DESC_ENG"; if (Locale.CHINESE.getLanguage().equals(locale.getLanguage())) { nameColumn = "FOO_NAME_ZH"; descColumn = "FOO_CLASS_DESC_ZH"; } // 动态拼接SQL查询对应字段 String sql = String.format("SELECT %s, %s FROM FOO_TYPE", nameColumn, descColumn); jdbcTemplate.query(sql, (ResultSet rs) -> { while (rs.next()) { results.put(rs.getString(nameColumn), rs.getString(descColumn)); } return results; }); return results; } }
这种方式性能好,直接查询目标语言数据,不需要额外翻译处理;缺点是新增语言时需要修改表结构。
方案二:用国际化消息键映射数据库值
把数据库中存储的FOO_NAME_ENG作为国际化消息的key,在messages.properties、messages_zh.properties等配置文件中维护对应的翻译值,然后在Thymeleaf中直接用#{}语法解析。
步骤1:维护国际化配置
- messages.properties:
foo.type.bar=Bar foo.type.baz=Baz
- messages_zh.properties:
foo.type.bar=巴 foo.type.baz=巴兹
步骤2:Thymeleaf模板修改
<div th:each="map : ${listTypeMap}"> <div th:each="mapEntry : ${map}" th:if="${mapEntry.value} == 'foo'"> <div class="col-md-12 form-check"> <input type="checkbox" class="form-check-input" th:value="${mapEntry.key}" required> <label class="form-check-label" for="validationFormCheck1" th:text="#{'foo.type.' + ${mapEntry.key}}"></label> </div> </div> </div>
这种方式不用修改数据库结构,新增语言只需要添加对应的配置文件;缺点是数据库中的值必须和消息键严格对应,不适合动态生成的内容。
方案三:集成翻译服务(适合动态内容)
如果数据库内容是用户生成的动态数据,没法提前在配置文件中维护,可以集成第三方翻译服务(比如百度翻译、谷歌翻译API),在Service层根据Locale实时翻译。
Service层示例
@Service @Slf4j public class SearchFooServiceImpl implements SearchFooService{ @Autowired private JdbcTemplate jdbcTemplate; @Autowired private TranslationService translationService; // 自定义翻译服务,封装第三方API @Override public HashMap<String,String> searchFoo() { HashMap<String,String> results = new HashMap<>(); Locale locale = LocaleContextHolder.getLocale(); jdbcTemplate.query("SELECT FOO_NAME_ENG, FOO_CLASS_DESC_ENG FROM FOO_TYPE ", (ResultSet rs) -> { while (rs.next()) { String name = rs.getString("FOO_NAME_ENG"); String desc = rs.getString("FOO_CLASS_DESC_ENG"); // 非英文环境时翻译 if (!Locale.ENGLISH.getLanguage().equals(locale.getLanguage())) { name = translationService.translate(name, "en", locale.getLanguage()); desc = translationService.translate(desc, "en", locale.getLanguage()); } results.put(name, desc); } return results; }); return results; } }
这种方式支持动态内容翻译,不需要提前维护;缺点是依赖第三方服务,有调用成本和延迟,建议加缓存优化性能。
内容的提问来源于stack exchange,提问作者Leonard Kawhi
相关产品推荐
相关产品推荐

