- 浏览: 5222 次
- 性别:
- 来自: 广州
最新评论
Spring与Hibernate动态建表及动态加载映射文件(无需SessionFactory Rebuild)
J.Office2有一功能是工作流支持动态表单设计,设计后可以动态生成数据库表,并且支持实时查询(单表及多表均可)。
由于J.Office2版本中采用了Hibernate作为底层的ORM框架,结合Spring框架,Spring容器启动后,SessionFactory就会被注入到各个业务的Dao层中去。
动态建表功能比较容易实现,我们可以new一个SessionFactory,然后把它的配置属性hibernate.hbm2ddl.auto改为update或create,就可以达到动态修改表结构的效果。
但若要加入新的hbm或class,需要重新调用SessionFactoryBean来获取一个全新的SessionFactory,这种方案试过了,效果并不理想。重新加载,会导致大量的hbm或class文件重新加载,实在有点慢。并且严重影响现在注入SessionFactory的Dao。若Dao采用动态构建SessionFactory,性能又是一问题。而Hibernate没有提供SessionFactory动态加入hbm或Class文件。所以实在无计可施。
所以最终还是回到如何扩展Hibernate的SessionFactory类中去了,这想法已经有不少开发人员尝试过,JE也有一帖子专门讨论这个。不过仅是一Demo,不完善。我们提供了两个扩展的类(修改Hibernate中的两类,使其支持动态加入配置文件,并且能实时查询。
我们仅需要修改两个类,一个是Configuration,在其里面加一方法,如下:
public void doComplie(){
secondPassCompile();
}
修改
在SessonFactoryImpl类中加入以下方法,(有一些变量值不能修改的,请改为可修改)
Java代码 收藏代码
Java代码 收藏代码
//add by csx
public void addNewConfig(Configuration cfg){
log.info("add NewConfig.....");
Mapping mapping=this.configuration.getMapping();
this.filters.putAll( cfg.getFilterDefinitions() );
//Generators:
Iterator classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
if ( !model.isInherited() ) {
IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
settings.getDialect(),
settings.getDefaultCatalogName(),
settings.getDefaultSchemaName(),
(RootClass) model
);
identifierGenerators.put( model.getEntityName(), generator );
}
}
///////////////////////////////////////////////////////////////////////
// Prepare persisters and link them up with their cache
// region/access-strategy
String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + ".";
Map entityAccessStrategies = new HashMap();
Map tmpEntityPersisters=new HashMap();
Map tmpClassMetadata=new HashMap();
this.configuration.getClassMap().putAll(cfg.getClassMap());
classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
model.prepareTemporaryTables( mapping, settings.getDialect() );
String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName();
// cache region is defined by the root-class in the hierarchy...
EntityRegionAccessStrategy accessStrategy = ( EntityRegionAccessStrategy ) entityAccessStrategies.get( cacheRegionName );
if ( accessStrategy == null && settings.isSecondLevelCacheEnabled() ) {
AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
log.trace( "Building cache for entity data [" + model.getEntityName() + "]" );
EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
accessStrategy = entityRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
allCacheRegions.put( cacheRegionName, entityRegion );
}
}
EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, this, cfg.getMapping() );
tmpEntityPersisters.put( model.getEntityName(), cp );
tmpClassMetadata.put( model.getEntityName(), cp.getClassMetadata() );
}
//Named Queries:
namedQueries.putAll(cfg.getNamedQueries());
namedSqlQueries.putAll( cfg.getNamedSQLQueries() );
sqlResultSetMappings.putAll(cfg.getSqlResultSetMappings());
imports.putAll(cfg.getImports());
entityPersisters.putAll(tmpEntityPersisters);
classMetadata.putAll(tmpClassMetadata);
Map tmpEntityToCollectionRoleMap = new HashMap();
Map tempCollectionPersisters=new HashMap();
this.configuration.getCollectionMap().putAll(cfg.getCollectionMap());
Iterator collections = cfg.getCollectionMappings();
while ( collections.hasNext() ) {
Collection model = (Collection) collections.next();
final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
CollectionRegionAccessStrategy accessStrategy = null;
if ( accessType != null && settings.isSecondLevelCacheEnabled() ) {
log.trace( "Building cache for collection data [" + model.getRole() + "]" );
CollectionRegion collectionRegion = settings.getRegionFactory().buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
accessStrategy = collectionRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
allCacheRegions.put( cacheRegionName, collectionRegion );
}
CollectionPersister persister = PersisterFactory.createCollectionPersister(this.getConfiguration(), model, accessStrategy, this) ;
tempCollectionPersisters.put( model.getRole(), persister.getCollectionMetadata() );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
Type elementType = persister.getElementType();
if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this );
Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
}
//加入新的
collectionPersisters.putAll(tempCollectionPersisters);
Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
}
collectionRolesByEntityParticipant.putAll( tmpEntityToCollectionRoleMap);
// after *all* persisters and named queries are registered
Iterator iter = tmpEntityPersisters.values().iterator();
while ( iter.hasNext() ) {
( (EntityPersister) iter.next() ).postInstantiate();
}
iter = tempCollectionPersisters.values().iterator();
while ( iter.hasNext() ) {
( (CollectionPersister) iter.next() ).postInstantiate();
}
queryPlanCache=new QueryPlanCache(this);
}
我们动态加入实体,动态可进行查询,Hibernate提供几种实体的查询策略,其中一个是我们常用的pojo,若采用该方法,我们得加上hbm与 class类或仅是含注解的class至hibernate的SessionFactory,这种方案并且没有问题,但会遇到当我们修改表单字段,重新生 成对应的实体时,我们就会遇到原有的实体class不能在ClassLoader里卸载。使用的还是旧的Class,达不到动态查询的效果。若使用动态的 ClassLoader,代码将变得很复杂。(尝试过,代码相对比较繁杂)
还好Hibernate提供了另一种实体查询策略,基于Map的动态实体。基于这种方式,我们配置一个一对多的表,其示例代码如下:
MainEntity.hbm.xml
Java代码 收藏代码
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="main_entity" entity-name="MainEntity">
<id name="mainId" column="mainId" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="itemSubject" type="java.lang.String" length="128"/>
<property name="itemDescp" type="java.lang.String" />
<property name="createtime" type="java.util.Date" />
<bag name="subEntitys"
table="sub_entity"
lazy="false"
inverse="true"
cascade="save-update,delete-orphan"
>
<key>
<column name="mainId"/>
</key>
<one-to-many entity-name="SubEntity"/>
</bag>
</class>
</hibernate-mapping>
SubEntity.hbm.xml
Java代码 收藏代码
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="sub_entity" entity-name="SubEntity">
<id name="subId" column="subId" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="subject" type="java.lang.String" length="128"/>
<property name="createtime" type="java.util.Date"/>
<many-to-one name="mainEntity" entity-name="MainEntity" not-null="false" fetch="select">
<column name="mainId"></column>
</many-to-one>
</class>
</hibernate-mapping>
为两实体插入数据后,可动态测试如下:
Java代码 收藏代码
public static void main(String[]args){
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:app-context.xml");
MyAnnotationSessionFactoryBean sessionFactoryBean=(MyAnnotationSessionFactoryBean)ctx.getBean("&sessionFactory");
SessionFactoryImpl sessionFactoryImpl=(SessionFactoryImpl)sessionFactoryBean.getObject();
Configuration cfg=new Configuration();
//cfg.configure();
cfg.addFile("D:/download/eclipse/workspace2/SpringHibernate/src/com/hotent/entity/MainEntity.hbm.xml");
cfg.addFile("D:/download/eclipse/workspace2/SpringHibernate/src/com/hotent/entity/SubEntity.hbm.xml");
cfg.doComplie();
sessionFactoryImpl.addNewConfig(cfg);
MainEntityDao dao=(MainEntityDao)ctx.getBean("mainEntityDao");
List list=dao.query();
for(int i=0;i<list.size();i++){
Map map=(Map)list.get(i);
Iterator it=map.keySet().iterator();
while(it.hasNext()){
//String key=(String)it.next();
Object key=it.next();
Object val=map.get(key);
System.out.println("--------------->key:"+key );
}
}
Configuration cfg2=new Configuration();
cfg2.addFile("D:/dev/product/SpringHibernate/src/com/hotent/entity/MainEntity2.hbm.xml");
cfg2.addFile("D:/dev/product/SpringHibernate/src/com/hotent/entity/SubEntity2.hbm.xml");
cfg2.doComplie();
sessionFactoryImpl.addNewConfig(cfg2);
List list2=dao.query();
for(int i=0;i<list2.size();i++){
Map map=(Map)list2.get(i);
Iterator it=map.keySet().iterator();
while(it.hasNext()){
//String key=(String)it.next();
Object key=it.next();
Object val=map.get(key);
System.out.println("key:"+key );
}
}
}
Java代码 收藏代码
MainEntity2.hbm.xml与SubEntity2.hbm.xml文件相对原来的文件增加了一些列或删除了一些列
执行后,可以实时看到不同的结果,并且不会影响现有的dao。
J.Office2有一功能是工作流支持动态表单设计,设计后可以动态生成数据库表,并且支持实时查询(单表及多表均可)。
由于J.Office2版本中采用了Hibernate作为底层的ORM框架,结合Spring框架,Spring容器启动后,SessionFactory就会被注入到各个业务的Dao层中去。
动态建表功能比较容易实现,我们可以new一个SessionFactory,然后把它的配置属性hibernate.hbm2ddl.auto改为update或create,就可以达到动态修改表结构的效果。
但若要加入新的hbm或class,需要重新调用SessionFactoryBean来获取一个全新的SessionFactory,这种方案试过了,效果并不理想。重新加载,会导致大量的hbm或class文件重新加载,实在有点慢。并且严重影响现在注入SessionFactory的Dao。若Dao采用动态构建SessionFactory,性能又是一问题。而Hibernate没有提供SessionFactory动态加入hbm或Class文件。所以实在无计可施。
所以最终还是回到如何扩展Hibernate的SessionFactory类中去了,这想法已经有不少开发人员尝试过,JE也有一帖子专门讨论这个。不过仅是一Demo,不完善。我们提供了两个扩展的类(修改Hibernate中的两类,使其支持动态加入配置文件,并且能实时查询。
我们仅需要修改两个类,一个是Configuration,在其里面加一方法,如下:
public void doComplie(){
secondPassCompile();
}
修改
在SessonFactoryImpl类中加入以下方法,(有一些变量值不能修改的,请改为可修改)
Java代码 收藏代码
Java代码 收藏代码
//add by csx
public void addNewConfig(Configuration cfg){
log.info("add NewConfig.....");
Mapping mapping=this.configuration.getMapping();
this.filters.putAll( cfg.getFilterDefinitions() );
//Generators:
Iterator classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
if ( !model.isInherited() ) {
IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
settings.getDialect(),
settings.getDefaultCatalogName(),
settings.getDefaultSchemaName(),
(RootClass) model
);
identifierGenerators.put( model.getEntityName(), generator );
}
}
///////////////////////////////////////////////////////////////////////
// Prepare persisters and link them up with their cache
// region/access-strategy
String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + ".";
Map entityAccessStrategies = new HashMap();
Map tmpEntityPersisters=new HashMap();
Map tmpClassMetadata=new HashMap();
this.configuration.getClassMap().putAll(cfg.getClassMap());
classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
model.prepareTemporaryTables( mapping, settings.getDialect() );
String cacheRegionName = cacheRegionPrefix + model.getRootClass().getCacheRegionName();
// cache region is defined by the root-class in the hierarchy...
EntityRegionAccessStrategy accessStrategy = ( EntityRegionAccessStrategy ) entityAccessStrategies.get( cacheRegionName );
if ( accessStrategy == null && settings.isSecondLevelCacheEnabled() ) {
AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
log.trace( "Building cache for entity data [" + model.getEntityName() + "]" );
EntityRegion entityRegion = settings.getRegionFactory().buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
accessStrategy = entityRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
allCacheRegions.put( cacheRegionName, entityRegion );
}
}
EntityPersister cp = PersisterFactory.createClassPersister( model, accessStrategy, this, cfg.getMapping() );
tmpEntityPersisters.put( model.getEntityName(), cp );
tmpClassMetadata.put( model.getEntityName(), cp.getClassMetadata() );
}
//Named Queries:
namedQueries.putAll(cfg.getNamedQueries());
namedSqlQueries.putAll( cfg.getNamedSQLQueries() );
sqlResultSetMappings.putAll(cfg.getSqlResultSetMappings());
imports.putAll(cfg.getImports());
entityPersisters.putAll(tmpEntityPersisters);
classMetadata.putAll(tmpClassMetadata);
Map tmpEntityToCollectionRoleMap = new HashMap();
Map tempCollectionPersisters=new HashMap();
this.configuration.getCollectionMap().putAll(cfg.getCollectionMap());
Iterator collections = cfg.getCollectionMappings();
while ( collections.hasNext() ) {
Collection model = (Collection) collections.next();
final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
final AccessType accessType = AccessType.parse( model.getCacheConcurrencyStrategy() );
CollectionRegionAccessStrategy accessStrategy = null;
if ( accessType != null && settings.isSecondLevelCacheEnabled() ) {
log.trace( "Building cache for collection data [" + model.getRole() + "]" );
CollectionRegion collectionRegion = settings.getRegionFactory().buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
accessStrategy = collectionRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
allCacheRegions.put( cacheRegionName, collectionRegion );
}
CollectionPersister persister = PersisterFactory.createCollectionPersister(this.getConfiguration(), model, accessStrategy, this) ;
tempCollectionPersisters.put( model.getRole(), persister.getCollectionMetadata() );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
Type elementType = persister.getElementType();
if ( elementType.isAssociationType() && !elementType.isAnyType() ) {
String entityName = ( ( AssociationType ) elementType ).getAssociatedEntityName( this );
Set roles = ( Set ) tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
}
//加入新的
collectionPersisters.putAll(tempCollectionPersisters);
Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
}
collectionRolesByEntityParticipant.putAll( tmpEntityToCollectionRoleMap);
// after *all* persisters and named queries are registered
Iterator iter = tmpEntityPersisters.values().iterator();
while ( iter.hasNext() ) {
( (EntityPersister) iter.next() ).postInstantiate();
}
iter = tempCollectionPersisters.values().iterator();
while ( iter.hasNext() ) {
( (CollectionPersister) iter.next() ).postInstantiate();
}
queryPlanCache=new QueryPlanCache(this);
}
我们动态加入实体,动态可进行查询,Hibernate提供几种实体的查询策略,其中一个是我们常用的pojo,若采用该方法,我们得加上hbm与 class类或仅是含注解的class至hibernate的SessionFactory,这种方案并且没有问题,但会遇到当我们修改表单字段,重新生 成对应的实体时,我们就会遇到原有的实体class不能在ClassLoader里卸载。使用的还是旧的Class,达不到动态查询的效果。若使用动态的 ClassLoader,代码将变得很复杂。(尝试过,代码相对比较繁杂)
还好Hibernate提供了另一种实体查询策略,基于Map的动态实体。基于这种方式,我们配置一个一对多的表,其示例代码如下:
MainEntity.hbm.xml
Java代码 收藏代码
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="main_entity" entity-name="MainEntity">
<id name="mainId" column="mainId" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="itemSubject" type="java.lang.String" length="128"/>
<property name="itemDescp" type="java.lang.String" />
<property name="createtime" type="java.util.Date" />
<bag name="subEntitys"
table="sub_entity"
lazy="false"
inverse="true"
cascade="save-update,delete-orphan"
>
<key>
<column name="mainId"/>
</key>
<one-to-many entity-name="SubEntity"/>
</bag>
</class>
</hibernate-mapping>
SubEntity.hbm.xml
Java代码 收藏代码
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class table="sub_entity" entity-name="SubEntity">
<id name="subId" column="subId" type="java.lang.Long">
<generator class="native"/>
</id>
<property name="subject" type="java.lang.String" length="128"/>
<property name="createtime" type="java.util.Date"/>
<many-to-one name="mainEntity" entity-name="MainEntity" not-null="false" fetch="select">
<column name="mainId"></column>
</many-to-one>
</class>
</hibernate-mapping>
为两实体插入数据后,可动态测试如下:
Java代码 收藏代码
public static void main(String[]args){
ClassPathXmlApplicationContext ctx=new ClassPathXmlApplicationContext("classpath:app-context.xml");
MyAnnotationSessionFactoryBean sessionFactoryBean=(MyAnnotationSessionFactoryBean)ctx.getBean("&sessionFactory");
SessionFactoryImpl sessionFactoryImpl=(SessionFactoryImpl)sessionFactoryBean.getObject();
Configuration cfg=new Configuration();
//cfg.configure();
cfg.addFile("D:/download/eclipse/workspace2/SpringHibernate/src/com/hotent/entity/MainEntity.hbm.xml");
cfg.addFile("D:/download/eclipse/workspace2/SpringHibernate/src/com/hotent/entity/SubEntity.hbm.xml");
cfg.doComplie();
sessionFactoryImpl.addNewConfig(cfg);
MainEntityDao dao=(MainEntityDao)ctx.getBean("mainEntityDao");
List list=dao.query();
for(int i=0;i<list.size();i++){
Map map=(Map)list.get(i);
Iterator it=map.keySet().iterator();
while(it.hasNext()){
//String key=(String)it.next();
Object key=it.next();
Object val=map.get(key);
System.out.println("--------------->key:"+key );
}
}
Configuration cfg2=new Configuration();
cfg2.addFile("D:/dev/product/SpringHibernate/src/com/hotent/entity/MainEntity2.hbm.xml");
cfg2.addFile("D:/dev/product/SpringHibernate/src/com/hotent/entity/SubEntity2.hbm.xml");
cfg2.doComplie();
sessionFactoryImpl.addNewConfig(cfg2);
List list2=dao.query();
for(int i=0;i<list2.size();i++){
Map map=(Map)list2.get(i);
Iterator it=map.keySet().iterator();
while(it.hasNext()){
//String key=(String)it.next();
Object key=it.next();
Object val=map.get(key);
System.out.println("key:"+key );
}
}
}
Java代码 收藏代码
MainEntity2.hbm.xml与SubEntity2.hbm.xml文件相对原来的文件增加了一些列或删除了一些列
执行后,可以实时看到不同的结果,并且不会影响现有的dao。
相关推荐
* Rebuild hibernate session factory * */ public static void rebuildSessionFactory() { try { configuration.configure(configFile); sessionFactory = configuration.buildSessionFactory(); } catch ...
在开发过程中,遇到“Visual Studio 未能加载文件或程序集解决方案”的问题,通常是由于多种原因导致的。这可能涉及到依赖项丢失、配置错误、权限问题或者是项目引用的问题。以下是一些详细的解决步骤和可能的原因...
"Workers-Factory Rebuild" 是一款专门针对这一需求设计的前端开源库,它旨在通过智能地利用 Web Workers 技术,提升前端应用程序的性能和响应速度。本文将深入探讨该库的核心理念、工作原理及其在实际项目中的应用...
REBUILD 通过创新的业务流程引擎帮助你快速搭建各类企业管理系统,全图形化配置无需了解技术。REBUILD 侧重于业务需求实现,而非基础技术框架或项目启动模板,通过 REBUILD 可以真正实现零代码快速搭建!无需编程、...
本示例文件提供了关于如何在运行时动态管理菜单栏的方法,这对于初学者了解和掌握VB6.0的菜单控件使用具有重要的学习价值。 首先,我们需要了解VB6.0中的菜单系统。在VB6.0中,菜单通常通过MenuStrip控件来创建和...
SQL Server 修复工具 REPAIR_REBUILD SQL Server 是一个复杂的关系数据库管理系统,它提供了强大的数据存储和管理功能。但是,当 SQL Server 遇到 I/O 错误、磁盘问题或其他错误时,数据库可能会损坏,导致数据丢失...
总的来说,通过合理配置IDEA的自动构建选项,以及Mybatis Plus的热加载设置,我们可以实现在修改Mapper XML文件后,无需重启Tomcat即可看到更新效果,大大提高开发效率。如果遇到XML文件未被自动检测到更新的情况,...
### Android Studio加载本地HTML文件详解 #### 一、引言 在进行Android应用开发时,有时需要在应用内部展示HTML内容。例如,显示帮助文档、用户手册或是简单的网页信息等。传统的Eclipse环境下,通常的做法是将...
这些文件通常以二进制格式存储,直接查看难以理解,而WZ-Explorer-Rebuild-master就是用来解析和编辑这类文件的利器。它允许用户浏览、搜索、修改WZ文件内容,从而深入探究游戏的内在机制。 该工具的核心功能包括:...
### DELL服务器硬盘掉线后的REBUILD修复操作详解 在企业级服务器运维中,RAID技术作为数据冗余和性能提升的重要手段,被广泛应用。然而,在长时间运行或遇到突发状况时,服务器硬盘可能会出现故障,导致RAID阵列...
Sync Project with gradle files:对gradle...Rebuild Project :包含了Clean的操作,并对整个项目进行了重新编译(包括NDK和资源文件),因此耗时相对较长; Invalidate Cache/Restart AndroidStudio:自动生成的项目
标题“rebuild_db-1.0-rc1.zip”表明这是一个软件或工具的打包文件,版本为1.0的候选发布版1(RC1)。在IT行业中,RC1通常代表Release Candidate 1,这意味着该软件已经接近最终版本,但在正式发布前还需要进行最后...
"Qt 生成 so 文件并调用 so 文件" Qt 是一个跨平台的应用程序开发框架,它支持多种操作系统,包括 Windows、Linux 和 macOS。在 Linux 系统中,因为不支持 dll 文件,而是支持 so 文件,因此,需要生成 so 文件...
Spring Boot 项目创建方法 Spring Boot 是一个基于 Java 的开源框架,旨在简化...创建 Spring Boot 项目有多种方式,但无论选择哪种方式,都是为了快速生成一个基本的 Spring Boot 项目,供开发者进一步开发和完善。
Solar Board Rebuild on TI part4
W589_Rebuild_Tool.exe
这种情况下,我们可以将C或C++代码编译为动态链接库(.so文件),然后在Android应用中通过JNI(Java Native Interface)进行调用。下面我们将详细介绍如何在Android Studio中创建并使用C文件生成So库,以及如何在...
此外,还可以使用插件如JRebel,它提供了更强大的热部署能力,包括对Spring、Hibernate等框架的支持,可以在不重启应用的情况下更新资源文件、配置文件甚至部分数据库结构。 Eclipse也有类似的功能,例如“Build ...
开发平台VC6.0及ObjectARX3.0(本程序所涉及的文件已包含在安装程序中)。 1. 解压缩source.zip到C盘,自动生成c:\source目录。 2.在VC6下打开工程c:\source\MyModelessSheet.dsw。 3.编译生成c:/source/debug/...
通过编写 MonoBehaviour 收集Unity UI 中的当前帧有那些元素触发了Rebuild。方便进行UI重建方面的性能检查,以便提升性能。 原理就是通过对 CanvasUpdateRegistry 中的属性值型判断收集实现。由于UGUI中...