`
jetway
  • 浏览: 491996 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

解决Spring导致iBatis缓存失效问题

    博客分类:
  • java
 
阅读更多

 

版本:
  Spring 3.0.4(2.x版本中也存在类似问题)
  iBatis 2.3.4.726(2.3.x版本都适用)

起因:
  使用Spring管理iBatis实例,标准方式采用SqlMapClientFactoryBean创建SqlMapClient

 

Java代码   收藏代码
  1. <bean id="sqlMapClient" class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">  
  2.     <property name="configLocation"  
  3.         value="classpath:/com/foo/xxx/sqlMapConfig.xml" />  
  4.     <property name="dataSource" ref="dataSource" />  
  5.     <property name="mappingLocations" value="classpath*:/**/sqlmap/*SqlMap.xml" />  
  6. </bean>  



使用mappingLocations方式定义可以让sqlmap不必添加到sqlMapConfig.xml
即避免了如下形式

 

 

Java代码   收藏代码
  1. <sqlMapConfig>  
  2. ...  
  3.   <sqlMap url="someSqlMap" resource="com/foo/xxx/someSqlMap.xml"/>  
  4. ...  
  5. </sqlMapConfig>  

 

随之而来的问题是在sqlMap中的cache无法在执行预订方法时自动flush!

Java代码   收藏代码
  1. <cacheModel id="mycache" type ="LRU" readOnly="false" serialize="false">  
  2.   <flushInterval hours="24"/>  
  3.   <flushOnExecute statement="myobj.insert"/>  
  4.   <property name="cache-size" value="50" />  
  5. </cacheModel>  

 

在myobj.insert被执行时cache不会flush,即无报错也无提醒,彻头彻尾的坑爹,不清楚Spring开发组为什么会让这问题一直存在。

产生问题的原因网上有不少分析贴(不再重复,需要的可搜索相关帖子),原因是Spring在处理mappingLocations之前,iBatis已经完成对sqlMapConfig里注册的sqlMap的cache设置(真绕口=.="),非亲生的sqlMap被无情的抛弃了。解决办法大都建议放弃mappingLocations的方式,把sqlMap写到sqlMapConfig里——还真是够简单——或者说够偷懒。

找到原因就想办法解决吧,从SqlMapClientFactoryBean下手,扩展一份

Java代码   收藏代码
  1. /** 
  2.  
  3. * @author Foxswily 
  4. */  
  5.   
  6. @SuppressWarnings("deprecation")  
  7. public class MySqlMapClientFactoryBean implements FactoryBean<SqlMapClient>,  
  8.         InitializingBean {  
  9.   
  10.     private static final ThreadLocal<LobHandler> configTimeLobHandlerHolder = new ThreadLocal<LobHandler>();  
  11.   
  12.     /** 
  13.      * Return the LobHandler for the currently configured iBATIS SqlMapClient, 
  14.      * to be used by TypeHandler implementations like ClobStringTypeHandler. 
  15.      * <p> 
  16.      * This instance will be set before initialization of the corresponding 
  17.      * SqlMapClient, and reset immediately afterwards. It is thus only available 
  18.      * during configuration. 
  19.      *  
  20.      * @see #setLobHandler 
  21.      * @see org.springframework.orm.ibatis.support.ClobStringTypeHandler 
  22.      * @see org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler 
  23.      * @see org.springframework.orm.ibatis.support.BlobSerializableTypeHandler 
  24.      */  
  25.     public static LobHandler getConfigTimeLobHandler() {  
  26.         return configTimeLobHandlerHolder.get();  
  27.     }  
  28.   
  29.     private Resource[] configLocations;  
  30.   
  31.     private Resource[] mappingLocations;  
  32.   
  33.     private Properties sqlMapClientProperties;  
  34.   
  35.     private DataSource dataSource;  
  36.   
  37.     private boolean useTransactionAwareDataSource = true;  
  38.   
  39.     @SuppressWarnings("rawtypes")  
  40.     private Class transactionConfigClass = ExternalTransactionConfig.class;  
  41.   
  42.     private Properties transactionConfigProperties;  
  43.   
  44.     private LobHandler lobHandler;  
  45.   
  46.     private SqlMapClient sqlMapClient;  
  47.   
  48.     public MySqlMapClientFactoryBean() {  
  49.         this.transactionConfigProperties = new Properties();  
  50.         this.transactionConfigProperties.setProperty("SetAutoCommitAllowed""false");  
  51.     }  
  52.   
  53.     /** 
  54.      * Set the location of the iBATIS SqlMapClient config file. A typical value 
  55.      * is "WEB-INF/sql-map-config.xml". 
  56.      *  
  57.      * @see #setConfigLocations 
  58.      */  
  59.     public void setConfigLocation(Resource configLocation) {  
  60.         this.configLocations = (configLocation != null ? new Resource[] { configLocation }  
  61.                 : null);  
  62.     }  
  63.   
  64.     /** 
  65.      * Set multiple locations of iBATIS SqlMapClient config files that are going 
  66.      * to be merged into one unified configuration at runtime. 
  67.      */  
  68.     public void setConfigLocations(Resource[] configLocations) {  
  69.         this.configLocations = configLocations;  
  70.     }  
  71.   
  72.     /** 
  73.      * Set locations of iBATIS sql-map mapping files that are going to be merged 
  74.      * into the SqlMapClient configuration at runtime. 
  75.      * <p> 
  76.      * This is an alternative to specifying "&lt;sqlMap&gt;" entries in a 
  77.      * sql-map-client config file. This property being based on Spring's 
  78.      * resource abstraction also allows for specifying resource patterns here: 
  79.      * e.g. "/myApp/*-map.xml". 
  80.      * <p> 
  81.      * Note that this feature requires iBATIS 2.3.2; it will not work with any 
  82.      * previous iBATIS version. 
  83.      */  
  84.     public void setMappingLocations(Resource[] mappingLocations) {  
  85.         this.mappingLocations = mappingLocations;  
  86.     }  
  87.   
  88.     /** 
  89.      * Set optional properties to be passed into the SqlMapClientBuilder, as 
  90.      * alternative to a <code>&lt;properties&gt;</code> tag in the 
  91.      * sql-map-config.xml file. Will be used to resolve placeholders in the 
  92.      * config file. 
  93.      *  
  94.      * @see #setConfigLocation 
  95.      * @see com.ibatis.sqlmap.client.SqlMapClientBuilder#buildSqlMapClient(java.io.InputStream, 
  96.      *      java.util.Properties) 
  97.      */  
  98.     public void setSqlMapClientProperties(Properties sqlMapClientProperties) {  
  99.         this.sqlMapClientProperties = sqlMapClientProperties;  
  100.     }  
  101.   
  102.     /** 
  103.      * Set the DataSource to be used by iBATIS SQL Maps. This will be passed to 
  104.      * the SqlMapClient as part of a TransactionConfig instance. 
  105.      * <p> 
  106.      * If specified, this will override corresponding settings in the 
  107.      * SqlMapClient properties. Usually, you will specify DataSource and 
  108.      * transaction configuration <i>either</i> here <i>or</i> in SqlMapClient 
  109.      * properties. 
  110.      * <p> 
  111.      * Specifying a DataSource for the SqlMapClient rather than for each 
  112.      * individual DAO allows for lazy loading, for example when using 
  113.      * PaginatedList results. 
  114.      * <p> 
  115.      * With a DataSource passed in here, you don't need to specify one for each 
  116.      * DAO. Passing the SqlMapClient to the DAOs is enough, as it already 
  117.      * carries a DataSource. Thus, it's recommended to specify the DataSource at 
  118.      * this central location only. 
  119.      * <p> 
  120.      * Thanks to Brandon Goodin from the iBATIS team for the hint on how to make 
  121.      * this work with Spring's integration strategy! 
  122.      *  
  123.      * @see #setTransactionConfigClass 
  124.      * @see #setTransactionConfigProperties 
  125.      * @see com.ibatis.sqlmap.client.SqlMapClient#getDataSource 
  126.      * @see SqlMapClientTemplate#setDataSource 
  127.      * @see SqlMapClientTemplate#queryForPaginatedList 
  128.      */  
  129.     public void setDataSource(DataSource dataSource) {  
  130.         this.dataSource = dataSource;  
  131.     }  
  132.   
  133.     /** 
  134.      * Set whether to use a transaction-aware DataSource for the SqlMapClient, 
  135.      * i.e. whether to automatically wrap the passed-in DataSource with Spring's 
  136.      * TransactionAwareDataSourceProxy. 
  137.      * <p> 
  138.      * Default is "true": When the SqlMapClient performs direct database 
  139.      * operations outside of Spring's SqlMapClientTemplate (for example, lazy 
  140.      * loading or direct SqlMapClient access), it will still participate in 
  141.      * active Spring-managed transactions. 
  142.      * <p> 
  143.      * As a further effect, using a transaction-aware DataSource will apply 
  144.      * remaining transaction timeouts to all created JDBC Statements. This means 
  145.      * that all operations performed by the SqlMapClient will automatically 
  146.      * participate in Spring-managed transaction timeouts. 
  147.      * <p> 
  148.      * Turn this flag off to get raw DataSource handling, without Spring 
  149.      * transaction checks. Operations on Spring's SqlMapClientTemplate will 
  150.      * still detect Spring-managed transactions, but lazy loading or direct 
  151.      * SqlMapClient access won't. 
  152.      *  
  153.      * @see #setDataSource 
  154.      * @see org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy 
  155.      * @see org.springframework.jdbc.datasource.DataSourceTransactionManager 
  156.      * @see SqlMapClientTemplate 
  157.      * @see com.ibatis.sqlmap.client.SqlMapClient 
  158.      */  
  159.     public void setUseTransactionAwareDataSource(boolean useTransactionAwareDataSource) {  
  160.         this.useTransactionAwareDataSource = useTransactionAwareDataSource;  
  161.     }  
  162.   
  163.     /** 
  164.      * Set the iBATIS TransactionConfig class to use. Default is 
  165.      * <code>com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig</code> 
  166.      * . 
  167.      * <p> 
  168.      * Will only get applied when using a Spring-managed DataSource. An instance 
  169.      * of this class will get populated with the given DataSource and 
  170.      * initialized with the given properties. 
  171.      * <p> 
  172.      * The default ExternalTransactionConfig is appropriate if there is external 
  173.      * transaction management that the SqlMapClient should participate in: be it 
  174.      * Spring transaction management, EJB CMT or plain JTA. This should be the 
  175.      * typical scenario. If there is no active transaction, SqlMapClient 
  176.      * operations will execute SQL statements non-transactionally. 
  177.      * <p> 
  178.      * JdbcTransactionConfig or JtaTransactionConfig is only necessary when 
  179.      * using the iBATIS SqlMapTransactionManager API instead of external 
  180.      * transactions. If there is no explicit transaction, SqlMapClient 
  181.      * operations will automatically start a transaction for their own scope (in 
  182.      * contrast to the external transaction mode, see above). 
  183.      * <p> 
  184.      * <b>It is strongly recommended to use iBATIS SQL Maps with Spring 
  185.      * transaction management (or EJB CMT).</b> In this case, the default 
  186.      * ExternalTransactionConfig is fine. Lazy loading and SQL Maps operations 
  187.      * without explicit transaction demarcation will execute 
  188.      * non-transactionally. 
  189.      * <p> 
  190.      * Even with Spring transaction management, it might be desirable to specify 
  191.      * JdbcTransactionConfig: This will still participate in existing 
  192.      * Spring-managed transactions, but lazy loading and operations without 
  193.      * explicit transaction demaration will execute in their own auto-started 
  194.      * transactions. However, this is usually not necessary. 
  195.      *  
  196.      * @see #setDataSource 
  197.      * @see #setTransactionConfigProperties 
  198.      * @see com.ibatis.sqlmap.engine.transaction.TransactionConfig 
  199.      * @see com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig 
  200.      * @see com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig 
  201.      * @see com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig 
  202.      * @see com.ibatis.sqlmap.client.SqlMapTransactionManager 
  203.      */  
  204.     @SuppressWarnings("rawtypes")  
  205.     public void setTransactionConfigClass(Class transactionConfigClass) {  
  206.         if (transactionConfigClass == null  
  207.                 || !TransactionConfig.class.isAssignableFrom(transactionConfigClass)) {  
  208.             throw new IllegalArgumentException(  
  209.                     "Invalid transactionConfigClass: does not implement "  
  210.                             + "com.ibatis.sqlmap.engine.transaction.TransactionConfig");  
  211.         }  
  212.         this.transactionConfigClass = transactionConfigClass;  
  213.     }  
  214.   
  215.     /** 
  216.      * Set properties to be passed to the TransactionConfig instance used by 
  217.      * this SqlMapClient. Supported properties depend on the concrete 
  218.      * TransactionConfig implementation used: 
  219.      * <p> 
  220.      * <ul> 
  221.      * <li><b>ExternalTransactionConfig</b> supports "DefaultAutoCommit" 
  222.      * (default: false) and "SetAutoCommitAllowed" (default: true). Note that 
  223.      * Spring uses SetAutoCommitAllowed = false as default, in contrast to the 
  224.      * iBATIS default, to always keep the original autoCommit value as provided 
  225.      * by the connection pool. 
  226.      * <li><b>JdbcTransactionConfig</b> does not supported any properties. 
  227.      * <li><b>JtaTransactionConfig</b> supports "UserTransaction" (no default), 
  228.      * specifying the JNDI location of the JTA UserTransaction (usually 
  229.      * "java:comp/UserTransaction"). 
  230.      * </ul> 
  231.      *  
  232.      * @see com.ibatis.sqlmap.engine.transaction.TransactionConfig#initialize 
  233.      * @see com.ibatis.sqlmap.engine.transaction.external.ExternalTransactionConfig 
  234.      * @see com.ibatis.sqlmap.engine.transaction.jdbc.JdbcTransactionConfig 
  235.      * @see com.ibatis.sqlmap.engine.transaction.jta.JtaTransactionConfig 
  236.      */  
  237.     public void setTransactionConfigProperties(Properties transactionConfigProperties) {  
  238.         this.transactionConfigProperties = transactionConfigProperties;  
  239.     }  
  240.   
  241.     /** 
  242.      * Set the LobHandler to be used by the SqlMapClient. Will be exposed at 
  243.      * config time for TypeHandler implementations. 
  244.      *  
  245.      * @see #getConfigTimeLobHandler 
  246.      * @see com.ibatis.sqlmap.engine.type.TypeHandler 
  247.      * @see org.springframework.orm.ibatis.support.ClobStringTypeHandler 
  248.      * @see org.springframework.orm.ibatis.support.BlobByteArrayTypeHandler 
  249.      * @see org.springframework.orm.ibatis.support.BlobSerializableTypeHandler 
  250.      */  
  251.     public void setLobHandler(LobHandler lobHandler) {  
  252.         this.lobHandler = lobHandler;  
  253.     }  
  254.   
  255.     public void afterPropertiesSet() throws Exception {  
  256.         if (this.lobHandler != null) {  
  257.             // Make given LobHandler available for SqlMapClient configuration.  
  258.             // Do early because because mapping resource might refer to custom  
  259.             // types.  
  260.             configTimeLobHandlerHolder.set(this.lobHandler);  
  261.         }  
  262.   
  263.         try {  
  264.             this.sqlMapClient = buildSqlMapClient(this.configLocations,  
  265.                     this.mappingLocations, this.sqlMapClientProperties);  
  266.   
  267.             // Tell the SqlMapClient to use the given DataSource, if any.  
  268.             if (this.dataSource != null) {  
  269.                 TransactionConfig transactionConfig = (TransactionConfig) this.transactionConfigClass  
  270.                         .newInstance();  
  271.                 DataSource dataSourceToUse = this.dataSource;  
  272.                 if (this.useTransactionAwareDataSource  
  273.                         && !(this.dataSource instanceof TransactionAwareDataSourceProxy)) {  
  274.                     dataSourceToUse = new TransactionAwareDataSourceProxy(this.dataSource);  
  275.                 }  
  276.                 transactionConfig.setDataSource(dataSourceToUse);  
  277.                 transactionConfig.initialize(this.transactionConfigProperties);  
  278.                 applyTransactionConfig(this.sqlMapClient, transactionConfig);  
  279.             }  
  280.         }  
  281.   
  282.         finally {  
  283.             if (this.lobHandler != null) {  
  284.                 // Reset LobHandler holder.  
  285.                 configTimeLobHandlerHolder.set(null);  
  286.             }  
  287.         }  
  288.     }  
  289.   
  290.     /** 
  291.      * Build a SqlMapClient instance based on the given standard configuration. 
  292.      * <p> 
  293.      * The default implementation uses the standard iBATIS 
  294.      * {@link SqlMapClientBuilder} API to build a SqlMapClient instance based on 
  295.      * an InputStream (if possible, on iBATIS 2.3 and higher) or on a Reader (on 
  296.      * iBATIS up to version 2.2). 
  297.      *  
  298.      * @param configLocations 
  299.      *            the config files to load from 
  300.      * @param properties 
  301.      *            the SqlMapClient properties (if any) 
  302.      * @return the SqlMapClient instance (never <code>null</code>) 
  303.      * @throws IOException 
  304.      *             if loading the config file failed 
  305.      * @throws NoSuchFieldException 
  306.      * @throws SecurityException 
  307.      * @throws IllegalAccessException 
  308.      * @throws IllegalArgumentException 
  309.      * @throws NoSuchMethodException 
  310.      * @throws InvocationTargetException 
  311.      * @see com.ibatis.sqlmap.client.SqlMapClientBuilder#buildSqlMapClient 
  312.      */  
  313.     protected SqlMapClient buildSqlMapClient(Resource[] configLocations,  
  314.             Resource[] mappingLocations, Properties properties) throws IOException,  
  315.             SecurityException, NoSuchFieldException, IllegalArgumentException,  
  316.             IllegalAccessException, NoSuchMethodException, InvocationTargetException {  
  317.   
  318.         if (ObjectUtils.isEmpty(configLocations)) {  
  319.             throw new IllegalArgumentException(  
  320.                     "At least 1 'configLocation' entry is required");  
  321.         }  
  322.   
  323.         SqlMapClient client = null;  
  324.         SqlMapConfigParser configParser = new SqlMapConfigParser();  
  325.         for (Resource configLocation : configLocations) {  
  326.             InputStream is = configLocation.getInputStream();  
  327.             try {  
  328.                 client = configParser.parse(is, properties);  
  329.             } catch (RuntimeException ex) {  
  330.                 throw new NestedIOException("Failed to parse config resource: "  
  331.                         + configLocation, ex.getCause());  
  332.             }  
  333.         }  
  334.   
  335.         if (mappingLocations != null) {  
  336.             SqlMapParser mapParser = SqlMapParserFactory.createSqlMapParser(configParser);  
  337.             for (Resource mappingLocation : mappingLocations) {  
  338.                 try {  
  339.                     mapParser.parse(mappingLocation.getInputStream());  
  340.                 } catch (NodeletException ex) {  
  341.                     throw new NestedIOException("Failed to parse mapping resource: "  
  342.                             + mappingLocation, ex);  
  343.                 }  
  344.             }  
  345.         }  
  346.         //*************其实只改这一点而已,为了方便他人,全source贴出**************  
  347.         //为了取sqlMapConfig,反射private的field  
  348.         Field stateField = configParser.getClass().getDeclaredField("state");  
  349.         stateField.setAccessible(true);  
  350.         XmlParserState state = (XmlParserState) stateField.get(configParser);  
  351.         SqlMapConfiguration sqlMapConfig = state.getConfig();  
  352.         //反射取设置cache的方法,执行  
  353.         Method wireUpCacheModels = sqlMapConfig.getClass().getDeclaredMethod(  
  354.                 "wireUpCacheModels");  
  355.         wireUpCacheModels.setAccessible(true);  
  356.         wireUpCacheModels.invoke(sqlMapConfig);  
  357.         //*************************************************************************  
  358.         return client;  
  359.     }  
  360.   
  361.     /**  
  362.      * Apply the given iBATIS TransactionConfig to the SqlMapClient.  
  363.      * <p>  
  364.      * The default implementation casts to ExtendedSqlMapClient, retrieves the  
  365.      * maximum number of concurrent transactions from the  
  366.      * SqlMapExecutorDelegate, and sets an iBATIS TransactionManager with the  
  367.      * given TransactionConfig.  
  368.      *   
  369.      * @param sqlMapClient  
  370.      *            the SqlMapClient to apply the TransactionConfig to  
  371.      * @param transactionConfig  
  372.      *            the iBATIS TransactionConfig to apply  
  373.      * @see com.ibatis.sqlmap.engine.impl.ExtendedSqlMapClient  
  374.      * @see com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate#getMaxTransactions  
  375.      * @see com.ibatis.sqlmap.engine.impl.SqlMapExecutorDelegate#setTxManager  
  376.      */  
  377.     protected void applyTransactionConfig(SqlMapClient sqlMapClient,  
  378.             TransactionConfig transactionConfig) {  
  379.         if (!(sqlMapClient instanceof ExtendedSqlMapClient)) {  
  380.             throw new IllegalArgumentException(  
  381.                     "Cannot set TransactionConfig with DataSource for SqlMapClient if not of type "  
  382.                             + "ExtendedSqlMapClient: " + sqlMapClient);  
  383.         }  
  384.         ExtendedSqlMapClient extendedClient = (ExtendedSqlMapClient) sqlMapClient;  
  385.         transactionConfig.setMaximumConcurrentTransactions(extendedClient.getDelegate()  
  386.                 .getMaxTransactions());  
  387.         extendedClient.getDelegate().setTxManager(  
  388.                 new TransactionManager(transactionConfig));  
  389.     }  
  390.   
  391.     public SqlMapClient getObject() {  
  392.         return this.sqlMapClient;  
  393.     }  
  394.   
  395.     public Class<? extends SqlMapClient> getObjectType() {  
  396.         return (this.sqlMapClient != null ? this.sqlMapClient.getClass()  
  397.                 : SqlMapClient.class);  
  398.     }  
  399.   
  400.     public boolean isSingleton() {  
  401.         return true;  
  402.     }  
  403.   
  404.     /** 
  405.      * Inner class to avoid hard-coded iBATIS 2.3.2 dependency (XmlParserState 
  406.      * class). 
  407.      */  
  408.     private static class SqlMapParserFactory {  
  409.   
  410.         public static SqlMapParser createSqlMapParser(SqlMapConfigParser configParser) {  
  411.             // Ideally: XmlParserState state = configParser.getState();  
  412.             // Should raise an enhancement request with iBATIS...  
  413.             XmlParserState state = null;  
  414.             try {  
  415.                 Field stateField = SqlMapConfigParser.class.getDeclaredField("state");  
  416.                 stateField.setAccessible(true);  
  417.                 state = (XmlParserState) stateField.get(configParser);  
  418.             } catch (Exception ex) {  
  419.                 throw new IllegalStateException(  
  420.                         "iBATIS 2.3.2 'state' field not found in SqlMapConfigParser class - "  
  421.                                 + "please upgrade to IBATIS 2.3.2 or higher in order to use the new 'mappingLocations' feature. "  
  422.                                 + ex);  
  423.             }  
  424.             return new SqlMapParser(state);  
  425.         }  
  426.     }  
  427.   
  428. }  

 

修改Spring配置文件

Java代码   收藏代码
  1. <bean id="sqlMapClient" class="com.foo.xxx.MySqlMapClientFactoryBean">  
  2.   <property name="configLocation"  
  3. value="classpath:/com/foo/xxx/sqlMapConfig.xml" />  
  4.   <property name="dataSource" ref="dataSource" />  
  5.   <property name="mappingLocations" value="classpath*:/**/sqlmap/*SqlMap.xml" />  
  6. </bean>  

 
至此,cache又工作如初了。
编后:
·反射会消耗,但仅仅在初始化时一次性消耗,还可以接受。
·iBatis的cache能力比较弱,但没太多要求的情况下是个省事的方案,聊胜于无。
·Mybatis3.0的cache暂时不用为好,EhCache选项本身还有bug,实在很无语。

分享到:
评论

相关推荐

    MyBatis.md

    根据提供的文件信息,“MyBatis.md”文档主要探讨了MyBatis框架的源码实现及其与Spring框架集成时出现的一级缓存失效问题。本文将深入解析MyBatis的核心组件如Configuration、SqlSession等,并针对MyBatis与Spring...

    mybatis学习笔记

    - **测试2**:展示缓存失效的情况。 - **二级缓存**:跨`SqlSession`的缓存。 - **原理**:基于磁盘或内存的缓存机制。 - **开启二级缓存**:配置文件中的设置。 - **实现序列化**:满足二级缓存的要求。 - **...

    java面试知识

    - **监控**:跟踪进度,解决问题。 - **收尾**:完成项目交付物,评估项目成果。 #### 框架篇 ##### Struts1的运行原理 - **ActionServlet**:前端控制器,接收用户请求。 - **ActionForm**:封装用户输入数据。 ...

    RSMA-Rate-Splitting-通信系统仿真-速率拆分

    《RSMA与速率拆分在有限反馈通信系统中的MMSE基预编码实现》 本文将深入探讨RSMA(Rate Splitting Multiple Access)技术在有限反馈通信系统中的应用,特别是通过MMSE(Minimum Mean Square Error)基预编码进行的实现。速率拆分是现代多用户通信系统中一种重要的信号处理策略,它能够提升系统的频谱效率和鲁棒性,特别是在资源受限和信道条件不理想的环境中。RSMA的核心思想是将用户的数据流分割成公共和私有信息两部分,公共信息可以被多个接收器解码,而私有信息仅由特定的接收器解码。这种方式允许系统在用户间共享信道资源,同时保证了每个用户的个性化服务。 在有限反馈通信系统中,由于信道状态信息(CSI)的获取通常是有限且不精确的,因此选择合适的预编码技术至关重要。MMSE预编码是一种优化策略,其目标是在考虑信道噪声和干扰的情况下最小化期望平方误差。在RSMA中,MMSE预编码用于在发射端对数据流进行处理,以减少接收端的干扰,提高解码性能。 以下代码研究RSMA与MMSE预编码的结合以观察到如何在实际系统中应用RSMA的速率拆分策略,并结合有限的反馈信息设计有效的预编码矩阵。关键步骤包括: 1. **信道模型的建立**:模拟多用户MIMO环境,考虑不同用户之间的信道条件差异。 2. **信道反馈机制**:设计有限反馈方案,用户向基站发送关于信道状态的简化的反馈信息。 3. **MMSE预编码矩阵计算**:根据接收到的有限反馈信息,计算出能够最小化期望平方误差的预编码矩阵。 4. **速率拆分**:将每个用户的传输信息划分为公共和私有两部分。 5. **信号发射与接收**:使用预编码矩阵对信号进行处理,然后在接收端进行解码。 6. **性能评估**:分析系统吞吐量、误码率等性能指标,对比不同策略的效果。

    【地理空间Python教程】使用XEE从Google Earth Engine下载图像:肯尼亚人口网格数据GeoTIFF文件生成方法介绍了如何使用XEE

    内容概要:本文档介绍了如何使用 XEE 包从 Google Earth Engine 下载图像数据并保存为 GeoTIFF 文件。主要内容包括:1) 使用新的 ee.data.getPixels() API 和 XEE 包简化了从 GEE 提取大型数据集的过程;2) 通过 XArray 数据集和 rioxarray 工具直接处理和保存图像数据,避免了复杂的导出任务;3) 具体示例展示了如何下载肯尼亚 2021 年的 LandScan 人口网格数据,包括环境搭建、数据准备、图像处理和最终保存为 GeoTIFF 文件。 适合人群:具备一定 Python 编程基础和地理信息系统(GIS)知识的开发者或研究人员,特别是对地理空间数据分析和遥感图像处理感兴趣的用户。 使用场景及目标:① 在基于 Python 的工作流中快速高效地提取和处理托管在 GEE 上的大规模地理空间数据;② 学习如何使用 XEE 包和相关工具进行地理空间数据的下载、裁剪、投影转换和保存;③ 通过实际案例掌握地理空间数据的处理技巧,提高数据处理效率和准确性。 其他说明:此教程提供了详细的代码示例和操作步骤,帮助用户在 Google Colab 环境中完成整个数据下载和处理过程。用户需要具备一定的 Python 编程能力,并熟悉常用的地理空间数据处理工具和库,如 geopandas、rioxarray 和 xarray。此外,教程还强调了数据版权和来源的重要性,确保用户合法合规地使用数据。

    基于STM32的工业级锅炉控制器系统设计:外设驱动、数据采集与通信协议实现

    内容概要:本文详细介绍了基于STM32F407的锅炉控制器系统设计,涵盖多个关键技术点。首先,在SD卡驱动方面,采用了硬件SPI配置,波特率为10.5MHz,并通过DMA发送80个空时钟进行初始化。其次,多路AD采集使用差分输入模式和DMA循环采集,配合滑动平均滤波提高效率。此外,Modbus通信部分通过结构体映射寄存器并使用硬件CRC单元进行校验。文件系统则采用FatFs结合SPI Flash缓存,确保断电保护。实时监控线程使用状态机设计,确保系统稳定性和安全性。硬件设计方面,模拟电路与数字电路分区布局,增强抗干扰能力。 适合人群:具备一定嵌入式开发基础的研发人员,特别是希望深入了解工业级项目设计的工程师。 使用场景及目标:适用于工业自动化领域的嵌入式系统开发,旨在帮助工程师掌握从硬件选型、外设驱动、数据采集到通信协议实现的全流程设计方法,提升系统的可靠性和实时性。 其他说明:文中提供了详细的代码示例和设计思路,强调了实际项目中的注意事项和常见问题解决方案,有助于读者快速上手并应用于实际项目中。

    基于MATLAB的配电网二阶锥优化:OLTC档位选择与123型支路的最优潮流研究

    内容概要:本文详细介绍了基于MATLAB实现的配电网二阶锥最优潮流研究,重点探讨了OLTC(有载调压变压器)档位选择和123型支路的优化方法。通过构建SOCP(二阶锥规划)模型,结合YALMIP和CPLEX求解器,实现了高效的潮流优化。文中提供了详细的代码示例和解释,涵盖系统参数定义、模型构建、约束添加以及求解过程。此外,还讨论了OLTC档位选择的离散变量建模、支路类型的差异化处理、动态优化的时间轴管理等方面的技术细节。 适合人群:对电力系统优化感兴趣的科研人员、研究生及有一定编程基础的工程师。 使用场景及目标:适用于配电网优化研究和实际工程应用,旨在提高潮流计算的效率和准确性,解决传统方法在复杂约束下的不足。通过学习本文,读者可以掌握如何利用MATLAB和相关工具进行二阶锥优化,从而更好地应对电力系统中的各种挑战。 其他说明:文章附带详细的代码注释和讲解视频,帮助读者快速理解和应用所介绍的方法和技术。

    临时网盘、企业内部共享网盘

    前端将文件切片上传服务器返回提取码,前端通过输入提取码下载文件。 编写语言php,html,js 运行环境要求:windows 10专业版64位,Apache2.4.39,PHP7.4.3nts,MySQL5.7.26。

    【Python开发】VSCode配置Python开发环境全流程:从安装到调试与依赖管理

    内容概要:本文档详细介绍了在Visual Studio Code (VSCode)中配置Python开发环境的步骤。首先,需安装Python并确保它被添加到系统的环境变量中,接着安装VSCode及其官方Python扩展,还可以安装Pylance、Jupyter等可选扩展来增强功能。然后,配置Python解释器,推荐创建和使用虚拟环境以隔离项目依赖。配置调试环境包括创建`launch.json`文件,以便能顺利运行和调试代码。此外,还应安装代码格式化和Lint工具如pylint、autopep8或black,并在VSCode的设置中启用它们,以保证代码质量和一致性。最后,文档提供了关于如何运行和调试代码以及管理项目依赖的方法,并列举了一些常见问题及解决办法。; 适合人群:初学者或有一定经验的Python开发者,希望在VSCode中搭建高效Python开发环境的人员。; 使用场景及目标:①为新项目搭建完整的Python开发环境;②优化现有开发环境,提高开发效率;③解决VSCode中Python开发遇到的基本问题。; 阅读建议:按照文档步骤顺序操作,确保每一步都成功完成再进行下一步,特别是要注意安装过程中的一些细节选项,如将Python添加到环境变量等。对于遇到的问题,可以参考文档最后列出的常见问题解答。

    基于西门子200Smart的凸轮飞剪控制系统设计与实现

    内容概要:本文详细介绍了基于西门子200Smart PLC的凸轮飞剪控制系统的设计与实现。主要内容涵盖硬件配置(如主轴编码器、伺服电机、触摸屏)、关键PLC编程技巧(如同步触发逻辑、高速中断处理、加减速曲线配置)、以及现场调试经验(如温度补偿、方向控制、误差处理)。文中特别强调了同步触发逻辑和加减速曲线对系统稳定性的影响,并分享了多个实用的调试技巧和技术难点解决方案。 适合人群:具备PLC编程基础的技术人员,特别是从事自动化控制领域的工程师。 使用场景及目标:适用于工业生产线中需要高精度同步控制的应用场景,如包装机、切割机等。目标是帮助技术人员理解和掌握凸轮飞剪系统的实现方法,提高生产效率和产品质量。 其他说明:文中提供了大量具体的代码示例和调试经验,有助于读者快速上手并应用于实际项目中。同时,文中提到的一些优化措施(如温度补偿、编码器断线检测等)对于提升系统的可靠性和稳定性具有重要价值。

    汇川H5U运动控制框架模板:高效、模块化的工业自动化解决方案

    内容概要:本文介绍了汇川H5U运动控制框架模板的特点及其应用场景。该框架提供了高度模块化的设计,使得伺服轴控、气缸控制以及与爱普生机器人的EIP通讯变得极为简便。框架内置了丰富的功能块(FB),如AxisControl_FB用于伺服轴控制,Cylinder_FB用于气缸控制,EpsonEIP_Data用于机器人通信。这些FB块不仅简化了编程流程,还集成了诸如互锁保护、超时检测等功能,极大提高了开发效率和系统稳定性。此外,框架支持结构体嵌套应用,便于参数管理和在线修改,确保项目的灵活性和可扩展性。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是那些希望提高开发效率、减少重复劳动的人群。 使用场景及目标:适用于各种运动控制项目,如流水线自动化、机器人控制等。主要目标是帮助工程师快速搭建稳定的控制系统,缩短开发周期,降低调试难度,提升系统的可靠性和性能。 其他说明:框架内的注释详尽且为中文,非常适合初学者理解和学习。对于有经验的工程师而言,该框架同样提供了一个高效的开发平台,能够显著提升工作效率。

    含绿证交易与碳排放优化的智能楼宇微网调度模型

    内容概要:本文介绍了一个复杂的电热综合能源系统优化调度模型,该模型不仅涵盖了传统的风光储火微网,还包括了电动汽车和智能楼宇单元。模型通过线性规划求解最优调度方案,同时考虑了碳市场和绿色证书交易市场的影响。代码实现了微网各单元的初始化、优化调度的核心算法以及碳市场和绿色证书交易的成本调整。此外,模型还涉及了多时间尺度的优化问题处理、热电耦合约束、市场交易机制的设计等方面。 适用人群:从事能源优化、微网调度研究的专业人士,尤其是对碳市场和绿色证书交易感兴趣的科研人员和技术开发者。 使用场景及目标:适用于需要进行复杂微网系统优化调度的研究和应用场合,旨在降低总成本并减少碳排放,提高能源利用效率。具体目标包括优化风光储火微网的调度策略,最大化绿色证书收益,最小化碳交易成本,提升电动汽车和智能楼宇的调度灵活性。 其他说明:该模型展示了如何通过引入碳市场和绿色证书交易机制来改善微网系统的性能,提供了详细的代码实现和理论解释,有助于理解和实践相关领域的前沿技术。

    基于改进粒子群算法的园区综合能源优化调度:含电动汽车参与的MATLAB实现

    内容概要:本文详细介绍了基于改进粒子群算法的园区综合能源优化调度方法及其MATLAB代码实现。文中首先分析了园区综合能源系统中的三个主要市场交易主体:系统能源运营商、分布式光伏用户和电动汽车充电代理商。接着,通过定义各主体的相关参数,建立了综合能量管理优化策略。然后,采用改进的粒子群算法对模型进行了求解,展示了粒子群算法的初始化、适应度函数定义及优化过程。最后,通过具体算例验证了该方法的有效性,特别是在冬季典型场景下的表现。文章强调了电动汽车在能源调度中的重要作用,以及改进粒子群算法在处理光伏出力突变等复杂场景时的优势。 适合人群:从事能源管理系统研究的技术人员、研究生及以上学历的科研工作者、对MATLAB编程有一定基础的学习者。 使用场景及目标:适用于希望深入了解园区综合能源系统优化调度方法的研究人员和技术人员。目标是掌握如何通过改进粒子群算法实现含电动汽车参与的能源优化调度,提高能源利用效率,降低成本。 其他说明:文章提供了详细的代码示例和解释,帮助读者更好地理解和实现该方法。同时,文中提到的多个改进点和注意事项也为进一步研究提供了方向。

    某全域旅游大数据信息系统建设方案Word(38页).docx

    在探索智慧旅游的新纪元中,一个集科技、创新与服务于一体的整体解决方案正悄然改变着我们的旅行方式。智慧旅游,作为智慧城市的重要分支,旨在通过新一代信息技术,如云计算、大数据、物联网等,为游客、旅游企业及政府部门提供无缝对接、高效互动的旅游体验与管理模式。这一方案不仅重新定义了旅游行业的服务标准,更开启了旅游业数字化转型的新篇章。 智慧旅游的核心在于“以人为本”,它不仅仅关注技术的革新,更注重游客体验的提升。从游前的行程规划、信息查询,到游中的智能导航、个性化导览,再到游后的心情分享、服务评价,智慧旅游通过构建“一云多屏”的服务平台,让游客在旅游的全过程中都能享受到便捷、个性化的服务。例如,游客可以通过手机APP轻松定制专属行程,利用智能语音导览深入了解景点背后的故事,甚至通过三维GIS地图实现虚拟漫游,提前感受目的地的魅力。这些创新服务不仅增强了游客的参与感和满意度,也让旅游变得更加智能化、趣味化。 此外,智慧旅游还为旅游企业和政府部门带来了前所未有的管理变革。通过大数据分析,旅游企业能够精准把握市场动态,实现旅游产品的精准营销和个性化推荐,从而提升市场竞争力。而政府部门则能利用智慧旅游平台实现对旅游资源的科学规划和精细管理,提高监管效率和质量。例如,通过实时监控和数据分析,政府可以迅速应对旅游高峰期的客流压力,有效预防景区超载,保障游客安全。同时,智慧旅游还促进了跨行业、跨部门的数据共享与协同合作,为旅游业的可持续发展奠定了坚实基础。总之,智慧旅游以其独特的魅力和无限潜力,正引领着旅游业迈向一个更加智慧、便捷、高效的新时代。

    工业自动化中变频器频率与线速度转换的Python实现及优化

    内容概要:本文详细介绍了如何将变频器的输出频率转换为实际线速度的方法及其Python实现。首先给出了基本的数学公式和基础版本的Python代码,然后逐步引入了单位换算、异常处理、移动平均滤波等优化措施。此外,还讨论了如何通过Modbus协议与PLC通信获取实时频率数据,并强调了参数准确性的重要性。文中提供了多个测试案例,展示了不同应用场景下的计算方法和注意事项。 适合人群:从事工业自动化领域的工程师和技术人员,尤其是需要进行变频器相关工作的人员。 使用场景及目标:适用于需要精确控制生产线速度的各种场合,如包装生产线、输送系统等。主要目标是帮助工程师快速准确地计算并监控变频器驱动的传送带或其他机械设备的实际运行速度。 其他说明:文章不仅提供了具体的代码实现,还分享了许多实用的经验和技巧,如参数校验、单位转换、异常处理等,有助于提高系统的稳定性和可靠性。同时,作者还提到可以通过图形化界面或HMI设备进一步提升用户体验。

    工业自动化中恒压供水系统的西门子200 SMART与ABB ACS510变频器控制逻辑解析

    内容概要:本文详细介绍了基于西门子200 SMART PLC和ABB ACS510变频器构建的恒压供水系统。该系统实现了泵数量自适应、时间轮换机制、频率控制、故障替换逻辑以及多段压力控制等功能。文中通过具体的梯形图和结构化文本(ST)代码片段解释了各个功能模块的工作原理和技术细节。例如,泵数量自适应通过VB100寄存器动态调整泵的数量;时间轮换机制利用指针寻址和环形队列确保泵的均匀使用;频率控制采用PID调节,并提供PLC和变频器两种PID控制方式的选择;故障替换逻辑设有‘三次重试’机制,保障系统的可靠性;多段压力控制则通过环形缓冲区存储24小时压力设定值,优化能源消耗。此外,系统还采用了频率滞回比较算法和平滑过渡策略,使得管网压力波动保持在较小范围内。 适用人群:从事工业自动化领域的工程师和技术人员,尤其是对PLC编程和变频器应用有一定基础的人群。 使用场景及目标:适用于中小型项目的恒压供水系统设计与实施。主要目标是提高系统的灵活性、可靠性和能效,减少设备磨损,降低运维成本。 其他说明:文中提到的一些具体实现方法如指针寻址、环形队列、PID参数设置等,对于理解和掌握现代工业控制系统具有重要价值。同时,文中提供的代码片段可以直接用于实际工程中,帮助工程师快速搭建高效稳定的恒压供水系统。

    MATLAB环境中基于最大重叠离散小波变换的ECG信号处理与多领域应用

    内容概要:本文详细介绍了在MATLAB环境下使用最大重叠离散小波变换(MODWT)对心电信号(ECG)进行处理的方法。首先解释了MODWT的基本概念及其相对于传统离散小波变换的优势,特别是在处理ECG信号时能够保持平移不变性。接着阐述了具体的处理流程,包括删除伪影、滤波降噪以及检测PQRST波并确定心跳等步骤。文中提供了详细的MATLAB代码示例,展示了如何通过选择合适的小波基和分解层数来优化信号处理效果。此外,还讨论了该算法在金融时间序列、地震信号和其他生理信号处理中的广泛应用潜力。 适合人群:从事生物医学信号处理的研究人员和技术爱好者,尤其是那些希望深入了解ECG信号处理原理的人群。 使用场景及目标:适用于需要精确分析一维时间序列信号的各种应用场景,如医疗诊断系统中ECG信号的自动分析,金融市场趋势预测,地震预警系统的信号处理等。目标是提高信号处理精度,减少噪声干扰,从而获得更加可靠的数据支持决策。 其他说明:文中提到的一些具体参数设置(如阈值的选择),可以根据实际情况灵活调整。同时提醒读者,在处理长时间连续记录的信号时需要注意内存管理问题。

    超表面全息技术中MIM结构的高效几何相位与FDTD仿真解析

    内容概要:本文详细介绍了基于金-氟化镁-金(MIM)结构的超表面全息技术,特别是其高效的几何相位调制和FDTD仿真方法。文章首先解释了MIM结构的独特之处,即通过磁偶极子模式降低辐射损耗,从而显著提高转换效率。接着,文章展示了如何使用FDTD Solutions进行建模,包括设置材料参数、纳米柱尺寸以及应用周期性边界条件。此外,还讨论了几何相位的计算方法及其在相位调制中的应用,并提供了具体的MATLAB代码示例。对于GS算法的应用,文中提出了改进措施以加快收敛速度并提高全息图的质量。最后,文章强调了在效率验证过程中需要注意的技术细节,如正确配置功率监视器和考虑边界效应。 适合人群:从事超表面研究、光学工程、纳米技术和电磁仿真的研究人员和技术人员。 使用场景及目标:适用于希望深入了解MIM结构在超表面全息领域的应用,掌握高效几何相位调制和FDTD仿真的具体实现方法的研究人员。目标是帮助读者理解并复现实验室级别的高效率超表面全息系统。 其他说明:文章不仅提供了详细的理论背景,还包括了大量的代码片段和实践经验,有助于读者更好地理解和应用相关技术。

    示波器基础知识.pdf### 示波器础知识总结

    内容概要:本文档详细介绍了示波器的基础知识,包括其工作原理、分类、关键组件(如CRT、偏转系统、触发系统等)以及各种控制功能。文章首先解释了示波器与普通电压表的区别,强调了示波器能以图形方式显示电压随时间的变化。接着深入探讨了模拟示波器的构造和工作方式,如垂直和水平偏转系统、灵敏度控制、耦合方式、带宽、上升时间等。随后介绍了数字存储示波器(DSO)的特点,包括数字存储、采样和数字化、预触发和后触发、峰值检测等功能。文档还对比了模拟示波器和DSO的优缺点,指出组合示波器兼具两者优势。最后,文档讨论了探头的工作原理、类型及其它附件和软件,帮助用户选择合适的示波器和探头。 适用人群:电子工程师、技术人员、科研人员以及对示波器有兴趣的学习者。 使用场景及目标:①理解示波器的工作原理和基本构造;②掌握模拟示波器和数字存储示波器的操作方法及应用场景;③选择合适的示波器和探头进行电路测试和信号分析;④利用示波器的高级功能(如预触发、峰值检测、自动测量等)提高工作效率。 其他说明:本文档不仅提供了理论知识,还结合实际应用案例,帮助读者更好地理解和使用示波器。文档内容详尽,涵盖了从基础到高级的各种知识点,适合不同层次的读者学习和参考。

    力士乐伺服系统IndraWorks Ds调试技巧与参数优化详解

    内容概要:本文详细介绍了力士乐伺服调试软件IndraWorks Ds 14V24 P5与15V16版本的调试经验和参数优化方法。主要内容涵盖参数映射规则、PID增益设置、通讯配置、心跳检测脚本、速度环调试、轴参数互锁机制、VBA脚本应用、XML配置管理、实时曲线对比、参数备份策略等方面。特别强调了不同版本之间的兼容性和特殊调试技巧,如惯量比设置、加速度斜坡时间调整、动态磁链补偿等。此外,还提供了多个实用的调试工具和技术细节,帮助工程师提高工作效率并解决常见问题。 适合人群:从事伺服控制系统调试的技术人员、自动化工程师以及相关领域的研究人员。 使用场景及目标:适用于力士乐伺服系统的安装、调试和维护过程中,旨在帮助工程师快速掌握关键调试技巧,优化系统性能,减少调试时间和错误发生率。 其他说明:文中提供的具体参数设置和脚本代码均经过实际验证,能够显著提升调试效果。建议读者结合自身应用场景灵活运用这些技术和经验。

Global site tag (gtag.js) - Google Analytics