学习Hibernate源码三_Hibernate中的配置文件解析 http://bsr1983.iteye.com/blog/1935617
本节要学习一下Hibernate的配置文件的具体加载、解析的过程,以及涉及到的相关代码,思路是建立一个简单的java项目,配置一个hbm文件,启动后,跟踪调试加载解析hbm的过程,学习相关的代码。
搭建项目后,将所需jar放入java项目的lib目录,在Hibernate的手册中说明此处也可以使用Maven来设置依赖jar,我这里还是使用比较原始的方式。直接建立一个lib目录放置所需要的jar包,然后设置classpath即可。
参考Hibernate手册中所说的,解释一下.hbm中几个具体配置项的相关注意事项。
(1)关于property元素
property中包含name、type、column 这3个常用的属性。
如:
Xml代码
name属性用来设置访问对应的映射类中对应属性值的getter、setter方法,有时候可以只配置一个name属性,type和column可以省略。上述例子中的type并不是java的数据类型,也不是SQL数据库的类型,而是被称为hibernate映射类型,它是用来在Java数据类型和SQL数据类型之间做转换的。如果type属性未定义,则Hibernate会尝试确定正确的映射类型来进行转换。在某些情况下,这种使用java类文件反射的自动检测可能没有你所期望和需要的类型,例如上述的date属性,Hibernate不能确定这里的java.util.Date应该映射为SQL的哪种类型,是date、timestamp还是time?因此此处使用了一个timestamp来指定对应的是一个包含日期和时间信息的属性。
注意:Hibernate在处理映射文件时会根据反射来设置对应的映射类型,这将会耗费一定的时间和资源,如果你的应用对启动的性能非常在意,那么你就要考虑精确的定义要使用的类型。
此处我使用的是mysql数据库,并不是手册中的HSQLDB,我创建了一个UserInfo表,具体的配置文件如下:
Xml代码
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
org.hibernate.dialect.MySQLDialect
jdbc:mysql://localhost:3306/hibernatecode
root
root
com.mysql.jdbc.Driver
接着是数据库表UserInfo的映射文件
Xml代码
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
最后是运行所需的类的主方法:
Java代码
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建配置对象
Configuration configuration = new Configuration();
//调用默认配置方法
configuration.configure();
//注册服务
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
.applySettings(configuration.getProperties())
.buildServiceRegistry();
//根据所注册的服务创建sessionFactory
SessionFactory sessionFactory = configuration
.buildSessionFactory(serviceRegistry);
UserInfo user = new UserInfo();
user.setName("ibsrapp");
user.setPassword("ibsrapp");
user.setBirthday(new Date());
//获取一个session
Session session = sessionFactory.openSession();
Transaction trans = session.beginTransaction();
session.save(user);
trans.commit();
session.close();
sessionFactory.close();
System.out.print("save Success");
}
接着按照main方法中的代码进行debug,看看将一个对象保存到数据库中所需的步骤和涉及的相关代码。
首先是
Java代码
//创建配置对象
Configuration configuration = new Configuration();
//调用默认配置方法
configuration.configure();
查看Configuration的configure()方法,代码如下:
Java代码
public Configuration configure() throws HibernateException {
configure( "/hibernate.cfg.xml" );
return this;
}
通过这个方法,我们就能明白为什么配置文件的名称默认是hibernate.cfg.xml , 而且默认是放在src目录下了。
接着看一下configure( "/hibernate.cfg.xml" );所对应的方法
Java代码
public Configuration configure(String resource) throws HibernateException {
LOG.configuringFromResource( resource );
InputStream stream = getConfigurationInputStream( resource );
return doConfigure( stream, resource );
}
此处最终还是调用了doConfigure( stream, resource );代码如下
核心代码为:
Java代码
Document document = xmlHelper.createSAXReader( errorLogger, entityResolver )
.read( new InputSource( stream ) );
if ( errorLogger.hasErrors() ) {
throw new MappingException( "invalid configuration", errorLogger.getErrors().get( 0 ) );
}
doConfigure( document );
即将所传递的流转换为一个org.dom4j.Document对象,然后调用
Java代码
protected Configuration doConfigure(Document doc) throws HibernateException {
//获取根元素下(hibernate-configuration)的session-factory子节点
Element sfNode = doc.getRootElement().element( "session-factory" );
String name = sfNode.attributeValue( "name" );
if ( name != null ) {
properties.setProperty( Environment.SESSION_FACTORY_NAME, name );
}
addProperties( sfNode );
//处理session-factory子节点
parseSessionFactory( sfNode, name );
Element secNode = doc.getRootElement().element( "security" );
if ( secNode != null ) {
parseSecurity( secNode );
}
LOG.configuredSessionFactory( name );
LOG.debugf( "Properties: %s", properties );
return this;
}
其中用于处理session-factory 子节点的方法如下:
可以看到mapping属性所指明的映射文件,以及class-cache 之门的类粒度级别的缓存以及collection-cache 指明的集合粒度级别的缓存都有对应的处理方法。
Java代码
private void parseSessionFactory(Element sfNode, String name) {
Iterator elements = sfNode.elementIterator();
while ( elements.hasNext() ) {
Element subelement = (Element) elements.next();
String subelementName = subelement.getName();
if ( "mapping".equals( subelementName ) ) {
parseMappingElement( subelement, name );
}
else if ( "class-cache".equals( subelementName ) ) {
String className = subelement.attributeValue( "class" );
Attribute regionNode = subelement.attribute( "region" );
final String region = ( regionNode == null ) ? className : regionNode.getValue();
boolean includeLazy = !"non-lazy".equals( subelement.attributeValue( "include" ) );
setCacheConcurrencyStrategy( className, subelement.attributeValue( "usage" ), region, includeLazy );
}
else if ( "collection-cache".equals( subelementName ) ) {
String role = subelement.attributeValue( "collection" );
Attribute regionNode = subelement.attribute( "region" );
final String region = ( regionNode == null ) ? role : regionNode.getValue();
setCollectionCacheConcurrencyStrategy( role, subelement.attributeValue( "usage" ), region );
}
}
}
用于处理mapping映射文件的方法如下:
Java代码
private void parseMappingElement(Element mappingElement, String name) {
final Attribute resourceAttribute = mappingElement.attribute( "resource" );
final Attribute fileAttribute = mappingElement.attribute( "file" );
final Attribute jarAttribute = mappingElement.attribute( "jar" );
final Attribute packageAttribute = mappingElement.attribute( "package" );
final Attribute classAttribute = mappingElement.attribute( "class" );
if ( resourceAttribute != null ) {
final String resourceName = resourceAttribute.getValue();
LOG.debugf( "Session-factory config [%s] named resource [%s] for mapping", name, resourceName );
addResource( resourceName );
}
else if ( fileAttribute != null ) {
final String fileName = fileAttribute.getValue();
LOG.debugf( "Session-factory config [%s] named file [%s] for mapping", name, fileName );
addFile( fileName );
}
else if ( jarAttribute != null ) {
final String jarFileName = jarAttribute.getValue();
LOG.debugf( "Session-factory config [%s] named jar file [%s] for mapping", name, jarFileName );
addJar( new File( jarFileName ) );
}
else if ( packageAttribute != null ) {
final String packageName = packageAttribute.getValue();
LOG.debugf( "Session-factory config [%s] named package [%s] for mapping", name, packageName );
addPackage( packageName );
}
else if ( classAttribute != null ) {
final String className = classAttribute.getValue();
LOG.debugf( "Session-factory config [%s] named class [%s] for mapping", name, className );
try {
addAnnotatedClass( ReflectHelper.classForName( className ) );
}
catch ( Exception e ) {
throw new MappingException(
"Unable to load class [ " + className + "] declared in Hibernate configuration entry",
e
);
}
}
else {
throw new MappingException( " element in configuration specifies no known attributes" );
}
}
可以看到这里的资源可以是以下5种类型中的一种resource 、 file 、 jar 、 package 、 class 。 对于每种资源这里都有不同的加载方式,
查看每一类资源对应的加载方法,最终会发现他们还是会以一种输入流的方式加载到一个XmlDocument对象中,然后调用下面的方法,将对应的类和数据表进行映射,并将其添加到metadataSourceQueue 这个队列之中。
Java代码
public void add(XmlDocument metadataXml) {
if ( inSecondPass || !isOrmXml( metadataXml ) ) {
metadataSourceQueue.add( metadataXml );
}
else {
final MetadataProvider metadataProvider = ( (MetadataProviderInjector) reflectionManager ).getMetadataProvider();
JPAMetadataProvider jpaMetadataProvider = ( JPAMetadataProvider ) metadataProvider;
List classNames = jpaMetadataProvider.getXMLContext().addDocument( metadataXml.getDocumentTree() );
for ( String className : classNames ) {
try {
metadataSourceQueue.add( reflectionManager.classForName( className, this.getClass() ) );
}
catch ( ClassNotFoundException e ) {
throw new AnnotationException( "Unable to load class defined in XML: " + className, e );
}
}
}
}
通过调用JPAMetadataProvider的getXMLContext()方法获取到一个XMLContext,调用XMLContext的public List addDocument(Document doc)来将doc中所配置的相关class全部条件到一个List中,然后通过reflectionManager 通过类名称将对应的配置加载为org.hibernate.annotations.common.reflection.XClass接口的一个实现。
然后将其加入到MetadataSourceQueue中。MetadataSourceQueue中包含一个声明为transient 的ListannotatedClasses ,即annotatedClasses不需要进行序列化。
在Hibernate的手册中是通过
new Configuration().configure().buildSessionFactory();的方式来获取一个SessionFactory对象的,但是当前的代码中该方法以及被废弃,建议使用的方法是buildSessionFactory(ServiceRegistry)。
因此我们的主方法中使用的是推荐的方法。
Hibernate源码学习五_创建SessionFactoryhttp://bsr1983.iteye.com/blog/1941608
接学习四,下来就是调用configuration的buildSessionFactory方法来创建一个sessionFactory了,具体代码如下:
Java代码
public SessionFactory buildSessionFactory(ServiceRegistry serviceRegistry) throws HibernateException {
LOG.debugf( "Preparing to build session factory with filters : %s", filterDefinitions );
//注册类型,包含数据库方言
buildTypeRegistrations( serviceRegistry );
//二次传递编译,包含注解处理
secondPassCompile();
if ( !metadataSourceQueue.isEmpty() ) {
LOG.incompleteMappingMetadataCacheProcessing();
}
//校验所配置的映射类与hbm配置文件中的属性是否一致
validate();
//校验全局配置属性
Environment.verifyProperties( properties );
Properties copy = new Properties();
copy.putAll( properties );
//拷贝一份配置,处理占位符
ConfigurationHelper.resolvePlaceHolders( copy );
//通过配置的属性和注册的服务创建一个设置
Settings settings = buildSettings( copy, serviceRegistry );
//通过注册的服务,映射文件,设置,以及一个session工厂的观察者//(用于监视会话工厂状态)来创建一个会话工厂的实现
return new SessionFactoryImpl(
this,
mapping,
serviceRegistry,
settings,
sessionFactoryObserver
);
}
下面看一下上述的secondPassCompile ()二次传递编译方法secondPassCompile()的具体代码:
Java代码
protected void secondPassCompile () throws MappingException {
LOG.trace( "Starting secondPassCompile() processing" );
// TEMPORARY
// Ensure the correct ClassLoader is used in commons-annotations.
//获取当前线程中所使用的classLoader,便于处理结束后,将该classloader在设置为当//前线程所使用的类加载器,仅用于保留对象
ClassLoader tccl = Thread.currentThread().getContextClassLoader();
//获取ClassLoaderHelper中的上下文类加载器并设置到当前线程,确保所使用的类//加载器,查看实际代码,发现其实返回的还是当前线程所使用的上下文加载器,但//ClassLoaderHelper注释中说明该属性可以通过客户自定义注入来进行替换,而且在//Hibernate5中将被替换为其他方式,具体参见ClassLoaderHelper源码 Thread.currentThread().setContextClassLoader( ClassLoaderHelper.getContextClassLoader() );
//process default values first,第一次处理的时候需要设置一下默认值
{
if ( !isDefaultProcessed ) {
//use global delimiters if orm.xml declare it
Map defaults = reflectionManager.getDefaults();
final Object isDelimited = defaults.get( "delimited-identifier" );
if ( isDelimited != null && isDelimited == Boolean.TRUE ) {
getProperties().put( Environment.GLOBALLY_QUOTED_IDENTIFIERS, "true" );
}
// Set default schema name if orm.xml declares it.
final String schema = (String) defaults.get( "schema" );
if ( StringHelper.isNotEmpty( schema ) ) {
getProperties().put( Environment.DEFAULT_SCHEMA, schema );
}
// Set default catalog name if orm.xml declares it.
final String catalog = (String) defaults.get( "catalog" );
if ( StringHelper.isNotEmpty( catalog ) ) {
getProperties().put( Environment.DEFAULT_CATALOG, catalog );
}
//注解绑定
AnnotationBinder.bindDefaults( createMappings() );
isDefaultProcessed = true;
}
}
// process metadata queue
{
metadataSourceQueue.syncAnnotatedClasses();
metadataSourceQueue.processMetadata( determineMetadataSourcePrecedence() );
}
try {
inSecondPass = true;
processSecondPassesOfType( PkDrivenByDefaultMapsIdSecondPass.class );
processSecondPassesOfType( SetSimpleValueTypeSecondPass.class );
processSecondPassesOfType( CopyIdentifierComponentSecondPass.class );
processFkSecondPassInOrder();
processSecondPassesOfType( CreateKeySecondPass.class );
processSecondPassesOfType( SecondaryTableSecondPass.class );
originalSecondPassCompile();
inSecondPass = false;
}
catch ( RecoverableException e ) {
//the exception was not recoverable after all
throw ( RuntimeException ) e.getCause();
}
// process cache queue,缓存队列处理
{
for ( CacheHolder holder : caches ) {
if ( holder.isClass ) {
applyCacheConcurrencyStrategy( holder );
}
else {
applyCollectionCacheConcurrencyStrategy( holder );
}
}
caches.clear();
}
//唯一约束处理
for ( Map.Entry> tableListEntry : uniqueConstraintHoldersByTable.entrySet() ) {
final Table table = tableListEntry.getKey();
final List uniqueConstraints = tableListEntry.getValue();
for ( UniqueConstraintHolder holder : uniqueConstraints ) {
buildUniqueKeyFromColumnNames( table, holder.getName(), holder.getColumns() );
}
}
//恢复当前线程的上下文类加载器为初始上下文类加载器
Thread.currentThread().setContextClassLoader( tccl );
}
创建sessionFactory所使用的构造函数代码:
Java代码
public SessionFactoryImpl(
final Configuration cfg,
Mapping mapping,
ServiceRegistry serviceRegistry,
Settings settings,
SessionFactoryObserver observer) throws HibernateException {
LOG.debug( "Building session factory" );
//session工厂的设置项
sessionFactoryOptions = new SessionFactoryOptions() {
private EntityNotFoundDelegate entityNotFoundDelegate;
@Override
public Interceptor getInterceptor() {
return cfg.getInterceptor();
}
@Override
public EntityNotFoundDelegate getEntityNotFoundDelegate() {
if ( entityNotFoundDelegate == null ) {
if ( cfg.getEntityNotFoundDelegate() != null ) {
entityNotFoundDelegate = cfg.getEntityNotFoundDelegate();
}
else {
entityNotFoundDelegate = new EntityNotFoundDelegate() {
public void handleEntityNotFound(String entityName, Serializable id) {
throw new ObjectNotFoundException( id, entityName );
}
};
}
}
return entityNotFoundDelegate;
}
};
this.settings = settings;
this.properties = new Properties();
this.properties.putAll( cfg.getProperties() );
this.serviceRegistry = serviceRegistry.getService( SessionFactoryServiceRegistryFactory.class ).buildServiceRegistry(
this,
cfg
);
//jdbc服务
this.jdbcServices = this.serviceRegistry.getService( JdbcServices.class );
//方言
this.dialect = this.jdbcServices.getDialect();
//缓存访问服务
this.cacheAccess = this.serviceRegistry.getService( CacheImplementor.class );
final RegionFactory regionFactory = cacheAccess.getRegionFactory();
//sql函数注册,将配置中的自定义方法及制定数据库方言中的方法注册到一个//以方法名称为key,对应的方言所对英的SQLFunction接口实现类的 Map中,
this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() );
//如果指定的观察者不为空,将其添加到当前的观察者链中//SessionFactoryObserverChain
if ( observer != null ) {
this.observer.addObserver( observer );
}
this.typeResolver = cfg.getTypeResolver().scope( this );
this.typeHelper = new TypeLocatorImpl( typeResolver );
//过滤器
this.filters = new HashMap();
this.filters.putAll( cfg.getFilterDefinitions() );
LOG.debugf( "Session factory constructed with filter configurations : %s", filters );
LOG.debugf( "Instantiating session factory with properties: %s", properties );
//查询计划缓存
this.queryPlanCache = new QueryPlanCache( this );
// todo : everything above here consider implementing as standard SF service. specifically: stats, caches, types, function-reg
//内部类,用于定义一个拦截器的SessionFactory观察者
//拦截器接口可以用于在对持久类进行加载、编辑、更新等操作前进行处理,可//以用于记录操作信息
class IntegratorObserver implements SessionFactoryObserver {
private ArrayList integrators = new ArrayList();
@Override
public void sessionFactoryCreated(SessionFactory factory) {
}
@Override
//sessionFactory关闭时,调用每个拦截器的回调方法disintegrate
public void sessionFactoryClosed(SessionFactory factory) {
for ( Integrator integrator : integrators ) {
integrator.disintegrate( SessionFactoryImpl.this, SessionFactoryImpl.this.serviceRegistry );
}
}
}
//拦截器观察着
final IntegratorObserver integratorObserver = new IntegratorObserver();
//将拦截器的观察者加入当前的观察者链中
this.observer.addObserver( integratorObserver );
//获取拦截器对应的服务类,设置拦截
for ( Integrator integrator : serviceRegistry.getService( IntegratorService.class ).getIntegrators() ) {
integrator.integrate( cfg, this, this.serviceRegistry );
integratorObserver.integrators.add( integrator );
}
//Generators:
//标示符生成器
identifierGenerators = new HashMap();
//获取当前配置中的所有映射类
Iterator classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
PersistentClass model = (PersistentClass) classes.next();
//如果当前映射类的定义不是继承的,则根据其定义进行设置
if ( !model.isInherited() ) {
IdentifierGenerator generator = model.getIdentifier().createIdentifierGenerator(
cfg.getIdentifierGeneratorFactory(),
getDialect(),
settings.getDefaultCatalogName(),
settings.getDefaultSchemaName(),
(RootClass) model
);
//设定持久类的标示符生成器
identifierGenerators.put( model.getEntityName(), generator );
}
}
///////////////////////////////////////////////////////////////////////
// Prepare persisters and link them up with their cache
// region/access-strategy
//获取设置中的缓存范围
final String cacheRegionPrefix = settings.getCacheRegionPrefix() == null ? "" : settings.getCacheRegionPrefix() + ".";
//持久化工厂服务
final PersisterFactory persisterFactory = serviceRegistry.getService( PersisterFactory.class );
//持久类
entityPersisters = new HashMap();
Map entityAccessStrategies = new HashMap();
Map classMeta = new HashMap();
//获取所有映射类
classes = cfg.getClassMappings();
while ( classes.hasNext() ) {
final PersistentClass model = (PersistentClass) classes.next();
model.prepareTemporaryTables( mapping, getDialect() );
final 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() ) {
final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() );
if ( accessType != null ) {
LOG.tracef( "Building shared cache region for entity data [%s]", model.getEntityName() );
EntityRegion entityRegion = regionFactory.buildEntityRegion( cacheRegionName, properties, CacheDataDescriptionImpl.decode( model ) );
accessStrategy = entityRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
cacheAccess.addCacheRegion( cacheRegionName, entityRegion );
}
}
NaturalIdRegionAccessStrategy naturalIdAccessStrategy = null;
if ( model.hasNaturalId() && model.getNaturalIdCacheRegionName() != null ) {
final String naturalIdCacheRegionName = cacheRegionPrefix + model.getNaturalIdCacheRegionName();
naturalIdAccessStrategy = ( NaturalIdRegionAccessStrategy ) entityAccessStrategies.get( naturalIdCacheRegionName );
if ( naturalIdAccessStrategy == null && settings.isSecondLevelCacheEnabled() ) {
final CacheDataDescriptionImpl cacheDataDescription = CacheDataDescriptionImpl.decode( model );
NaturalIdRegion naturalIdRegion = null;
try {
naturalIdRegion = regionFactory.buildNaturalIdRegion( naturalIdCacheRegionName, properties,
cacheDataDescription );
}
catch ( UnsupportedOperationException e ) {
LOG.warnf(
"Shared cache region factory [%s] does not support natural id caching; " +
"shared NaturalId caching will be disabled for not be enabled for %s",
regionFactory.getClass().getName(),
model.getEntityName()
);
}
if (naturalIdRegion != null) {
naturalIdAccessStrategy = naturalIdRegion.buildAccessStrategy( regionFactory.getDefaultAccessType() );
entityAccessStrategies.put( naturalIdCacheRegionName, naturalIdAccessStrategy );
cacheAccess.addCacheRegion( naturalIdCacheRegionName, naturalIdRegion );
}
}
}
//根据上述配置生成一个实体映射
EntityPersister cp = persisterFactory.createEntityPersister(
model,
accessStrategy,
naturalIdAccessStrategy,
this,
mapping
);
//以实体映射的名称为key,将对应的持久类加入entityPersisters
entityPersisters.put( model.getEntityName(), cp );
classMeta.put( model.getEntityName(), cp.getClassMetadata() );
}
this.classMetadata = Collections.unmodifiableMap(classMeta);
Map> tmpEntityToCollectionRoleMap = new HashMap>();
collectionPersisters = new HashMap();
Map tmpCollectionMetadata = new HashMap();
Iterator collections = cfg.getCollectionMappings();
while ( collections.hasNext() ) {
Collection model = (Collection) collections.next();
final String cacheRegionName = cacheRegionPrefix + model.getCacheRegionName();
final AccessType accessType = AccessType.fromExternalName( model.getCacheConcurrencyStrategy() );
CollectionRegionAccessStrategy accessStrategy = null;
if ( accessType != null && settings.isSecondLevelCacheEnabled() ) {
LOG.tracev( "Building shared cache region for collection data [{0}]", model.getRole() );
CollectionRegion collectionRegion = regionFactory.buildCollectionRegion( cacheRegionName, properties, CacheDataDescriptionImpl
.decode( model ) );
accessStrategy = collectionRegion.buildAccessStrategy( accessType );
entityAccessStrategies.put( cacheRegionName, accessStrategy );
cacheAccess.addCacheRegion( cacheRegionName, collectionRegion );
}
CollectionPersister persister = persisterFactory.createCollectionPersister(
cfg,
model,
accessStrategy,
this
) ;
collectionPersisters.put( model.getRole(), persister );
tmpCollectionMetadata.put( model.getRole(), persister.getCollectionMetadata() );
Type indexType = persister.getIndexType();
if ( indexType != null && indexType.isAssociationType() && !indexType.isAnyType() ) {
String entityName = ( ( AssociationType ) indexType ).getAssociatedEntityName( this );
Set roles = 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 = tmpEntityToCollectionRoleMap.get( entityName );
if ( roles == null ) {
roles = new HashSet();
tmpEntityToCollectionRoleMap.put( entityName, roles );
}
roles.add( persister.getRole() );
}
}
collectionMetadata = Collections.unmodifiableMap( tmpCollectionMetadata );
Iterator itr = tmpEntityToCollectionRoleMap.entrySet().iterator();
while ( itr.hasNext() ) {
final Map.Entry entry = ( Map.Entry ) itr.next();
entry.setValue( Collections.unmodifiableSet( ( Set ) entry.getValue() ) );
}
collectionRolesByEntityParticipant = Collections.unmodifiableMap( tmpEntityToCollectionRoleMap );
//Named Queries:
namedQueries = new HashMap( cfg.getNamedQueries() );
namedSqlQueries = new HashMap( cfg.getNamedSQLQueries() );
sqlResultSetMappings = new HashMap( cfg.getSqlResultSetMappings() );
imports = new HashMap( cfg.getImports() );
// after *all* persisters and named queries are registered
Iterator iter = entityPersisters.values().iterator();
while ( iter.hasNext() ) {
final EntityPersister persister = ( ( EntityPersister ) iter.next() );
persister.postInstantiate();
registerEntityNameResolvers( persister );
}
iter = collectionPersisters.values().iterator();
while ( iter.hasNext() ) {
final CollectionPersister persister = ( ( CollectionPersister ) iter.next() );
persister.postInstantiate();
}
//JNDI + Serialization:
//获取当前设置的会话工厂名称
name = settings.getSessionFactoryName();
//获取uuid
try {
uuid = (String) UUID_GENERATOR.generate(null, null);
}
catch (Exception e) {
throw new AssertionFailure("Could not generate UUID");
}
//将当前的会话工厂加入会话工厂注册
SessionFactoryRegistry.INSTANCE.addSessionFactory(
uuid,
name,
settings.isSessionFactoryNameAlsoJndiName(),
this,
serviceRegistry.getService( JndiService.class )
);
LOG.debug( "Instantiated session factory" );
settings.getMultiTableBulkIdStrategy().prepare(
jdbcServices,
buildLocalConnectionAccess(),
cfg.createMappings(),
cfg.buildMapping(),
properties
);
if ( settings.isAutoCreateSchema() ) {
new SchemaExport( serviceRegistry, cfg )
.setImportSqlCommandExtractor( serviceRegistry.getService( ImportSqlCommandExtractor.class ) )
.create( false, true );
}
if ( settings.isAutoUpdateSchema() ) {
new SchemaUpdate( serviceRegistry, cfg ).execute( false, true );
}
if ( settings.isAutoValidateSchema() ) {
new SchemaValidator( serviceRegistry, cfg ).validate();
}
if ( settings.isAutoDropSchema() ) {
schemaExport = new SchemaExport( serviceRegistry, cfg )
.setImportSqlCommandExtractor( serviceRegistry.getService( ImportSqlCommandExtractor.class ) );
}
currentSessionContext = buildCurrentSessionContext();
//checking for named queries
if ( settings.isNamedQueryStartupCheckingEnabled() ) {
final Map errors = checkNamedQueries();
if ( ! errors.isEmpty() ) {
StringBuilder failingQueries = new StringBuilder( "Errors in named queries: " );
String sep = "";
for ( Map.Entry entry : errors.entrySet() ) {
LOG.namedQueryError( entry.getKey(), entry.getValue() );
failingQueries.append( sep ).append( entry.getKey() );
sep = ", ";
}
throw new HibernateException( failingQueries.toString() );
}
}
// this needs to happen after persisters are all ready to go...
this.fetchProfiles = new HashMap();
itr = cfg.iterateFetchProfiles();
while ( itr.hasNext() ) {
final org.hibernate.mapping.FetchProfile mappingProfile =
( org.hibernate.mapping.FetchProfile ) itr.next();
final FetchProfile fetchProfile = new FetchProfile( mappingProfile.getName() );
for ( org.hibernate.mapping.FetchProfile.Fetch mappingFetch : mappingProfile.getFetches() ) {
// resolve the persister owning the fetch
final String entityName = getImportedClassName( mappingFetch.getEntity() );
final EntityPersister owner = entityName == null
? null
: entityPersisters.get( entityName );
if ( owner == null ) {
throw new HibernateException(
"Unable to resolve entity reference [" + mappingFetch.getEntity()
+ "] in fetch profile [" + fetchProfile.getName() + "]"
);
}
// validate the specified association fetch
Type associationType = owner.getPropertyType( mappingFetch.getAssociation() );
if ( associationType == null || !associationType.isAssociationType() ) {
throw new HibernateException( "Fetch profile [" + fetchProfile.getName() + "] specified an invalid association" );
}
// resolve the style
final Fetch.Style fetchStyle = Fetch.Style.parse( mappingFetch.getStyle() );
// then construct the fetch instance...
fetchProfile.addFetch( new Association( owner, mappingFetch.getAssociation() ), fetchStyle );
((Loadable) owner).registerAffectingFetchProfile( fetchProfile.getName() );
}
fetchProfiles.put( fetchProfile.getName(), fetchProfile );
}
this.customEntityDirtinessStrategy = determineCustomEntityDirtinessStrategy();
this.currentTenantIdentifierResolver = determineCurrentTenantIdentifierResolver( cfg.getCurrentTenantIdentifierResolver() );
this.transactionEnvironment = new TransactionEnvironmentImpl( this );
this.observer.sessionFactoryCreated( this );
}
你可能感兴趣的:(Hibernate,JAVA)
java课程设计体会_Java课程设计(阶段一)
XY LIU
java课程设计体会
1选题选题一算术运算测试题目要求实现十道100以内加减法数学题,能根据题目计算出答案,与输入答案对比,判断做题是否正确,最后计算分数。添加排行榜功能存放到文件或数据库中。使用Java知识String类IO:Reader、Writer类集合:ArrayLiastsort()方法选题二猜数游戏题目要求计算机产生随机数,猜中即胜,猜不中,提示是大了还是小了,继续猜,直至猜到,给出所用时间和评语。保留用户
java项目打包_Java项目打包方式分析
weixin_39727402
java项目打包
概述在项目实践过程中,有个需求需要做一个引擎能执行指定jar包的指定main方法。起初我们以一个简单的spring-boot项目进行测试,使用spring-boot-maven-plugin进行打包,使用java-cpdemo.jar.执行,结果报错找不到对应的类。我分析了spring-boot-maven-plugin打包的结构,又回头复习了java原生jar命令打包的结果,以及其他Maven打
java spi 好处_Java SPI 实战
Gaven Wang
java spi 好处
SPI全称为(ServiceProviderInterface),是JDK内置的一种服务提供发现机制,可以轻松实现面向服务的注册与发现,完成服务提供与使用的解耦,并且可以实现动态加载SPI能做什么利用SPI机制,sdk的开发者可以为使用者提供扩展点,使用者无需修改源码,有点类似Spring@ConditionalOnMissingBean的意思动手实现一个SPI例如我们要正在开发一个sdk其中有一
Java中的批处理优化:使用Spring Batch处理大规模数据的实践
微赚淘客系统开发者@聚娃科技
java spring batch
Java中的批处理优化:使用SpringBatch处理大规模数据的实践大家好,我是微赚淘客返利系统3.0的小编,是个冬天不穿秋裤,天冷也要风度的程序猿!在处理大规模数据的场景中,批处理是一个非常常见且必要的操作。Java中的SpringBatch是一个强大的框架,能够帮助我们高效地执行复杂的批处理任务。本文将带大家了解如何使用SpringBatch处理大规模数据,并通过代码示例展示如何实现高效的批
js递归性能优化
啃火龙果的兔子
开发DEMO javascript 开发语言 ecmascript
JavaScript递归性能优化递归是编程中强大的技术,但在JavaScript中如果不注意优化可能会导致性能问题甚至栈溢出。以下是几种优化递归性能的方法:1.尾调用优化(TailCallOptimization,TCO)ES6引入了尾调用优化,但只在严格模式下有效:'usestrict';//普通递归functionfactorial(n){if(n===1)return1;returnn*fa
2025 VUE常见面试题
hmildj
vue.js 面试 前端
前言总结一些VUE面试的基础知识,共同学习1.什么是Vue?答案:Vue.js(通常简称为Vue)是一个用于构建用户界面的渐进式JavaScript框架,Vue3是Vue.js框架的最新版本,它引入了许多改进和优化,包括性能提升、更好的类型支持、组合API等。2.MVVM模式是什么?Vue如何体现这一模式?答案:MVVM将视图(View)与数据(Model)通过ViewModel层解耦,Vue
Java静态static详解
Obltv
Java基础 java
更多内容请看我的个人网站date:2025-06-04tags:八股基础静态变量特点被该类的所有对象共享不属于对象,属于类优先于对象存在,随着类的加载而加载调用方式类名调用对象名调用(不推荐)静态方法没有this关键字publicclassStudent{privateStringname;privateintage;privateStringteacherName;publicvoidshow(
Java中多态的一些见解
更多内容请看我的个人网站多态初识调用成员的特点成员变量:编译看左边,运行看左边成员方法:编译看左边,运行看右边多态在调用成员变量时为什么是父类的,但是方法是子类的?一句话解释:在编译时(静态绑定),成员变量是根据引用类型(也就是声明的类型)来决定的;在运行时(动态绑定),方法是根据对象的实际类型(也就是new出来的类型)来决定的。举个经典例子classParent{publicStringname
Java中的值传递
Obltv
Java基础 java 开发语言
更多内容请看我的个人网站date:2025-06-01tags:八股基础Java中只有值传递什么是值传递值传递(PassbyValue)调用方法时,传递的是参数的值,是原始数据的一个副本。方法内部改变这个副本,不影响原始数据。什么是引用传递引用传递(PassbyReference)调用方法时,传递的是变量的地址(指针),方法内部对这个引用的任何更改,都会影响原始对象的引用。举例一个方法不能修改一个
代码随想录算法训练营第52天 | 101.孤岛的总面积 、102.沉没孤岛、103.水流问题、104.建造最大岛屿
Amor_Fati_Yu
算法 java 数据结构
101.孤岛的总面积importjava.util.*;publicclassMain{privatestaticintcount=0;privatestaticfinalint[][]dir={{0,1},{1,0},{-1,0},{0,-1}};//四个方向privatestaticvoidbfs(int[][]grid,intx,inty){Queueque=newLinkedList=gr
将字符串数组String[]转换成List的三种方法
积极向上的Elbert
java学习 java 开发语言
通过Arrays.asList(strArray)方式,将数组转换List后,不能对List增删,只能查改,否则抛异常。String[]strArray=newString[2];Listlist=Arrays.asList(strArray);list.add("1");//此处会报错原因解析:Arrays.asList(strArray)返回值是java.util.Arrays类中一个私有静态
Java Fork/Join 框架详解
empti_
数据结构与算法 java
JavaFork/Join框架详解Fork/Join框架是Java7引入的一个并行编程框架,专门设计用来高效地实现分治算法(Divide-and-Conquer)。它通过工作窃取(Work-Stealing)算法来最大化多核处理器的利用率。一、核心概念1.基本组成ForkJoinPool:特殊的线程池,管理工作线程ForkJoinTask:表示任务的抽象类,有两个重要子类:RecursiveAct
Java注解的实现原理
empti_
Java基础 java
Java注解的实现原理Java注解的实现涉及Java语言规范、编译器处理和JVM支持等多个层面。下面我将详细解释注解在Java中的实现机制。一、注解的本质注解本质上是一种特殊的接口,所有注解类型都隐式继承自java.lang.annotation.Annotation接口。当你定义一个注解时:public@interfaceMyAnnotation{Stringvalue();}编译器实际上会生成
并行归并排序的 Java 实现
empti_
数据结构与算法 java 算法 排序算法
并行归并排序Java实现importjava.util.concurrent.RecursiveAction;importjava.util.concurrent.ForkJoinPool;publicclassParallelMergeSort{//主方法,供外部调用publicstaticvoidparallelMergeSort(int[]array){ForkJoinPoolpool=ne
Spring Boot项目初始化加载自定义配置文件内容到静态属性字段
@Corgi
Java面试题 spring boot 后端 java
文章目录创建配置文件cXXX.properties配置类XXXConfig.java添加第三方JAR包创建配置文件cXXX.properties在resource目录下新建配置文件cXXX.properties,内容如下:#商户号mch_id=xxxxx#商户密码pwd=xxxx#接口请求地址req_url=https://xxx#异步回调通知地址(请替换为实际地址)notify_url=htt
Nginx与Tomcat:谁更适合你的服务器?
当归1024
java 中间件 nginx nginx tomcat 服务器
nginx和Tomcat是两种不同类型的服务器软件,它们各有不同的用途和特点:基本定义nginx轻量级的HTTP服务器和反向代理服务器主要用于静态文件服务、负载均衡、反向代理TomcatJavaWeb应用服务器专门用于运行JavaWeb应用(JSP、Servlet)主要区别1.功能定位nginx:静态文件服务器反向代理服务器负载均衡器HTTP缓存服务器Tomcat:Java应用容器JSP/Serv
Spring AI Alibaba 支持国产大模型的Spring ai框架
程序员老陈头
面试 学习路线 阿里巴巴 spring 人工智能 java
总计30万奖金,SpringAIAlibaba应用框架挑战赛开赛点此了解SpringAI:java做ai应用的最好选择过去,Java在AI应用开发方面缺乏一个高效且易于集成的框架,这限制了开发者快速构建和部署智能应用程序的能力。SpringAI正是为解决这一问题而生,它提供了一套统一的接口,使得AI功能能够以一种标准化的方式被集成到现有的Java项目中。此外,SpringAI与原有的Spring生
Node.js 全局对象
froginwe11
开发语言
Node.js全局对象引言Node.js作为一种流行的JavaScript运行环境,以其高性能、轻量级和跨平台的特点,被广泛应用于服务器端编程、网络应用开发等领域。在Node.js中,全局对象是一个重要的概念,它为开发者提供了一系列内置的全局变量和方法,使得编程变得更加便捷。本文将详细介绍Node.js的全局对象,帮助开发者更好地理解和运用它们。Node.js全局对象概述Node.js的全局对象指
企业级AI开发利器:Spring AI框架深度解析与实战_spring ai实战
AI大模型-海文
人工智能 spring python 算法 开发语言 java 机器学习
企业级AI开发利器:SpringAI框架深度解析与实战一、前言:Java生态的AI新纪元在人工智能技术爆发式发展的今天,Java开发者面临着一个新的挑战:如何将大语言模型(LLMs)和生成式AI(GenAI)无缝融入企业级应用。传统的Java生态缺乏统一的AI集成方案,开发者往往需要为不同AI供应商(如OpenAI、阿里云、HuggingFace)编写大量重复的接口适配代码,这不仅增加了开发成本,
009 【入门】单双链表及其反转-堆栈诠释
要天天开心啊
算法专栏 算法 链表
链表与堆栈系统详解|[数据结构]-[中级]-[通用]一、基础概念与内存模型1.按值传递vs按引用传递|[Java]-[基础]-[内存]//[典型错误示例]-Java中的引用传递陷阱voidmodify(Nodenode){node=node.next;//[警告]错误!仅修改局部引用的指向,不影响原始链表}//[正确做法]-通过引用修改对象内部状态voidrealModify(Nodenode){
深度解析JavaScript 闭包
coding随想
JavaScript javascript 开发语言 ecmascript
深度解析JavaScript闭包引言:为什么闭包让人又爱又怕?在JavaScript的学习过程中,闭包(Closure)是一个绕不开的“坎”。很多开发者第一次接触闭包时,会感到一头雾水:“为什么函数能记住外部作用域的变量?”、“为什么闭包会导致内存泄漏?”。但另一方面,闭包又是JavaScript最强大的特性之一,它支撑着模块化开发、数据封装、异步编程等核心场景。本文将通过通俗的语言和生动的案例,
JavaScript中的函数柯里化(Currying):从概念到实战
coding随想
JavaScript javascript ecmascript 开发语言 前端
JavaScript中的函数柯里化(Currying):从概念到实战在JavaScript开发中,函数式编程(FunctionalProgramming)逐渐成为一种主流思想。而函数柯里化(Currying),正是这一思想中的核心技巧之一。它不仅能提升代码的复用性和灵活性,还能帮助我们构建更优雅、更模块化的解决方案。本文将带你从零开始,深入理解柯里化的原理、实现方式及实际应用场景。一、什么是函数柯
webpack和vite区别
PromptOnce
webpack 前端 node.js
一、Webpack1.概述Webpack是一个模块打包工具,它会递归地构建依赖关系图,并将所有模块打包成一个或多个bundle(包)。2.特点配置灵活:Webpack提供了高度可定制的配置文件,可以根据项目需求进行各种优化。生态系统丰富:Webpack拥有庞大的插件和加载器生态系统,可以处理各种资源类型(JavaScript、CSS、图片等)。支持代码拆分:通过代码拆分和懒加载,Webpack可以
javascript 动态画心加文字
das白
# javascript javascript 动态 心型线 文字
测试//铺满屏幕varwidth=document.documentElement.clientWidth;varheight=document.documentElement.clientHeight;document.getElementById("gycanvas").setAttribute("width",width);document.getElementById("gycanvas"
javascript 动态画心
das白
# javascript javascript 动态 心型线
测试canvas{background:lawngreen;//画布背景色}//铺满屏幕varwidth=document.documentElement.clientWidth;varheight=document.documentElement.clientHeight;document.getElementById("gycanvas").setAttribute("width",width
javascript 画心型线
测试canvas{background:lawngreen;//画布背景色}//铺满屏幕varwidth=document.documentElement.clientWidth;varheight=document.documentElement.clientHeight;document.getElementById("gycanvas").setAttribute("width",width
掌握Web3开发:从入门到精通
夲奋亻Jay
Web3 web3
掌握Web3开发是一个涉及多个步骤和学习阶段的过程。以下是一些关键的步骤和开发案例,以及它们在搜索结果中的索引编号:了解区块链基础:学习区块链的基本概念,如去中心化、加密技术、共识机制等[1]。学习智能合约:学习智能合约的工作原理和它们在区块链上的应用,特别是以太坊平台上的智能合约[1]。掌握Web3.js或Ethers.js:学习如何使用这些JavaScript库与智能合约交互、发送交易和监听事
JavaScript性能优化
lyh1344
javascript 性能优化 开发语言
JavaScript性能优化方法减少重绘和回流频繁操作DOM会导致浏览器反复计算布局,引发性能问题。使用documentFragment进行批量DOM操作,或通过classList一次性修改多个样式属性。缓存DOM查询结果,避免重复访问。事件委托利用事件冒泡机制,将事件监听器绑定到父元素而非多个子元素。减少内存占用,提升动态内容的事件处理效率。节流与防抖高频事件(如滚动、输入)通过节流(Throt
将图片的base64编码直接嵌入到html文件的css中
Kuo-Teng
软件开发实战 html css javascript
将图片的base64编码直接嵌入到html文件的css中1.背景2.将图片进行base64编码3.将图片的base64编码写入到css1.背景如果你需要在html中引入一张外部图片,你可能会这样做:如果你将引用的图片保存到本地,你可能会这样做:但是,如果网络延迟较高,或者在jar包中运行Java项目时无法根据路径顺利找到图片呢?那么,将图片的base64编码直接写入html文件便是最好的选择!2.
什么是Node.js,有什么特点
前端与小赵
node.js
Node.js简介Node.js是一个基于ChromeV8引擎的JavaScript运行时环境,由RyanDahl于2009年创建。Node.js允许开发者使用JavaScript编写服务器端应用程序,打破了JavaScript仅限于浏览器端的限制。Node.js的设计目标是提供一种简单、高效的方式来构建可伸缩的网络应用。Node.js的特点非阻塞I/O特点:Node.js使用事件驱动的非阻塞I/
继之前的线程循环加到窗口中运行
3213213333332132
java thread JFrame JPanel
之前写了有关java线程的循环执行和结束,因为想制作成exe文件,想把执行的效果加到窗口上,所以就结合了JFrame和JPanel写了这个程序,这里直接贴出代码,在窗口上运行的效果下面有附图。
package thread;
import java.awt.Graphics;
import java.text.SimpleDateFormat;
import java.util
linux 常用命令
BlueSkator
linux 命令
1.grep
相信这个命令可以说是大家最常用的命令之一了。尤其是查询生产环境的日志,这个命令绝对是必不可少的。
但之前总是习惯于使用 (grep -n 关键字 文件名 )查出关键字以及该关键字所在的行数,然后再用 (sed -n '100,200p' 文件名),去查出该关键字之后的日志内容。
但其实还有更简便的办法,就是用(grep -B n、-A n、-C n 关键
php heredoc原文档和nowdoc语法
dcj3sjt126com
PHP heredoc nowdoc
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Current To-Do List</title>
</head>
<body>
<?
overflow的属性
周华华
JavaScript
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml&q
《我所了解的Java》——总体目录
g21121
java
准备用一年左右时间写一个系列的文章《我所了解的Java》,目录及内容会不断完善及调整。
在编写相关内容时难免出现笔误、代码无法执行、名词理解错误等,请大家及时指出,我会第一时间更正。
&n
[简单]docx4j常用方法小结
53873039oycg
docx
本代码基于docx4j-3.2.0,在office word 2007上测试通过。代码如下:
import java.io.File;
import java.io.FileInputStream;
import ja
Spring配置学习
云端月影
spring配置
首先来看一个标准的Spring配置文件 applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi=&q
Java新手入门的30个基本概念三
aijuans
java 新手 java 入门
17.Java中的每一个类都是从Object类扩展而来的。 18.object类中的equal和toString方法。 equal用于测试一个对象是否同另一个对象相等。 toString返回一个代表该对象的字符串,几乎每一个类都会重载该方法,以便返回当前状态的正确表示.(toString 方法是一个很重要的方法) 19.通用编程:任何类类型的所有值都可以同object类性的变量来代替。
《2008 IBM Rational 软件开发高峰论坛会议》小记
antonyup_2006
软件测试 敏捷开发 项目管理 IBM 活动
我一直想写些总结,用于交流和备忘,然都没提笔,今以一篇参加活动的感受小记开个头,呵呵!
其实参加《2008 IBM Rational 软件开发高峰论坛会议》是9月4号,那天刚好调休.但接着项目颇为忙,所以今天在中秋佳节的假期里整理了下.
参加这次活动是一个朋友给的一个邀请书,才知道有这样的一个活动,虽然现在项目暂时没用到IBM的解决方案,但觉的参与这样一个活动可以拓宽下视野和相关知识.
PL/SQL的过程编程,异常,声明变量,PL/SQL块
百合不是茶
PL/SQL的过程编程 异常 PL/SQL块 声明变量
PL/SQL;
过程;
符号;
变量;
PL/SQL块;
输出;
异常;
PL/SQL 是过程语言(Procedural Language)与结构化查询语言(SQL)结合而成的编程语言PL/SQL 是对 SQL 的扩展,sql的执行时每次都要写操作
Mockito(三)--完整功能介绍
bijian1013
持续集成 mockito 单元测试
mockito官网:http://code.google.com/p/mockito/,打开documentation可以看到官方最新的文档资料。
一.使用mockito验证行为
//首先要import Mockito
import static org.mockito.Mockito.*;
//mo
精通Oracle10编程SQL(8)使用复合数据类型
bijian1013
oracle 数据库 plsql
/*
*使用复合数据类型
*/
--PL/SQL记录
--定义PL/SQL记录
--自定义PL/SQL记录
DECLARE
TYPE emp_record_type IS RECORD(
name emp.ename%TYPE,
salary emp.sal%TYPE,
dno emp.deptno%TYPE
);
emp_
【Linux常用命令一】grep命令
bit1129
Linux常用命令
grep命令格式
grep [option] pattern [file-list]
grep命令用于在指定的文件(一个或者多个,file-list)中查找包含模式串(pattern)的行,[option]用于控制grep命令的查找方式。
pattern可以是普通字符串,也可以是正则表达式,当查找的字符串包含正则表达式字符或者特
mybatis3入门学习笔记
白糖_
sql ibatis qq jdbc 配置管理
MyBatis 的前身就是iBatis,是一个数据持久层(ORM)框架。 MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。MyBatis对JDBC进行了一次很浅的封装。
以前也学过iBatis,因为MyBatis是iBatis的升级版本,最初以为改动应该不大,实际结果是MyBatis对配置文件进行了一些大的改动,使整个框架更加方便人性化。
Linux 命令神器:lsof 入门
ronin47
lsof
lsof是系统管理/安全的尤伯工具。我大多数时候用它来从系统获得与网络连接相关的信息,但那只是这个强大而又鲜为人知的应用的第一步。将这个工具称之为lsof真实名副其实,因为它是指“列出打开文件(lists openfiles)”。而有一点要切记,在Unix中一切(包括网络套接口)都是文件。
有趣的是,lsof也是有着最多
java实现两个大数相加,可能存在溢出。
bylijinnan
java实现
import java.math.BigInteger;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class BigIntegerAddition {
/**
* 题目:java实现两个大数相加,可能存在溢出。
* 如123456789 + 987654321
Kettle学习资料分享,附大神用Kettle的一套流程完成对整个数据库迁移方法
Kai_Ge
Kettle
Kettle学习资料分享
Kettle 3.2 使用说明书
目录
概述..........................................................................................................................................7
1.Kettle 资源库管
[货币与金融]钢之炼金术士
comsci
金融
自古以来,都有一些人在从事炼金术的工作.........但是很少有成功的
那么随着人类在理论物理和工程物理上面取得的一些突破性进展......
炼金术这个古老
Toast原来也可以多样化
dai_lm
android toast
Style 1: 默认
Toast def = Toast.makeText(this, "default", Toast.LENGTH_SHORT);
def.show();
Style 2: 顶部显示
Toast top = Toast.makeText(this, "top", Toast.LENGTH_SHORT);
t
java数据计算的几种解决方法3
datamachine
java hadoop ibatis r-langue r
4、iBatis
简单敏捷因此强大的数据计算层。和Hibernate不同,它鼓励写SQL,所以学习成本最低。同时它用最小的代价实现了计算脚本和JAVA代码的解耦,只用20%的代价就实现了hibernate 80%的功能,没实现的20%是计算脚本和数据库的解耦。
复杂计算环境是它的弱项,比如:分布式计算、复杂计算、非数据
向网页中插入透明Flash的方法和技巧
dcj3sjt126com
html Web Flash
将
Flash 作品插入网页的时候,我们有时候会需要将它设为透明,有时候我们需要在Flash的背面插入一些漂亮的图片,搭配出漂亮的效果……下面我们介绍一些将Flash插入网页中的一些透明的设置技巧。
一、Swf透明、无坐标控制 首先教大家最简单的插入Flash的代码,透明,无坐标控制: 注意wmode="transparent"是控制Flash是否透明
ios UICollectionView的使用
dcj3sjt126com
UICollectionView的使用有两种方法,一种是继承UICollectionViewController,这个Controller会自带一个UICollectionView;另外一种是作为一个视图放在普通的UIViewController里面。
个人更喜欢第二种。下面采用第二种方式简单介绍一下UICollectionView的使用。
1.UIViewController实现委托,代码如
Eos平台java公共逻辑
蕃薯耀
Eos平台java公共逻辑 Eos平台 java公共逻辑
Eos平台java公共逻辑
>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
蕃薯耀 2015年6月1日 17:20:4
SpringMVC4零配置--Web上下文配置【MvcConfig】
hanqunfeng
springmvc4
与SpringSecurity的配置类似,spring同样为我们提供了一个实现类WebMvcConfigurationSupport和一个注解@EnableWebMvc以帮助我们减少bean的声明。
applicationContext-MvcConfig.xml
<!-- 启用注解,并定义组件查找规则 ,mvc层只负责扫描@Controller -->
<
解决ie和其他浏览器poi下载excel文件名乱码
jackyrong
Excel
使用poi,做传统的excel导出,然后想在浏览器中,让用户选择另存为,保存用户下载的xls文件,这个时候,可能的是在ie下出现乱码(ie,9,10,11),但在firefox,chrome下没乱码,
因此必须综合判断,编写一个工具类:
/**
*
* @Title: pro
挥洒泪水的青春
lampcy
编程 生活 程序员
2015年2月28日,我辞职了,离开了相处一年的触控,转过身--挥洒掉泪水,毅然来到了兄弟连,背负着许多的不解、质疑——”你一个零基础、脑子又不聪明的人,还敢跨行业,选择Unity3D?“,”真是不自量力••••••“,”真是初生牛犊不怕虎•••••“,••••••我只是淡淡一笑,拎着行李----坐上了通向挥洒泪水的青春之地——兄弟连!
这就是我青春的分割线,不后悔,只会去用泪水浇灌——已经来到
稳增长之中国股市两点意见-----严控做空,建立涨跌停版停牌重组机制
nannan408
对于股市,我们国家的监管还是有点拼的,但始终拼不过飞流直下的恐慌,为什么呢?
笔者首先支持股市的监管。对于股市越管越荡的现象,笔者认为首先是做空力量超过了股市自身的升力,并且对于跌停停牌重组的快速反应还没建立好,上市公司对于股价下跌没有很好的利好支撑。
我们来看美国和香港是怎么应对股灾的。美国是靠禁止重要股票做空,在
动态设置iframe高度(iframe高度自适应)
Rainbow702
JavaScript iframe contentDocument 高度自适应 局部刷新
如果需要对画面中的部分区域作局部刷新,大家可能都会想到使用ajax。
但有些情况下,须使用在页面中嵌入一个iframe来作局部刷新。
对于使用iframe的情况,发现有一个问题,就是iframe中的页面的高度可能会很高,但是外面页面并不会被iframe内部页面给撑开,如下面的结构:
<div id="content">
<div id=&quo
用Rapael做图表
tntxia
rap
function drawReport(paper,attr,data){
var width = attr.width;
var height = attr.height;
var max = 0;
&nbs
HTML5 bootstrap2网页兼容(支持IE10以下)
xiaoluode
html5 bootstrap
<!DOCTYPE html>
<html>
<head lang="zh-CN">
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">