Oracle的同义词(synonyms)

本文介绍了Oracle数据库中同义词的概念及其应用场景,包括如何创建、删除同义词及查询同义词列表。同义词能简化操作并提高跨用户表访问的便利性。

Oracle的同义词(synonyms)从字面上理解就是别名的意思,和试图的功能类似,就是一种映射关系。本文介绍如何创建同义词语句,删除同义词以及查看同义词语句。

 

oracle的同义词总结:

  从字面上理解就是别名的意思,和试图的功能类似。就是一种映射关系

1.创建同义词语句:

        create public synonym table_name for user.table_name;

其中第一个user_table和第二个user_table可以不一样。

 

此外如果要创建一个远程的数据库上的某张表的同义词,需要先创建一个Database Link(数据库连接)来扩展访问,然后在使用如下语句创建数据库同义词:create synonym table_name for table_name@DB_Link;

 

当然,你可能需要在user用户中给当前用户(user2)授权: grant select/delete/update on user2

 

2.删除同义词:

        drop public synonym table_name;

3.查看所有同义词:

        select * from dba_synonyms

 

同义词拥有如下好处:节省大量的数据库空间,对不同用户的操作同一张表没有多少差别;扩展的数据库的使用范围,能够在不同的数据库用户之间实现无缝交互;同义词可以创建在不同一个数据库服务器上,通过网络实现连接。

<think>我们正在讨论Mybatis-Plus的逆向工程如何处理Oracle同义词的问题。根据用户的需求,他想要了解如何在使用Mybatis-Plus的代码生成器时处理Oracle数据库中的同义词。 首先,我们需要明确:Mybatis-Plus的逆向工程(即代码生成器)默认情况下并不会自动处理同义词同义词Oracle数据库中的一种对象,它相当于给表或视图起一个别名,用于简化访问或提供透明访问。在逆向工程中,我们通常需要访问实际的数据字典来获取表结构信息。 在Oracle中,同义词分为私有同义词和公有同义词。私有同义词属于某个用户,而公有同义词则对所有用户可见。当我们使用Mybatis-Plus的代码生成器时,它默认会查询当前用户下的表(即`USER_TABLES`视图),而不会查询同义词指向的表。 为了解决这个问题,我们需要修改Mybatis-Plus逆向工程的配置,使其能够查询同义词指向的实际表。我们可以通过以下步骤实现: 1. **修改数据源配置**:确保连接数据库的用户具有访问同义词所指向的基表的权限。因为即使通过同义词访问,也需要对基表有相应的权限。 2. **修改逆向工程的查询SQL**:Mybatis-Plus的代码生成器默认使用`USER_TAB_COMMENTS`等视图查询表信息,这些视图只包含当前用户下的表。我们需要将其改为查询`ALL_TAB_COMMENTS`视图,因为该视图包含当前用户有访问权限的所有表(包括其他用户的表以及通过同义词访问的表)。同时,我们还需要注意,在查询表字段信息时也需要使用相应的`ALL_`视图。 3. **设置表名过滤规则**:在使用`ALL_TAB_COMMENTS`视图时,会得到当前用户有权限的所有表,因此我们需要在代码生成器中设置表名过滤规则,只生成我们需要的表。 具体实现步骤如下: ### 1. 修改数据源配置 确保数据库用户有访问同义词所指向的基表的权限。例如,如果同义词指向另一个用户(模式)下的表,那么当前用户需要被授予访问那个表的权限。 ### 2. 自定义Mybatis-Plus的代码生成器配置 在Mybatis-Plus的代码生成器配置中,我们可以自定义用于查询数据库元数据的SQL。以下是关键修改: #### 修改表信息查询SQL 默认情况下,代码生成器使用如下SQL查询表信息: ```sql SELECT table_name tableName, comments tableComment FROM user_tab_comments ``` 我们需要改为: ```sql SELECT table_name tableName, comments tableComment FROM all_tab_comments WHERE owner = ? ``` 但是注意,这里我们不能直接用`?`参数,因为Mybatis-Plus的代码生成器并没有提供这个地方的参数绑定。因此,我们可以考虑另一种方式:使用`ALL_TAB_COMMENTS`视图并根据当前用户来过滤。但是,在Oracle中,`ALL_TAB_COMMENTS`视图包含了当前用户有权限的所有表,包括其他用户的表,所以我们可以进一步过滤,只查询当前用户和公有同义词(公有同义词的所有者为'PUBLIC')的表。 然而,同义词本身并不在`ALL_TAB_COMMENTS`中,我们需要查询的是同义词指向的基表。所以,我们实际上是要生成基表的代码,而不是同义词。因此,我们可以在代码生成器的表名过滤条件中直接使用基表的表名。 但是,问题在于:当我们使用同义词进行查询时,在`ALL_TAB_COMMENTS`中并不包含同义词的名字,而是包含基表的名字。因此,如果我们希望根据同义词的名字来生成代码(例如,我们有一个同义词叫`SYN_EMPLOYEE`,它指向`HR.EMPLOYEES`),那么我们需要在代码生成器中指定基表`HR.EMPLOYEES`,而不是同义词`SYN_EMPLOYEE`。 所以,如果我们希望生成同义词对应的实体类,实际上应该生成其指向的基表对应的实体类,因为最终操作的是基表。 但是,如果我们的需求是:在代码生成器中,我们输入的是同义词,然后生成该同义词对应的基表的代码,那么我们需要先通过同义词找到基表。这需要我们自定义代码生成器的逻辑。 ### 自定义代码生成器策略 我们可以通过以下步骤实现: 1. 在代码生成器配置中,覆盖`getTableList`方法,首先查询同义词对应的基表,然后将基表的表名和模式名保存下来,再调用父类的方法生成基表的代码。 2. 或者,在调用代码生成器之前,先查询同义词对应的基表,然后使用基表名来生成代码。 ### 示例:自定义查询表信息的SQL Mybatis-Plus的代码生成器配置类`AutoGenerator`中,我们可以通过`DataSourceConfig`和`StrategyConfig`来配置,但是更深入的需要自定义`ITableNameHandler`和`IColumnNameHandler`等。 然而,对于查询表信息的SQL,我们可以通过重写`ConfigBuilder`类来改变。但这比较复杂。 一个相对简单的方法是:在生成代码之前,我们通过数据库连接查询同义词对应的基表,然后使用基表名来生成代码。 例如,在Oracle中,我们可以通过以下SQL查询同义词的基表: ```sql SELECT table_owner, table_name FROM all_synonyms WHERE synonym_name = 'SYN_EMPLOYEE' AND owner = '当前用户'; ``` 然后,我们使用`table_owner`和`table_name`来设置代码生成器的表名(使用`table_owner.table_name`形式)。 ### 在代码生成器中设置表名 在`StrategyConfig`中,我们可以设置表名前缀,这个前缀通常是模式名(即用户名)。例如,如果基表在`HR`模式下,表名为`EMPLOYEES`,我们可以设置表名前缀为`HR.EMPLOYEES`,但是Mybatis-Plus的代码生成器在解析表名时,会将点(.)分隔的部分分别作为模式名和表名。因此,我们可以这样设置: ```java strategy.setInclude("HR.EMPLOYEES"); ``` 注意:这样设置时,Mybatis-Plus会将`HR.EMPLOYEES`作为表名(带模式),然后生成实体类时,会去掉模式名,只取`EMPLOYEES`作为实体类名(或者根据配置的规则转换)。但这样生成的Mapper和XML文件会基于`EMPLOYEES`表。 ### 结论 总结一下,处理Oracle同义词的步骤: 1. 确定同义词指向的基表(包括模式名和表名)。 2. 在代码生成器的表名设置中,使用基表的完全限定名(即模式名.表名)。 3. 确保数据库连接用户有访问基表的权限。 这样,Mybatis-Plus的代码生成器就可以像处理普通表一样处理同义词指向的基表了。 ### 示例代码 以下是一个简单的示例,展示如何通过查询同义词获取基表信息,然后设置到代码生成器中: ```java // 假设我们有一个同义词synonymName String synonymName = "SYN_EMPLOYEE"; // 查询同义词的基表 String sql = "SELECT table_owner, table_name FROM all_synonyms WHERE synonym_name = ? AND owner = ?"; // 假设conn是数据库连接 PreparedStatement ps = conn.prepareStatement(sql); ps.setString(1, synonymName); ps.setString(2, "MY_SCHEMA"); // 当前用户 ResultSet rs = ps.executeQuery(); if (rs.next()) { String tableOwner = rs.getString("table_owner"); String tableName = rs.getString("table_name"); String fullTableName = tableOwner + "." + tableName; // 配置代码生成器 AutoGenerator autoGenerator = new AutoGenerator(); // ... 配置数据源等 StrategyConfig strategy = new StrategyConfig(); strategy.setInclude(fullTableName); // 设置表名为模式.表名 // 其他策略配置... autoGenerator.setStrategy(strategy); autoGenerator.execute(); } ``` 注意:上面的代码只是一个思路示例,实际应用中需要根据具体环境调整。 另一种更通用的做法是:在代码生成器中,我们配置要生成的表名时,直接使用基表名(完全限定名),而忽略同义词。因为同义词只是在数据库层面提供的一个别名,在代码生成时我们关心的是实际存储数据的表。 ### 相关问题 1. 在Mybatis-Plus中,如何处理数据库中的视图? 2. Mybatis-Plus逆向工程如何支持多模式(Schema)数据库? 3. 如何自定义Mybatis-Plus代码生成器以支持其他特殊数据库对象? </think>### Mybatis-Plus逆向工程处理Oracle同义词的方法 #### 核心概念说明 1. **Oracle同义词**: - 数据库对象的别名(公有/私有) - 提供对象位置透明性:`CREATE SYNONYM emp_syn FOR hr.employees` 2. **MyBatis-Plus逆向工程**: - 通过`AutoGenerator`自动生成实体类/Mapper/Service - 依赖数据库元数据查询(如`USER_TABLES`) #### 处理同义词的关键步骤 1. **配置数据源权限**: ```java DataSourceConfig dsc = new DataSourceConfig(); dsc.setUrl("jdbc:oracle:thin:@//host:1521/ORCL"); dsc.setUsername("your_user"); dsc.setPassword("your_pwd"); ``` - 需确保数据库用户拥有`SELECT_CATALOG_ROLE`角色 - 授权语句:`GRANT SELECT ANY DICTIONARY TO your_user;` 2. **修改元数据查询逻辑(核心)**: ```java AutoGenerator generator = new AutoGenerator(); generator.setDataSource(dataSourceConfig); // 自定义表查询SQL InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { String sql = "SELECT synonym_name AS table_name, 'SYNONYM' AS table_type " + "FROM all_synonyms WHERE table_owner = ?"; this.setMap(new HashMap<String, Object>() {{ put("tableSql", sql); }}); } }; generator.setCfg(cfg); ``` 3. **同义词基表解析**: ```sql SELECT table_owner, table_name FROM all_synonyms WHERE synonym_name = 'YOUR_SYNONYM'; ``` 4. **自定义表名处理器**: ```java StrategyConfig strategy = new StrategyConfig(); strategy.setTableNameConvertor((entityName) -> { if (entityName.endsWith("_SYN")) { // 识别同义词后缀 return entityName.replace("_SYN", ""); } return entityName; }); ``` 5. **字段映射处理**: ```java strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityTableFieldAnnotationEnable(true); // 生成@TableField注解 ``` #### 完整配置示例 ```java public class OracleSynonymGenerator { public static void main(String[] args) { AutoGenerator generator = new AutoGenerator(); // 数据源配置 DataSourceConfig dsc = new DataSourceConfig(); dsc.setDbType(DbType.ORACLE); dsc.setDriverName("oracle.jdbc.OracleDriver"); dsc.setUrl("jdbc:oracle:thin:@//localhost:1521/ORCLPDB"); dsc.setUsername("mp_user"); dsc.setPassword("secret"); generator.setDataSource(dsc); // 自定义元数据查询 InjectionConfig cfg = new InjectionConfig() { @Override public void initMap() { String sql = "SELECT synonym_name AS table_name, table_owner || '.' || table_name AS remarks " + "FROM all_synonyms WHERE owner = USER"; this.setMap(new HashMap<String, Object>() {{ put("tableSql", sql); }}); } }; generator.setCfg(cfg); // 策略配置 StrategyConfig strategy = new StrategyConfig(); strategy.setNaming(NamingStrategy.underline_to_camel); strategy.setColumnNaming(NamingStrategy.underline_to_camel); strategy.setEntityLombokModel(true); strategy.setRestControllerStyle(true); strategy.setInclude("EMP_SYN", "DEPT_SYN"); // 指定同义词名称 generator.setStrategy(strategy); generator.execute(); // 执行生成 } } ``` #### 注意事项 1. **权限要求**: - `SELECT ON ALL_SYNONYMS`权限 - 同义词指向的基表需有`SELECT`权限 2. **版本兼容性**: - MyBatis-Plus ≥ 3.4.0 支持自定义SQL注入 - Oracle 11g/12c/19c 均适用 3. **常见问题解决**: - **问题**:生成的实体类缺少字段 **解决**:检查`all_tab_columns`访问权限 - **问题**:同义词无法解析 **解决**:确认`all_synonyms`中存在目标同义词 - **问题**:生成XML文件报错 **解决**:添加 `<property name="skipView" value="true"/>` 配置 #### 典型应用场景 1. 跨Schema对象访问(如访问`HR.EMPLOYEES`) 2. 数据库迁移时的对象映射兼容层 3. 生产环境屏蔽真实表结构信息 ###
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值