




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
1、起因:在當(dāng)前我手上的一個項目中需要多個數(shù)據(jù)源,并且來自于不同類型的數(shù)據(jù)庫. 因為很多歷史原因.這個項目的住數(shù)據(jù)源是MySQL,整個系統(tǒng)的CURD都是操作的這個數(shù)據(jù)庫.但是還有另外兩個用于數(shù)據(jù)采集的數(shù)據(jù)庫: MSSQL,ACCESS.還好只是用于數(shù)據(jù)采集,在事務(wù)上可以不要跨數(shù)據(jù)庫了,這一點節(jié)省了好多的工作量. 環(huán)境:我搭建的測試環(huán)境是 spring2.5.6+hibernate3.2 思路:動態(tài)切換數(shù)據(jù)源確切的來說是在同一類型數(shù)據(jù)庫的情況下的。意思就是說 , 在系統(tǒng)中的使用的數(shù)據(jù)庫分布在多臺數(shù)據(jù)庫服務(wù)器或者在同臺服務(wù)器上的多個數(shù)據(jù)庫. 在運行時期間根據(jù)某種標(biāo)識符來動態(tài)的選擇當(dāng)前操作的數(shù)據(jù)庫. 1
2、.數(shù)據(jù)源是相同類型的數(shù)據(jù)庫: 一個SessionFactory+動態(tài)數(shù)據(jù)源+一個事務(wù)管理器 2.數(shù)據(jù)源是不同類型的數(shù)據(jù)庫: 根據(jù)類型 配置多套SessionFactory 模擬:兩個mysql數(shù)據(jù)源+一個Access數(shù)據(jù)源 實現(xiàn): 1.切換數(shù)據(jù)源需要標(biāo)識符,標(biāo)識符是Object類型package lhp.example.context;public enum DBType dataSource1, dataSource2; 2.然后創(chuàng)建一個用于切換數(shù)據(jù)源(設(shè)置或者獲得上下文)的工具類復(fù)制代碼package lhp.example.context;public class ContextHold
3、er private static final ThreadLocal<Object> holder = new ThreadLocal<Object>(); public static void setDbType(DBType dbType) holder.set(dbType); public static DBType getDbType() return (DBType) holder.get(); public static void clearDbType() holder.remove(); 復(fù)制代碼 3.創(chuàng)建動態(tài)數(shù)據(jù)源類,繼承org.springfra
4、mework.jdbc.datasource.lookup.AbstractRoutingDataSource這個類.復(fù)制代碼package lhp.example.context;import java.util.logging.Logger;import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;public class DynamicDataSource extends AbstractRoutingDataSource public static final Logger logger =
5、Logger.getLogger(DynamicDataSource.class.toString(); Override protected Object determineCurrentLookupKey() DBType key = ContextHolder.getDbType();/獲得當(dāng)前數(shù)據(jù)源標(biāo)識符 /("當(dāng)前數(shù)據(jù)源 :" + key); return key; 復(fù)制代碼 4.然后配置多個數(shù)據(jù)源復(fù)制代碼<!- 數(shù)據(jù)源1 : mysql -> <bean id="dataSource1" class=&
6、quot;com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <property name="jdbcUrl" value="jdbc:mysql:/:3306/dec"/> <property name="user" value="root"/> &
7、lt;property name="password" value=""/> </bean> <!- 數(shù)據(jù)源2 : mysql -> <bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="com.mysql.jdbc.Driver"/> <propert
8、y name="jdbcUrl" value="jdbc:mysql:/:3306/lms"/> <property name="user" value="root"/> <property name="password" value=""/> </bean> <!- 數(shù)據(jù)源3 : access -> <bean id="dataSource3" class="com.
9、mchange.v2.c3p0.ComboPooledDataSource"> <property name="driverClass" value="sun.jdbc.odbc.JdbcOdbcDriver"/> <property name="jdbcUrl" value="jdbc:odbc:accessTest"/> <property name="user" value="administrator"/> <
10、property name="password" value="XLZX0309"/> </bean> <!- mysql 動態(tài)數(shù)據(jù)源設(shè)置-> <bean id="mysqlDynamicDataSource" class="lhp.example.context.DynamicDataSource"> <property name="targetDataSources"> <!- 標(biāo)識符類型 -> <map key-typ
11、e="lhp.example.context.DBType"> <entry key="dataSource1" value-ref="dataSource1"/> <entry key="dataSource2" value-ref="dataSource2"/> </map> </property> <property name="defaultTargetDataSource" ref="dataSo
12、urce1"/> </bean> 復(fù)制代碼 5.配置sessionFactory復(fù)制代碼<!- mysql sessionFactory -> <bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource" ref="mysqlDynamicDataSource"/>
13、; <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.hbm2ddl.auto">update</prop>&
14、lt;!-create validate -> <prop key="hibernate.query.substitutions">true 1, false 0</prop> </props> </property> </bean> <!- access sessionFactory -> <bean id="aceessSessionFactory" class="org.springframework.orm.hibernate3.LocalSession
15、FactoryBean"> <property name="dataSource" ref="dataSource3"/> <property name="hibernateProperties"> <props> <!- access 語法和MSSQL相似 所以用的MSSQL方言,或者可以使用第三方方言 -> <prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDial
16、ect</prop> <prop key="hibernate.jdbc.batch_size">30</prop> <prop key="hibernate.jdbc.fetch_size">50</prop> <prop key="hibernate.show_sql">true</prop> <prop key="hibernate.format_sql">false</prop> <prop k
17、ey="hibernate.hbm2ddl.auto">update</prop><!-create validate -> <prop key="hibernate.query.substitutions">true 1, false 0</prop> <prop key="hibernate.cglib.use_reflection_optimizer">true</prop> <!- <prop key="hibernate.ca
18、che.use_second_level_cache">true</prop> -> <!- <prop key="vider_class">org.hibernate.cache.EhCacheProvider</prop> -> <!- <prop key="hibernate.cache.use_query_cache">true</prop> -> <!- <prop key="hi
19、bernate.generate_statistics">true</prop> -> <!- <prop key="vider_configuration_file_resource_path">classpath:ehcache.xml</prop> -> </props> </property> </bean>復(fù)制代碼 6.測試用例復(fù)制代碼package lhp.example.junit;import static org.
20、junit.Assert.*;import java.sql.DatabaseMetaData;import lhp.example.context.ContextHolder;import lhp.example.context.DBType;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.junit.Before;import org.junit.Test;import org.springframework.context.ApplicationContext;import org.s
21、pringframework.context.support.ClassPathXmlApplicationContext;public class ServiceTest private ApplicationContext context; /三個數(shù)據(jù)源的URL private String dataSource1_URL = "jdbc:mysql:/:3306/dec" private String dataSource2_URL = "jdbc:mysql:/:3306/lms" private String
22、 dataSource3_URL = "jdbc:odbc:accessTest" private SessionFactory mysqlSessionFactory; private SessionFactory aceessSessionFactory; Before public void setUp() throws Exception / 選擇數(shù)據(jù)源初始化spring ContextHolder.setDbType(DBType.dataSource1); / String xmlFiles = new String "applicationConte
23、xt-dataSource.xml", "applicationContext-hibernate.xml", "applicationContext-spring.xml" ; / context = new ClassPathXmlApplicationContext(xmlFiles); / mysqlSessionFactory = (SessionFactory) context.getBean("mysqlSessionFactory"); aceessSessionFactory = (SessionFacto
24、ry) context.getBean("aceessSessionFactory"); SuppressWarnings("deprecation") Test public void mysqlDataSourceTest() try Session mysqlSession = mysqlSessionFactory.openSession(); / 獲得數(shù)據(jù)庫元數(shù)據(jù) DatabaseMetaData meatData = mysqlSession.connection().getMetaData(); / 默認啟動數(shù)據(jù)源 dataSource1
25、/斷言當(dāng)前數(shù)據(jù)源URL是否是dataSource1的URL assertEquals(dataSource1_URL, meatData.getURL(); / 切換到數(shù)據(jù)源 dataSource2 ContextHolder.setDbType(DBType.dataSource2); mysqlSession = mysqlSessionFactory.openSession(); meatData = mysqlSession.connection().getMetaData(); /斷言當(dāng)前數(shù)據(jù)源URL是否是dataSource2的URL assertEquals(dataSource
26、2_URL, meatData.getURL(); catch (Exception e) e.printStackTrace(); SuppressWarnings("deprecation") Test public void accessDataSourceTest() try Session accessSession = aceessSessionFactory.openSession(); / 獲得數(shù)據(jù)庫元數(shù)據(jù) DatabaseMetaData meatData = accessSession.connection().getMetaData(); /斷言當(dāng)前數(shù)
27、據(jù)源URL是否是dataSource3的URL assertEquals(dataSource3_URL, meatData.getURL(); catch (Exception e) e.printStackTrace(); 復(fù)制代碼 7.測試結(jié)果spring動態(tài)配置多數(shù)據(jù)源,即在大型應(yīng)用中對數(shù)據(jù)進行切分,并且采用多個數(shù)據(jù)庫實例進行管理,這樣可以有效提高系統(tǒng)的水平伸縮性。而這樣的方案就會不同于常見的單一數(shù)據(jù)實例的方案,這就要程序在運行時根據(jù)當(dāng)時的請求及系統(tǒng)狀態(tài)來動態(tài)的決定將數(shù)據(jù)存儲在哪個數(shù)據(jù)庫實例中,以及從哪個數(shù)據(jù)庫提取數(shù)據(jù)。
28、60; Spring2.x以后的版本中采用Proxy模式,就是我們在方案中實現(xiàn)一個虛擬的數(shù)據(jù)源,并且用它來封裝數(shù)據(jù)源選擇邏輯,這樣就可以有效地將數(shù)據(jù)源選擇邏輯從Client中分離出來。Client提供選擇所需的上下文(因為這是Client所知道的),由虛擬的DataSource根據(jù)Client提供的上下文來實現(xiàn)數(shù)據(jù)源的選擇。實現(xiàn)具體的實現(xiàn)就是,虛擬的DataSource僅需繼承AbstractRoutingDataSource實現(xiàn)determineCurrentLookupKey()在其中封裝數(shù)據(jù)源的選擇邏輯。 一、動態(tài)配置多數(shù)據(jù)源1. 數(shù)據(jù)源的名稱常量類:java vie
29、w plain copy print?1. /* 2. * 動態(tài)配置多數(shù)據(jù)源 3. * 數(shù)據(jù)源的名稱常量類 4. * author LONGHUI_LUO 5. * 6. */ 7. public class DataSourceConst 8. public static final
30、 String TEST="test" 9. public static final String USER="User" 10. 2. 建立一個獲得和設(shè)置上下文環(huán)境的類,主要負責(zé)改變上下文數(shù)據(jù)源的名稱: java view plain copy print?1. /* 2. * 獲得和設(shè)置上下文環(huán)境
31、;主要負責(zé)改變上下文數(shù)據(jù)源的名稱 3. * 4. * author LONGHUI_LUO 5. * 6. */ 7. public class DataSourceContextHolder 8. private static final ThreadLocal contextHolder
32、= new ThreadLocal(); / 線程本地環(huán)境 9. 10. / 設(shè)置數(shù)據(jù)源類型 11. public static void setDataSourceType(String dataSourceType) 12.
33、; contextHolder.set(dataSourceType); 13. 14. 15. / 獲取數(shù)據(jù)源類型 16. public static String getDataSourceType() 17.
34、160; return (String) contextHolder.get(); 18. 19. 20. / 清除數(shù)據(jù)源類型 21. public static void clearDataSourceType() 22.
35、; contextHolder.remove(); 23. 24. 25. 3. 建立動態(tài)數(shù)據(jù)源類,注意,這個類必須繼承AbstractRoutingDataSource,且實現(xiàn)方法determineCurrentLookupKey,該方法返回一個Object,一般是返回字符串: java view plain copy print?1. /*&
36、#160;2. * 建立動態(tài)數(shù)據(jù)源 3. * 4. * author LONGHUI_LUO 5. * 6. */ 7. public class DynamicDataSource extends AbstractRoutingDataSource 8. 9. protected Object
37、0;determineCurrentLookupKey() 10. / 在進行DAO操作前,通過上下文環(huán)境變量,獲得數(shù)據(jù)源的類型 11. return DataSourceContextHolder.getDataSourceType(); 12. 13. 14. 4. 編寫spring的配置文件配置多個數(shù)據(jù)源html view plain cop
38、y print?1. <!- 數(shù)據(jù)源相同的內(nèi)容 -> 2. <bean 3. id="parentDataSource" 4. class="mons.dbcp.Bas
39、icDataSource" 5. destroy-method="close"> 6. <property 7. name="driverClas
40、sName" 8. value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> 9. <property name="username" value="sa&qu
41、ot; /> 10. <property name="password" value="net2com" /> 11. </bean> html view plain copy print?1. <!- start以下配置各個數(shù)據(jù)源的特性 ->
42、;2. <bean parent="parentDataSource" id="testDataSource"> 3. <propertynamepropertyname="url" value="jdbc:sqlserver:/localhost:1433;databaseName=test" />
43、4. </bean> 5. <bean parent="parentDataSource" id="UserDataSource"> 6. <property 7. &
44、#160; name="url" 8. value="jdbc:sqlserver:/localhost:1433;databaseName=User" /> 9. </bean> html view plain copy print?1. <!-
45、160;end 配置各個數(shù)據(jù)源的特性 -> 5. 編寫spring配置文件配置多數(shù)據(jù)源映射關(guān)系html view plain copy print?1. <bean class="com.xxxx.datasouce.DynamicDataSource" id="dataSource"> 2. <property name="targetDataSou
46、rces"> 3. <map key-type="java.lang.String"> 4. <entry value-ref="testDataSource" key="test">&
47、lt;/entry> 5. <entry value-ref="UserDataSource" key="User"></entry> 6. </map> 7.
48、60;</property> 8. <property name="defaultTargetDataSource" ref="testDataSource" ></property> 9. </bean> 在這個配置中第一個property屬性配置目標(biāo)數(shù)據(jù)源,<
49、map key-type="Java.lang.String">中的key-type必須要和靜態(tài)鍵值對照類DataSourceConst中的值的類型相 同;<entry key="User" value-ref="userDataSource"/>中key的值必須要和靜態(tài)鍵值對照類中的值相同,如果有多個值,可以配置多個< entry>標(biāo)簽。第二個property屬性配置默認的數(shù)據(jù)源。 動態(tài)切換是數(shù)據(jù)源java view plain copy print?1. Dat
50、aSourceContextHolder.setDataSourceType(DataSourceConst.TEST); 該方案的優(yōu)勢 首先,這個方案完全是在spring的框架下解決的,數(shù)據(jù)源依然配置在spring的配置文件中,sessionFactory依然去配置它的dataSource屬性,它甚至都不知道dataSource的改變。唯一不同的是在真正的dataSource與sessionFactory之間增加了一個MultiDataSource。其次,實現(xiàn)簡單,易于維護。這個方案雖然
51、我說了這么多東西,其實都是分析,真正需要我們寫的代碼就只有MultiDataSource、SpObserver兩個類。MultiDataSource類真正要寫的只有g(shù)etDataSource()和getDataSource(sp)兩個方法,而SpObserver類更簡單了。實現(xiàn)越簡單,出錯的可能就越小,維護性就越高。最后,這個方案可以使單數(shù)據(jù)源與多數(shù)據(jù)源兼容。這個方案完全不影響B(tài)US和DAO的編寫。如果我們的項目在開始之初是單數(shù)據(jù)源的情況下開發(fā),隨著項目的進行,需要變更為多數(shù)據(jù)源,則只需要修改spring配置,并少量修改MVC層以便在請求中寫入需要的數(shù)據(jù)源名,變更就完成了。如果我們的項目希望改
52、回單數(shù)據(jù)源,則只需要簡單修改配置文件。這樣,為我們的項目將增加更多的彈性。該方案的缺點 沒有能夠解決多用戶訪問單例“sessionFactory”時共享“dataSource”變量,導(dǎo)致產(chǎn)生爭搶“dataSource”的結(jié)果,本質(zhì)類似于操作系統(tǒng)中的“生產(chǎn)者消費者”問題。因此當(dāng)多用戶訪問時,多數(shù)據(jù)源可能會導(dǎo)致系統(tǒng)性能下降的后果。轉(zhuǎn)載我首先想到在spring但是,我很快發(fā)現(xiàn)一個問題:當(dāng)多用戶同時并發(fā)訪問數(shù)據(jù)庫的時候會出現(xiàn)資源爭用的問題。這都是“單例模式”惹的禍。眾所周知,我們在使用spring通過以上的分析,解決多數(shù)據(jù)源訪問問
53、題的關(guān)鍵,就集中在sessionFactory(一) 采用Decorator設(shè)計模式要解決這個問題,我的思路鎖定在了這個dataSource什么是“(二) 設(shè)計MultiDataSource類現(xiàn)在回到我們的問題,我們需要對dataSource對比原Decorator<span times="" span="" private DataSource dataSource = null; public MultiDataSource(DataSource dataSource) this.dataSource = dataSource; /* (non
54、-Javadoc) * see javax.sql.DataSource#getConnection() */ public Connection getConnection() throws SQLException return getDataSource().getConnection(); /其它DataSource接口應(yīng)當(dāng)實現(xiàn)的方法 public DataSource getDataSource() return this.dataSource; public void setDataSource(DataSource dataSource) this.dataSource = da
55、taSource; 客戶在發(fā)出請求的時候,將dataSourceName放到request中,然后把request中的數(shù)據(jù)源名通過調(diào)用new MultiDataSource(dataSource)時可以告訴客戶需要的數(shù)據(jù)源,就可以實現(xiàn)動態(tài)切換數(shù)據(jù)源了。但細心的朋友會發(fā)現(xiàn)這在單例的情況下就是問題的,因為在系統(tǒng)中只有一個對象,它的實例變量也只有一個,就如同一個靜態(tài)變量一般。正因為如此,(三) 單例模式下的MultiDataSource在單例模式下,由于我們在每次調(diào)用MultiDataSource log.debug("dataSourceName:"+dataSourceNam
56、e); try if(dataSourceName=null|dataSourceName.equals("") return this.dataSource; return (DataSource)this.applicationContext.getBean(dataSourceName); catch(NoSuchBeanDefinitionException ex) throw new DaoException("There is not the dataSource 值得一提的是,我需要的數(shù)據(jù)源已經(jīng)都在spring就是其對應(yīng)的<span couri
57、er="" span="" new?;bean id="dataSource1" class="mons.dbcp.BasicDataSource"> <property name="driverClassName"> <value>oracle.jdbc.driver.OracleDrivervalue> property> . bean> <bean id="dataSource2" class="mons.
58、dbcp.BasicDataSource"> <property name="driverClassName"> <value>oracle.jdbc.driver.OracleDrivervalue> property> . bean> 為了得到spring,并且實現(xiàn)方法:java 代碼private ApplicationContext applicationContext = null; public void setApplicationContext(ApplicationContext applicati
59、onContext) throws BeansException this.applicationContext = applicationContext; 如此這樣,我就可以通過得到了。(四) 通過線程傳遞dataSourceName查看以上設(shè)計,MultiDataSource<span times="" span="" roman?;class SpObserver private static ThreadLocal local = new ThreadLocal(); public static void putSp(String sp)
60、local.set(sp); public static String getSp() return (String)local.get(); 做一個filter,將request中的dataSourceName對象。 String sp = SpObserver.getSp(); return getDataSource(sp); 完整的MultiDataSource(五) 動態(tài)添加數(shù)據(jù)源通過以上方案,我們解決了動態(tài)分配數(shù)據(jù)源的問題,但你可能提出疑問:方案中的數(shù)據(jù)源都是配置在spring中(見附件)。不通過配置文件直接加載對象,在的源碼中也有,感興趣的朋友可以自己研究。(六) 在spring
61、中配置在完成了所有這些設(shè)計以后,我最后再嘮叨一句。我們應(yīng)當(dāng)在spring<span times="" span="" roman?;bean id="dynamicLoadBean" class="com.htxx.service.dao.DynamicLoadBean">bean> <bean id="dataSource" class="com.htxx.service.dao.MultiDataSource"> <property n
62、ame="dataSource"> <ref bean="dataSource1" /> property> bean> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="dataSource" /&g
63、t; property> . bean> 其中dataSource以上方案與其它方案相比,它有哪些優(yōu)勢呢?首先,這個方案完全是在spring其次,實現(xiàn)簡單,易于維護。這個方案雖然我說了這么多東西,其實都是分析,真正需要我們寫的代碼就只有MultiDataSource最后,這個方案可以使單數(shù)據(jù)源與多數(shù)據(jù)源兼容。這個方案完全不影響B(tài)US相關(guān)博客:再析在spring框架中解決多數(shù)據(jù)源的問題example.rar 描述: 源碼及示例 下載 文件名: example.rar 文件大小: 32 KB 下載過的: 文件被下載或查看 521 次 再析在spring框架中解決多數(shù)據(jù)源的問題關(guān)鍵字:
64、Spring Hibernate Decorator 設(shè)計模式 如何在spring總結(jié)多數(shù)據(jù)源的問題,其實它需要分為以下三種情況:各個數(shù)據(jù)源的數(shù)據(jù)結(jié)構(gòu)不同、各個數(shù)據(jù)源的數(shù)據(jù)結(jié)構(gòu)相同、各個數(shù)據(jù)源的數(shù)據(jù)結(jié)構(gòu)部分相同又有部分不同。對于第二種情況,各個數(shù)據(jù)源的數(shù)據(jù)結(jié)構(gòu)相同,我們使用一個sessionFactory對于各個數(shù)據(jù)源的數(shù)據(jù)結(jié)構(gòu)不同的情況,使用一個sessionFactory與MultiDataSource在該方案中,SessionFactory接口,Decorator就是MultiSessionFactory,SessionFactory1和SessionFactory2往往是spring的
65、。細心的朋友可能會注意,實際上并不是SessionFactory的時候其實并不是真正地得到了它,而是得到了一個SessionFactory重寫了getObject()。在整個這個方案中,我們需要實現(xiàn)的只有MultiSessionFactory。MultiSessionFactory<span times="" span="" roman?;class MultiSessionFactory implements SessionFactory, ApplicationContextAware private static final long serialVersionUID = 2064557324203496378L; private static final Log log = LogFactory.getLog(MultiSessionFactory.class); priva
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 樁基冬季施工方案
- 農(nóng)業(yè)項目資金籌措方案
- 汽車行業(yè)基礎(chǔ)知識
- 大理石樓地面施工方案
- 紅磚建筑加固施工方案
- 2025年非調(diào)質(zhì)鋼項目發(fā)展計劃
- 山東省濱州市鄒平市2024-2025學(xué)年七年級上學(xué)期期末考試數(shù)學(xué)試卷(原卷版+解析版)
- 非機動車棚工程施工方案
- 隨州鋼結(jié)構(gòu)農(nóng)村房施工方案
- 沂源公路標(biāo)志牌施工方案
- 人文社科書籍《中國在梁莊》
- 2025年上海市中考語文備考之記敘文十大考點梳理(附??季毩?xí)及參考答案)
- 第12課 結(jié)交朋友-初識人工智能(教學(xué)設(shè)計)2023-2024學(xué)年第四冊信息技術(shù)河大版(三起)
- 校園餐專項整治行動工作方案
- RB/T 223-2023國產(chǎn)化檢測儀器設(shè)備驗證評價指南氣相色譜儀
- DB3417-T 031-2024 學(xué)校食堂場所布局設(shè)置規(guī)范
- FANUC機器人培訓(xùn)教程(完成版)
- 《孤獨癥譜系障礙:家長及專業(yè)人員指南》筆記
- 2024年全國職業(yè)院校技能大賽高職組(檢驗檢疫技術(shù)賽項)考試題庫(含答案)
- 博士后研究報告(出站)
- 2024年單招考試題
評論
0/150
提交評論