版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、DroolsJAVA規(guī)則引擎(非常好的一篇教程) Drools是一個(gè)基于java的規(guī)則引擎,開源的,可以將復(fù)雜多變的規(guī)則從硬編碼中解放出來(lái),以規(guī)則腳本的形式存放在文件中,使得規(guī)則的變更不需要修正代碼重啟機(jī)器就可以立即在線上環(huán)境生效。 本文所使用的demo已上傳 1、Drools語(yǔ)法開始語(yǔ)法之前首先要了解一下drools的基本工作過(guò)程,通常而言我們使用一個(gè)接口來(lái)做事情,首先要穿進(jìn)去參數(shù),其次要獲取到接口的實(shí)現(xiàn)執(zhí)行完畢后的結(jié)果,而drools也是一樣的,我們需要傳遞進(jìn)去數(shù)據(jù),用于規(guī)則的檢查,調(diào)用外部接口,同時(shí)還可能需要獲取到規(guī)則執(zhí)行完畢后得到的結(jié)果。在drools中,這個(gè)傳遞數(shù)據(jù)進(jìn)去的對(duì)象,術(shù)語(yǔ)叫
2、 Fact對(duì)象。Fact對(duì)象是一個(gè)普通的java bean,規(guī)則中可以對(duì)當(dāng)前的對(duì)象進(jìn)行任何的讀寫操作,調(diào)用該對(duì)象提供的方法,當(dāng)一個(gè)java bean插入到workingMemory中,規(guī)則使用的是原有對(duì)象的引用,規(guī)則通過(guò)對(duì)fact對(duì)象的讀寫,實(shí)現(xiàn)對(duì)應(yīng)用數(shù)據(jù)的讀寫,對(duì)于其中的屬性,需要提供getter setter訪問(wèn)器,規(guī)則中,可以動(dòng)態(tài)的往當(dāng)前workingMemory中插入刪除新的fact對(duì)象。規(guī)則文件可以使用 .drl文件,也可以是xml文件,這里我們使用drl文件。規(guī)則語(yǔ)法:package:對(duì)一個(gè)規(guī)則文件而言,package是必須定義的,必須放在規(guī)則文件第一行。特別的是,package的
3、名字是隨意的,不必必須對(duì)應(yīng)物理路徑,跟java的package的概念不同,這里只是邏輯上的一種區(qū)分。同樣的package下定義的function和query等可以直接使用。比如:package com.drools.demo.pointimport:導(dǎo)入規(guī)則文件需要使用到的外部變量,這里的使用方法跟java相同,但是不同于java的是,這里的import導(dǎo)入的不僅僅可以是一個(gè)類,也可以是這個(gè)類中的某一個(gè)可訪問(wèn)的靜態(tài)方法。比如:import com.drools.demo.point.PointDomain;import com.drools.demo.point.PointDomain.get
4、ById;rule:定義一個(gè)規(guī)則。rule ruleName。一個(gè)規(guī)則可以包含三個(gè)部分:屬性部分:定義當(dāng)前規(guī)則執(zhí)行的一些屬性等,比如是否可被重復(fù)執(zhí)行、過(guò)期時(shí)間、生效時(shí)間等。條件部分,即LHS,定義當(dāng)前規(guī)則的條件,如 when Message(); 判斷當(dāng)前workingMemory中是否存在Message對(duì)象。結(jié)果部分,即RHS,這里可以寫普通java代碼,即當(dāng)前規(guī)則條件滿足后執(zhí)行的操作,可以直接調(diào)用Fact對(duì)象的方法來(lái)操作應(yīng)用。規(guī)則事例:rule name no-loop true when $message:Message(status = 0) then System.out.print
5、ln(fit); $message.setStatus(1); update($message);end上述的屬性中:no-loop : 定義當(dāng)前的規(guī)則是否不允許多次循環(huán)執(zhí)行,默認(rèn)是false,也就是當(dāng)前的規(guī)則只要滿足條件,可以無(wú)限次執(zhí)行。什么情況下會(huì)出現(xiàn)一條規(guī)則執(zhí)行過(guò)一次又被多次重復(fù)執(zhí)行呢?drools提供了一些api,可以對(duì)當(dāng)前傳入workingMemory中的Fact對(duì)象進(jìn)行修改或者個(gè)數(shù)的增減,比如上述的update方法,就是將當(dāng)前的workingMemory中的Message類型的Fact對(duì)象進(jìn)行屬性更新,這種操作會(huì)觸發(fā)規(guī)則的重新匹配執(zhí)行,可以理解為Fact對(duì)象更新了,所以規(guī)則需要重新
6、匹配一遍,那么疑問(wèn)是之前規(guī)則執(zhí)行過(guò)并且修改過(guò)的那些Fact對(duì)象的屬性的數(shù)據(jù)會(huì)不會(huì)被重置?結(jié)果是不會(huì),已經(jīng)修改過(guò)了就不會(huì)被重置,update之后,之前的修改都會(huì)生效。當(dāng)然對(duì)Fact對(duì)象數(shù)據(jù)的修改并不是一定需要調(diào)用update才可以生效,簡(jiǎn)單的使用set方法設(shè)置就可以完成,這里類似于java的引用調(diào)用,所以何時(shí)使用update是一個(gè)需要仔細(xì)考慮的問(wèn)題,一旦不慎,極有可能會(huì)造成規(guī)則的死循環(huán)。上述的no-loop true,即設(shè)置當(dāng)前的規(guī)則,只執(zhí)行一次,如果本身的RHS部分有update等觸發(fā)規(guī)則重新執(zhí)行的操作,也不要再次執(zhí)行當(dāng)前規(guī)則。但是其他的規(guī)則會(huì)被重新執(zhí)行,豈不是也會(huì)有可能造成多次重復(fù)執(zhí)行,數(shù)據(jù)
7、紊亂甚至死循環(huán)?答案是使用其他的標(biāo)簽限制,也是可以控制的:lock-on-active truelock-on-active true:通過(guò)這個(gè)標(biāo)簽,可以控制當(dāng)前的規(guī)則只會(huì)被執(zhí)行一次,因?yàn)橐粋€(gè)規(guī)則的重復(fù)執(zhí)行不一定是本身觸發(fā)的,也可能是其他規(guī)則觸發(fā)的,所以這個(gè)是no-loop的加強(qiáng)版。當(dāng)然該標(biāo)簽正規(guī)的用法會(huì)有其他的標(biāo)簽的配合,后續(xù)提及。date-expires:設(shè)置規(guī)則的過(guò)期時(shí)間,默認(rèn)的時(shí)間格式:“日-月-年”,中英文格式相同,但是寫法要用各自對(duì)應(yīng)的語(yǔ)言,比如中文:29-七月-2010,但是還是推薦使用更為精確和習(xí)慣的格式,這需要手動(dòng)在java代碼中設(shè)置當(dāng)前系統(tǒng)的時(shí)間格式,后續(xù)提及。屬性用法舉例
8、:date-expires 2011-01-31 23:59:59 / 這里我們使用了更為習(xí)慣的時(shí)間格式date-effective:設(shè)置規(guī)則的生效時(shí)間,時(shí)間格式同上。duration:規(guī)則定時(shí),duration 3000 3秒后執(zhí)行規(guī)則salience:優(yōu)先級(jí),數(shù)值越大越先執(zhí)行,這個(gè)可以控制規(guī)則的執(zhí)行順序。其他的屬性可以參照相關(guān)的api文檔查看具體用法,此處略。 規(guī)則的條件部分,即LHS部分:when:規(guī)則條件開始。條件可以單個(gè),也可以多個(gè),多個(gè)條件一次排列,比如 when eval(true) $customer:Customer() $message:Message(status=0)上
9、述羅列了三個(gè)條件,當(dāng)前規(guī)則只有在這三個(gè)條件都匹配的時(shí)候才會(huì)執(zhí)行RHS部分,三個(gè)條件中第一個(gè)eval(true):是一個(gè)默認(rèn)的api,true 無(wú)條件執(zhí)行,類似于 while(true)$message:Message(status=0) 這句話標(biāo)示的:當(dāng)前的workingMemory存在Message類型并且status屬性的值為0的Fact對(duì)象,這個(gè)對(duì)象通常是通過(guò)外部java代碼插入或者自己在前面已經(jīng)執(zhí)行的規(guī)則的RHS部分中insert進(jìn)去的。前面的$message代表著當(dāng)前條件的引用變量,在后續(xù)的條件部分和RHS部分中,可以使用當(dāng)前的變量去引用符合條件的FACT對(duì)象,修改屬性或者調(diào)用方法等
10、??蛇x,如果不需要使用,則可以不寫。條件可以有組合,比如:Message(status=0 | (status > 1 && status <=100)RHS中對(duì)Fact對(duì)象private屬性的操作必須使用getter和setter方法,而RHS中則必須要直接用.的方法去使用,比如 $order:Order(name=qu) $message:Message(status=0 && orders contains $order && $=qu)特別的是,如果條件全部是 &&關(guān)系,可以使用“,”來(lái)替代
11、,但是兩者不能混用如果現(xiàn)在Fact對(duì)象中有一個(gè)List,需要判斷條件,如何判斷呢?看一個(gè)例子:Message int status; List<String> names;$message:Message(status=0 && names contains 網(wǎng)易 && names.size >= 1)上述的條件中,status必須是0,并且names列表中含有“網(wǎng)易”并且列表長(zhǎng)度大于等于1contains:對(duì)比是否包含操作,操作的被包含目標(biāo)可以是一個(gè)復(fù)雜對(duì)象也可以是一個(gè)簡(jiǎn)單的值。 Drools提供了十二中類型比較操作符: > >=
12、 < <= = != contains / not contains / memberOf / not memberOf /matches/ not matchesnot contains:與contains相反。memberOf:判斷某個(gè)Fact屬性值是否在某個(gè)集合中,與contains不同的是他被比較的對(duì)象是一個(gè)集合,而contains被比較的對(duì)象是單個(gè)值或者對(duì)象。not memberOf:正好相反。matches:正則表達(dá)式匹配,與java不同的是,不用考慮/的轉(zhuǎn)義問(wèn)題not matches:正好相反。 規(guī)則的結(jié)果部分當(dāng)規(guī)則條件滿足,則進(jìn)入規(guī)則結(jié)果部分執(zhí)行,結(jié)果部分可以是純j
13、ava代碼,比如:then System.out.println(OK); /會(huì)在控制臺(tái)打印出okend當(dāng)然也可以調(diào)用Fact的方法,比如 $message.execute();操作數(shù)據(jù)庫(kù)等等一切操作。結(jié)果部分也有drools提供的方法:insert:往當(dāng)前workingMemory中插入一個(gè)新的Fact對(duì)象,會(huì)觸發(fā)規(guī)則的再次執(zhí)行,除非使用no-loop限定;update:更新modify:修改,與update語(yǔ)法不同,結(jié)果都是更新操作retract:刪除RHS部分除了調(diào)用Drools提供的api和Fact對(duì)象的方法,也可以調(diào)用規(guī)則文件中定義的方法,方法的定義使用 function 關(guān)鍵字fu
14、nction void console System.out.println(); StringUtils.getId();/ 調(diào)用外部靜態(tài)方法,StringUtils必須使用import導(dǎo)入,getId()必須是靜態(tài)方法Drools還有一個(gè)可以定義類的關(guān)鍵字:declare 可以再規(guī)則文件中定義一個(gè)class,使用起來(lái)跟普通java對(duì)象相似,你可以在RHS部分中new一個(gè)并且使用getter和setter方法去操作其屬性。declare Address author(quzishen) / 元數(shù)據(jù),僅用于描述信息 createTime(2011-1-24) city : String max
15、Lengh(100) postno : intend上述的是什么呢?是元數(shù)據(jù)定義,用于描述數(shù)據(jù)的數(shù)據(jù),沒什么執(zhí)行含義你可以在RHS部分中使用Address address = new Address()的方法來(lái)定義一個(gè)對(duì)象。 更多的規(guī)則語(yǔ)法,可以參考其他互聯(lián)網(wǎng)資料,推薦:(寫的很基礎(chǔ),但是部分語(yǔ)法寫的有些簡(jiǎn)單,含糊不好理解)2、Drools應(yīng)用實(shí)例:現(xiàn)在我們模擬一個(gè)應(yīng)用場(chǎng)景:網(wǎng)站伴隨業(yè)務(wù)產(chǎn)生而進(jìn)行的積分發(fā)放操作。比如支付寶信用卡還款獎(jiǎng)勵(lì)積分等。發(fā)放積分可能伴隨不同的運(yùn)營(yíng)策略和季節(jié)性調(diào)整,發(fā)放數(shù)目和規(guī)則完全不同,如果使用硬編碼的方式去伴隨業(yè)務(wù)調(diào)整而修改,代碼的修改、管理、優(yōu)化、測(cè)試、上線將是一件
16、非常麻煩的事情,所以,將發(fā)放規(guī)則部分提取出來(lái),交給Drools管理,可以極大程度的解決這個(gè)問(wèn)題。(注意一點(diǎn)的是,并非所有的規(guī)則相關(guān)內(nèi)容都建議使用Drools,這其中要考慮系統(tǒng)會(huì)運(yùn)行多久,規(guī)則變更頻率等一系列條件,如果你的系統(tǒng)只會(huì)在線上運(yùn)行一周,那根本沒必要選擇Drools來(lái)加重你的開發(fā)成本,java硬編碼的方式則將是首選)我們定義一下發(fā)放規(guī)則:積分的發(fā)放參考因素有:交易筆數(shù)、交易金額數(shù)目、信用卡還款次數(shù)、生日特別優(yōu)惠等。定義規(guī)則:/ 過(guò)生日,則加10分,并且將當(dāng)月交易比數(shù)翻倍后再計(jì)算積分/ 2011-01-08 - 2011-08-08每月信用卡還款3次以上,每滿3筆贈(zèng)送30分/ 當(dāng)月購(gòu)物總金
17、額100以上,每100元贈(zèng)送10分/ 當(dāng)月購(gòu)物次數(shù)5次以上,每五次贈(zèng)送50分/ 特別的,如果全部滿足了要求,則額外獎(jiǎng)勵(lì)100分/ 發(fā)生退貨,扣減10分/ 退貨金額大于100,扣減100分在事先分析過(guò)程中,我們需要全面的考慮對(duì)于積分所需要的因素,以此整理抽象Fact對(duì)象,通過(guò)上述的假設(shè)條件,我們假設(shè)積分計(jì)算對(duì)象如下:java view plaincopy/* * 積分計(jì)算對(duì)象 * author quzishen */ public class PointDomain / 用戶名 private String userName; / 是否當(dāng)日生日 private boolean birthDay;
18、 / 增加積分?jǐn)?shù)目 private long point; / 當(dāng)月購(gòu)物次數(shù) private int buyNums; / 當(dāng)月退貨次數(shù) private int backNums; / 當(dāng)月購(gòu)物總金額 private double buyMoney; / 當(dāng)月退貨總金額 private double backMondy; / 當(dāng)月信用卡還款次數(shù) private int billThisMonth; /* * 記錄積分發(fā)送流水,防止重復(fù)發(fā)放 * param userName 用戶名 * param type 積分發(fā)放類型 */ public void recordPointLog(String
19、userName, String type) System.out.println(增加對(duì)+userName+的類型為+type+的積分操作記錄.); public String getUserName() return userName; / 其他getter setter方法省略 定義積分規(guī)則接口java view plaincopy/* * 規(guī)則接口 * author quzishen */ public interface PointRuleEngine /* * 初始化規(guī)則引擎 */ public void initEngine(); /* * 刷新規(guī)則引擎中的規(guī)則 */ publi
20、c void refreshEnginRule(); /* * 執(zhí)行規(guī)則引擎 * param pointDomain 積分Fact */ public void executeRuleEngine(final PointDomain pointDomain); 規(guī)則接口實(shí)現(xiàn),Drools的API很簡(jiǎn)單,可以參考相關(guān)API文檔查看具體用法:java view plaincopyimport java.io.File; import java.io.FileNotFoundException; import java.io.FileReader; import java.io.IOExceptio
21、n; import java.io.Reader; import java.util.ArrayList; import java.util.List; import org.drools.RuleBase; import org.drools.StatefulSession; import piler.DroolsParserException; import piler.PackageBuilder; import org.drools.spi.Activation; /* * 規(guī)則接口實(shí)現(xiàn)類 * author quzishen */ public class PointRuleEngin
22、eImpl implements PointRuleEngine private RuleBase ruleBase; /* (non-Javadoc) * see com.drools.demo.point.PointRuleEngine#initEngine() */ public void initEngine() / 設(shè)置時(shí)間格式 System.setProperty(drools.dateformat, yyyy-MM-dd HH:mm:ss); ruleBase = RuleBaseFacatory.getRuleBase(); try PackageBuilder backage
23、Builder = getPackageBuilderFromDrlFile(); ruleBase.addPackages(backageBuilder.getPackages(); catch (DroolsParserException e) e.printStackTrace(); catch (IOException e) e.printStackTrace(); catch (Exception e) e.printStackTrace(); /* (non-Javadoc) * see com.drools.demo.point.PointRuleEngine#refreshEn
24、ginRule() */ public void refreshEnginRule() ruleBase = RuleBaseFacatory.getRuleBase(); org.drools.rule.Package packages = ruleBase.getPackages(); for(org.drools.rule.Package pg : packages) ruleBase.removePackage(pg.getName(); initEngine(); /* (non-Javadoc) * see com.drools.demo.point.PointRuleEngine
25、#executeRuleEngine(com.drools.demo.point.PointDomain) */ public void executeRuleEngine(final PointDomain pointDomain) if(null = ruleBase.getPackages() | 0 = ruleBase.getPackages().length) return; StatefulSession statefulSession = ruleBase.newStatefulSession(); statefulSession.insert(pointDomain); /
26、fire statefulSession.fireAllRules(new org.drools.spi.AgendaFilter() public boolean accept(Activation activation) return !activation.getRule().getName().contains(_test); ); statefulSession.dispose(); /* * 從Drl規(guī)則文件中讀取規(guī)則 * return * throws Exception */ private PackageBuilder getPackageBuilderFromDrlFile
27、() throws Exception / 獲取測(cè)試腳本文件 List<String> drlFilePath = getTestDrlFile(); / 裝載測(cè)試腳本文件 List<Reader> readers = readRuleFromDrlFile(drlFilePath); PackageBuilder backageBuilder = new PackageBuilder(); for (Reader r : readers) backageBuilder.addPackageFromDrl(r); / 檢查腳本是否有問(wèn)題 if(backageBuilde
28、r.hasErrors() throw new Exception(backageBuilder.getErrors().toString(); return backageBuilder; /* * param drlFilePath 腳本文件路徑 * return * throws FileNotFoundException */ private List<Reader> readRuleFromDrlFile(List<String> drlFilePath) throws FileNotFoundException if (null = drlFilePath
29、| 0 = drlFilePath.size() return null; List<Reader> readers = new ArrayList<Reader>(); for (String ruleFilePath : drlFilePath) readers.add(new FileReader(new File(ruleFilePath); return readers; /* * 獲取測(cè)試規(guī)則文件 * * return */ private List<String> getTestDrlFile() List<String> drlF
30、ilePath = new ArrayList<String>(); drlFilePath .add(D:/workspace2/DroolsDemo/src/com/drools/demo/point/addpoint.drl); drlFilePath .add(D:/workspace2/DroolsDemo/src/com/drools/demo/point/subpoint.drl); return drlFilePath; 為了獲取單實(shí)例的RuleBase,我們定義一個(gè)工廠類java view plaincopyimport org.drools.RuleBase;
31、import org.drools.RuleBaseFactory; /* * RuleBaseFacatory 單實(shí)例RuleBase生成工具 * author quzishen */ public class RuleBaseFacatory private static RuleBase ruleBase; public static RuleBase getRuleBase() return null != ruleBase ? ruleBase : RuleBaseFactory.newRuleBase(); 剩下的就是定義兩個(gè)規(guī)則文件,分別用于積分發(fā)放和積分扣減addpoint.d
32、rljava view plaincopypackage com.drools.demo.point import com.drools.demo.point.PointDomain; rule birthdayPoint / 過(guò)生日,則加10分,并且將當(dāng)月交易比數(shù)翻倍后再計(jì)算積分 salience 100 lock-on-active true when $pointDomain : PointDomain(birthDay = true) then $pointDomain.setPoint($pointDomain.getPoint()+10); $pointDomain.setBuyN
33、ums($pointDomain.getBuyNums()*2); $pointDomain.setBuyMoney($pointDomain.getBuyMoney()*2); $pointDomain.setBillThisMonth($pointDomain.getBillThisMonth()*2); $pointDomain.recordPointLog($pointDomain.getUserName(),birthdayPoint); end rule billThisMonthPoint / 2011-01-08 - 2011-08-08每月信用卡還款3次以上,每滿3筆贈(zèng)送30
34、分 salience 99 lock-on-active true date-effective 2011-01-08 23:59:59 date-expires 2011-08-08 23:59:59 when $pointDomain : PointDomain(billThisMonth >= 3) then $pointDomain.setPoint($pointDomain.getPoint()+$pointDomain.getBillThisMonth()/3*30); $pointDomain.recordPointLog($pointDomain.getUserName(
35、),billThisMonthPoint); end rule buyMoneyPoint / 當(dāng)月購(gòu)物總金額100以上,每100元贈(zèng)送10分 salience 98 lock-on-active true when $pointDomain : PointDomain(buyMoney >= 100) then $pointDomain.setPoint($pointDomain.getPoint()+ (int)$pointDomain.getBuyMoney()/100 * 10); $pointDomain.recordPointLog($pointDomain.getUserN
36、ame(),buyMoneyPoint); end rule buyNumsPoint / 當(dāng)月購(gòu)物次數(shù)5次以上,每五次贈(zèng)送50分 salience 97 lock-on-active true when $pointDomain : PointDomain(buyNums >= 5) then $pointDomain.setPoint($pointDomain.getPoint()+$pointDomain.getBuyNums()/5 * 50); $pointDomain.recordPointLog($pointDomain.getUserName(),buyNumsPoint
37、); end rule allFitPoint / 特別的,如果全部滿足了要求,則額外獎(jiǎng)勵(lì)100分 salience 96 lock-on-active true when $pointDomain:PointDomain(buyNums >= 5 && billThisMonth >= 3 && buyMoney >= 100) then $pointDomain.setPoint($pointDomain.getPoint()+ 100); $pointDomain.recordPointLog($pointDomain.getUserNa
38、me(),allFitPoint); end subpoint.drljava view plaincopypackage com.drools.demo.point import com.drools.demo.point.PointDomain; rule subBackNumsPoint / 發(fā)生退貨,扣減10分 salience 10 lock-on-active true when $pointDomain : PointDomain(backNums >= 1) then $pointDomain.setPoint($pointDomain.getPoint()-10); $
39、pointDomain.recordPointLog($pointDomain.getUserName(),subBackNumsPoint); end rule subBackMondyPoint / 退貨金額大于100,扣減100分 salience 9 lock-on-active true when $pointDomain : PointDomain(backMondy >= 100) then $pointDomain.setPoint($pointDomain.getPoint()-10); $pointDomain.recordPointLog($pointDomain.getUserName(),subBackMondyPoint); end 測(cè)試方法:java view plaincopypublic static void main(String args) throws IOException PointRuleEngine pointRuleEngine = new PointRuleEngineImpl(); while(true) InputStream is = System.in; BufferedReader br =
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年分期付款化妝品購(gòu)買合同
- 2025年P(guān)PP項(xiàng)目合作物資保障協(xié)議
- 二零二五年海洋工程建設(shè)項(xiàng)目施工合同6篇
- 二零二五年度PVC管材綠色制造技術(shù)合作合同3篇
- 2025年度新能源發(fā)電項(xiàng)目租賃合同3篇
- 2025版學(xué)校圖書館古籍保護(hù)與展示工程合同3篇
- 二零二五年度航空航天器研發(fā)與測(cè)試合同4篇
- 2025年度住宅小區(qū)物業(yè)管理權(quán)轉(zhuǎn)讓與社區(qū)安全防范協(xié)議
- 二零二五年度文化創(chuàng)意產(chǎn)業(yè)經(jīng)營(yíng)授權(quán)協(xié)議
- 2025年度集裝箱式活動(dòng)板房購(gòu)置與維修保養(yǎng)合同
- 2024年云南省中考數(shù)學(xué)試題含答案解析
- 國(guó)家中醫(yī)藥管理局發(fā)布的406種中醫(yī)優(yōu)勢(shì)病種診療方案和臨床路徑目錄
- 2024年全國(guó)甲卷高考化學(xué)試卷(真題+答案)
- 汽車修理廠管理方案
- 人教版小學(xué)數(shù)學(xué)一年級(jí)上冊(cè)小學(xué)生口算天天練
- (正式版)JBT 5300-2024 工業(yè)用閥門材料 選用指南
- 三年級(jí)數(shù)學(xué)添括號(hào)去括號(hào)加減簡(jiǎn)便計(jì)算練習(xí)400道及答案
- 蘇教版五年級(jí)上冊(cè)數(shù)學(xué)簡(jiǎn)便計(jì)算300題及答案
- 澳洲牛肉行業(yè)分析
- 計(jì)算機(jī)江蘇對(duì)口單招文化綜合理論試卷
- 成人學(xué)士學(xué)位英語(yǔ)單詞(史上全面)
評(píng)論
0/150
提交評(píng)論