当前位置: 首页 > article >正文

如何在@GenericGenerator中显式指定schema

现在的情况是,在MySQL中有db1和db2两个数据库。项目使用Hibernate,可同时访问db1和db2,默认数据库为db1。表table2在db2中。且table2的主键名为ids,是自增长字段(Auto Increment)。

table2和ids的定义为:

@Entity
@Table(name = "table2", schema = "db2")
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class Table2 implements java.io.Serializable {
	private static final long serialVersionUID = 48L;

	@Id
	@Column(name = "ids")
	@GeneratedValue(generator = "idGenerator", strategy = GenerationType.IDENTITY)
	@GenericGenerator(name = "idGenerator", strategy = "increment")
	private Integer ids;

当向table2中保存数据时,会报错。原因是生成ids时,系统会查询table2中ids的最大值。语句是:

select max(ids) from table2

由于默认数据库是db1,因此查询的是db1.table2表。但table2表实际上在db2中,所以系统找不到该表,从而报错。

这就需要在@GenericGenerator中指定max查询语句的schema。通过检查错误信息,发现对应代码在org.hibernate.id.IncrementGenerator.configure()方法中,如下:

	public void configure(Type type, Properties params, Dialect dialect) throws MappingException {
		returnClass = type.getReturnedClass();

		ObjectNameNormalizer normalizer =
				( ObjectNameNormalizer ) params.get( PersistentIdentifierGenerator.IDENTIFIER_NORMALIZER );

		String column = params.getProperty( "column" );
		if ( column == null ) {
			column = params.getProperty( PersistentIdentifierGenerator.PK );
		}
		column = dialect.quote( normalizer.normalizeIdentifierQuoting( column ) );

		String tableList = params.getProperty( "tables" );
		if ( tableList == null ) {
			tableList = params.getProperty( PersistentIdentifierGenerator.TABLES );
		}
		String[] tables = StringHelper.split( ", ", tableList );

		final String schema = dialect.quote(
				normalizer.normalizeIdentifierQuoting(
						params.getProperty( PersistentIdentifierGenerator.SCHEMA )
				)
		);
		final String catalog = dialect.quote(
				normalizer.normalizeIdentifierQuoting(
						params.getProperty( PersistentIdentifierGenerator.CATALOG )
				)
		);

		StringBuilder buf = new StringBuilder();
		for ( int i=0; i < tables.length; i++ ) {
			final String tableName = dialect.quote( normalizer.normalizeIdentifierQuoting( tables[i] ) );
			if ( tables.length > 1 ) {
				buf.append( "select max(" ).append( column ).append( ") as mx from " );
			}
			buf.append( Table.qualify( catalog, schema, tableName ) );
			if ( i < tables.length-1 ) {
				buf.append( " union " );
			}
		}
		if ( tables.length > 1 ) {
			buf.insert( 0, "( " ).append( " ) ids_" );
			column = "ids_.mx";
		}

		sql = "select max(" + column + ") from " + buf.toString();
	}

在初始化Table2实体类时,该方法就会执行。作用是生成对应数据库的select max语句。

在IncrementGenerator的注释中,有一段话:

Mapping parameters supported, but not usually needed: tables, column. (The tables parameter specified a comma-separated list of table names.)

说明在@GenericGenerator中,可以设置参数。在IncrementGenerator.configure()方法中,可以将这些参数读出来。读取参数的方法为params.getProperty("参数名")。例如:

params.getProperty( "column" )

就是读取column参数的值。对应读取schema的语句为:

final String schema = dialect.quote(
		normalizer.normalizeIdentifierQuoting(
		    params.getProperty( PersistentIdentifierGenerator.SCHEMA )
	)
);

schema的参数名就是PersistentIdentifierGenerator.SCHEMA,也就是"schema"。其他预置保留参数的值大都在org.hibernate.id.PersistentIdentifierGenerator中定义。如:

public interface PersistentIdentifierGenerator extends IdentifierGenerator {

	/**
	 * The configuration parameter holding the schema name
	 */
	public static final String SCHEMA = "schema";

	/**
	 * The configuration parameter holding the table name for the
	 * generated id
	 */
	public static final String TABLE = "target_table";

	/**
	 * The configuration parameter holding the table names for all
	 * tables for which the id must be unique
	 */
	public static final String TABLES = "identity_tables";

	/**
	 * The configuration parameter holding the primary key column
	 * name of the generated id
	 */
	public static final String PK = "target_column";

    /**
     * The configuration parameter holding the catalog name
     */
    public static final String CATALOG = "catalog";

	/**
	 * The key under whcih to find the {@link org.hibernate.cfg.ObjectNameNormalizer} in the config param map.
	 */
	public static final String IDENTIFIER_NORMALIZER = "identifier_normalizer";

在@GenericGenerator中设置parameter的方法为:

@Id
@Column(name = "ids")
@GeneratedValue(generator = "idGenerator", strategy = GenerationType.IDENTITY)
@GenericGenerator(name = "idGenerator", strategy = "increment", parameters = @Parameter(name = PersistentIdentifierGenerator.SCHEMA, value = "db2"))
private Integer ids;

这样就能在table2前加上正确的schema名称(db2),生成正确的查询语句:

select max(ids) from db2.table2

如果有多个参数,可以写为:

@GenericGenerator(name = "idGenerator", strategy = "increment", parameters = {
            @Parameter(name = PersistentIdentifierGenerator.SCHEMA, value = "db2"),
            @Parameter(name=PersistentIdentifierGenerator.CATALOG, value = "db2")

})


http://www.kler.cn/news/309443.html

相关文章:

  • 友思特方案 | 搭建红外桥梁:嵌入式视觉接口助力红外热像仪传输
  • SpringBoot入门(黑马)
  • 【数据可视化】Arcgis api 4.x 专题图制作之分级色彩,采用自然间断法(使用simple-statistics JS数学统计库生成自然间断点)
  • 0072__ActiveX插件的使用
  • Linux云计算 |【第二阶段】SHELL-DAY5
  • pdf文件怎么转换成ppt?介绍几种pdf转ppt的方法
  • 传感技术的应用
  • 利用正则表达式匹配格式并且获取替换内容中数据并保留
  • VS+QT--实现二进制和十进制的转换(含分数部分)
  • 去中心化的力量:探索Web3的分布式网络
  • 工商银行银企直联接口清单
  • Java高级Day40-QQ项目全代码
  • 使用SQL数据构建问答系统的完整指南
  • Nginx泛域名 解析的匹配前缀绑定或转发到子目录
  • APP测试基本流程与APP测试要点总结
  • 什么是单元测试?怎么做?
  • C++系列-匿名对象
  • linux网络命令:使用最多最广泛的网络抓包工具tcpdump详细介绍
  • MATLAB入门教程
  • 检查一个复数C的实部a和虚部b是否都是有限数值即a和b都不是无限数值、空值cmath.isfinite(x)
  • MES管理系统在智能制造中的重要应用
  • CMU 10423 Generative AI:lec5(Encoder-only Transformers + 阅读材料Bert, ViT)
  • 如何理解BCEWithLogitsLoss()
  • 什么是期权日内交易?怎么做日内期权策略?
  • MyBatis 源码解析:Mapper 文件加载与解析
  • 导弹追踪问题:蒙特卡罗模拟+matlab代码
  • Linux7-su,exit,sudo
  • Java 中的 sleep、wait、join 怎么理解
  • linux中的kill、pkill和killall
  • C++速通LeetCode简单第3题-相交链表