第一組:劉聰 .NET數(shù)據(jù)庫連接和參數(shù)化查詢
.NET中連接MySql數(shù)據(jù)庫
引用MySql.Data:.NET框架一般連接數(shù)據(jù)庫為SQL SERVER 數(shù)據(jù)庫痕钢,如果需要連接Mysql數(shù)據(jù)庫图柏,則需要添加專用的引用。從官網(wǎng)http://dev.mysql.com/downloads/connector/net/下載最新的MySQL connection/Net組件mysql-connector-net-6.10.5.msi并運行后任连,在本地C:\Program Files (x86)\MySQL\MySQL Connector Net 6.10.5\Assemblies\v4.5.2路徑下得到MySql.Data.dll(如果沒有也可能在C:\Program Files下)蚤吹。
-
建立數(shù)據(jù)庫連接
添加引用后可以使用using MySql.Data.MySqlClient;通過下列代碼實現(xiàn)MySql數(shù)據(jù)庫連接。
-
數(shù)據(jù)庫操作
這里只進(jìn)行簡單的查詢操作:
控制臺輸出:
參數(shù)化查詢
- SQL注入問題
上面的查詢操作是通過查詢字符串拼接實現(xiàn)的随抠,模擬用戶輸入裁着。這里存在一個SQL注入的問題:
問題在于password = "111' or '1'='1";最后拼成的sql語句為:
select * from usertable where UserName='congliu' AND Password ='111' or '1'='1'
由于1=1恒為真,所以不管其他的輸入為什么都會返回當(dāng)前表的所有信息拱她。這是一個簡單的sql注入二驰。
- 參數(shù)化查詢
為了解決這個問題,比較好的方法是采用參數(shù)化查詢:
參數(shù)化查詢是訪問數(shù)據(jù)庫時秉沼,在需要填入數(shù)值或數(shù)據(jù)的地方桶雀,使用參數(shù) (Parameter) 來給值。
在使用參數(shù)化查詢的情況下唬复,數(shù)據(jù)庫服務(wù)器不會將參數(shù)的內(nèi)容視為SQL指令的一部份來處理矗积,而是在數(shù)據(jù)庫完成SQL指令的編譯后,才套用參數(shù)運行盅抚,因此就算參數(shù)中含有指令漠魏,也不會被數(shù)據(jù)庫運行倔矾。Access妄均、SQL Server、MySQL哪自、SQLite等常用數(shù)據(jù)庫都支持參數(shù)化查詢丰包。
第二組:趙彩鳳 改變超鏈接樣式、AppCan--Switch開關(guān)組件
- 改變超鏈接樣式
<style type="text/css">
a:link {color: #FF0000} /* 未訪問的鏈接 */
a:visited {color: #00FF00} /* 已訪問的鏈接 */
a:hover {color: #FF00FF} /* 鼠標(biāo)移動到鏈接上 */
a:active {color: #0000FF} /* 選定的鏈接 */
</style>
- AppCan--Switch開關(guān)組件
(1)對象
appcan.switchBtn(selector, css, callback)
Selector 按鈕的選擇器壤巷,例如 .btn邑彪、div或#id‰驶可同時處理多個按鈕
css Switch 開啟后的背景CSS類名稱寄症。預(yù)置 bc-head宙彪。可選參數(shù)
callback switch 狀態(tài)變更后的回調(diào)函數(shù)
(2)代碼
HTML:
<div class="switch uba bc-border data-checked="true">
<div class="switch-btn sc-bg-active "></div>
</div>
JS:
appcan.switchBtn(switchBtns,function(obj,value) {
console.log(“switch status:”,value);
})
appcan.updateSwitch(obj)有巧;//obj:需要操作的dom對象
E.g.
<div class="switch uba bc-border" data-checked="true">
<div class="switch-btn sc-bg-active "></div>
</div>
appcan.updateSwitch($('.switch'))
第三組:蔡永堅 Asp.Net底層解析-頁面生命周期
頁面生命周期總體理解起來其實很容易释漆,說白了就是在客戶端提出了一個頁面請求之后,服務(wù)器端將ASPX頁面源代碼轉(zhuǎn)化為正確的HTML和JS代碼的整個過程篮迎。服務(wù)端在轉(zhuǎn)化的過程中當(dāng)然不是調(diào)用一兩個方法就能解決了的男图,是經(jīng)歷被設(shè)計好的若干個階段,一步一步完成的甜橱,且各個階段的功能很明確彼此是承前啟后的關(guān)系逊笆。這些階段大體上可以分為:初始化、加載岂傲、回發(fā)事件處理难裆、呈現(xiàn)、卸載等等镊掖。關(guān)于這些階段的具體細(xì)節(jié)本文將在后面說明差牛,現(xiàn)在先來看一個簡單的從整體上反映頁面生命周期的實例(頁面周期每達(dá)到一個事件時,就往頁面中寫入一些字符串)堰乔,新建一個空頁面偏化,并在后臺編寫以下代碼:
[csharp] view plain copy
1. protected void Page_PreInit(object sender, EventArgs e)
2. { //這里設(shè)置斷點
3. Response.Write("執(zhí)行Page_PreInit<br/>");
4. }
5. protected void Page_Init(object sender, EventArgs e)
6. { //這里設(shè)置斷點
7. Response.Write("執(zhí)行Page_Init<br/>");
8. }
9. protected void Page_InitComplete(object sender, EventArgs e)
10. { //這里設(shè)置斷點
11. Response.Write("執(zhí)行Page_InitComplete<br/>");
12. }
13. protected void Page_PreLoad(object sender, EventArgs e)
14. { //這里設(shè)置斷點
15. Response.Write("執(zhí)行Page_PreLoad<br/>");
16. }
17. protected void Page_Load(object sender, EventArgs e)
18. { //這里設(shè)置斷點
19. Response.Write("執(zhí)行Page_Load<br/>");
20. }
21. protected void Page_LoadComplete(object sender, EventArgs e)
22. { //這里設(shè)置斷點
23. Response.Write("執(zhí)行Page_LoadComplete<br/>");
24. }
25. protected void Page_PreRender(object sender, EventArgs e)
26. { //這里設(shè)置斷點
27. Response.Write("執(zhí)行Page_PreRender<br/>");
28. }
29. protected void Page_PreRenderComplete(object sender, EventArgs e)
30. { //這里設(shè)置斷點
31. Response.Write("執(zhí)行Page_PreRenderComplete<br/>");
32. }
33. protected void Page_SaveStateComplete(object sender, EventArgs e)
34. { //這里設(shè)置斷點
35. Response.Write("執(zhí)行Page_SaveStateComplete<br/>");
36. }
37. protected void Page_Unload(object sender, EventArgs e)
38. { //這里設(shè)置斷點
39. //這里是頁面卸載階段,不能使用Response.Write方法镐侯,一般該事件內(nèi)執(zhí)行釋放本頁面控制的系統(tǒng)資源
40. }
如果在每個方法的內(nèi)部都設(shè)置了斷點侦讨,那么當(dāng)運行該頁面后會發(fā)現(xiàn),斷點的觸發(fā)是從頂部往底部依次執(zhí)行的苟翻,觸發(fā)一個事件之后再觸發(fā)下一步事件韵卤,有條不紊,最終得到頁面效果如下截圖所示:
上面的示例是每次頁面(無論是首次請求還是PostBack)的請求都要觸發(fā)的一系列事件崇猫,而當(dāng)請求為PostBack時沈条,會在Page_Load事件與Page_LoadComplete事件之間觸發(fā)引起本次PostBack的控件對應(yīng)的事件,在上面的示例上進(jìn)行簡單的修改诅炉,前臺頁面添加Bot同控件蜡歹,代碼如下:
[html] view plain copy
1. <form id="form1" runat="server">
2. <asp:Button ID="aspbtn_TestPostBack" runat="server" Text="點擊提交"
3. onclick="aspbtn_TestPostBack_Click" />
4. </form>
后臺代碼與上面的示例一致,只是添加了Button控件的Click事件對應(yīng)的方法涕烧,添加的方法如下:
[csharp] view plain copy
1. //這里是Button的Click事件
2. protected void aspbtn_TestPostBack_Click(object sender, EventArgs e)
3. {
4. Response.Write("執(zhí)行Button控件的Click事件<br/>");
5. }
首次運行頁面得到結(jié)果與上次示例一致月而,而當(dāng)點擊按鈕產(chǎn)生PostBack時,發(fā)現(xiàn)在Page_Load事件與Page_LoadComplete事件之間執(zhí)行了按鈕的事件议纯,即aspbtn_TestPostBack_Click方法父款。
第四組:張元一 iOS獲取系統(tǒng)電量
EFB項目中,需要實現(xiàn)后臺持續(xù)監(jiān)控電量的功能,這可以拆分為三個需求:
- 程序需要保持在后臺可以運行憨攒。
- 程序需要獲取ipad精確電量世杀。
- 需要每隔一段時間掃描一次電量,以獲取當(dāng)前有效的電量肝集。
上次文章實現(xiàn)了需求一玫坛,本文先討論需求二的實現(xiàn):
獲取ios系統(tǒng)電量,有幾種方法:
方法一:
通過蘋果官方文檔里面UIDevice public API來獲取包晰,代碼如下:
[UIDevice currentDevice].batteryMonitoringEnabled = YES;
[[NSNotificationCenter defaultCenter]
addObserverForName:UIDeviceBatteryLevelDidChangeNotification
object:nil queue:[NSOperationQueue mainQueue]
usingBlock:^(NSNotification *notification) {
self.myVC.batteryLevellb.text = [NSString stringWithFormat:@"CurrentBatteryLevel:%.f%%",[UIDevice currentDevice].batteryLevel*100];
}];
方法獲取的電量是1%精度的湿镀,可以滿足要求。
方法二:通過runtime 獲取StatusBar上電池電量控件類私有變量的值伐憾,此方法可精準(zhǔn)獲取iOS6以上電池電量
- (int)getCurrentBatteryLevel
{
UIApplication *app = [UIApplication sharedApplication];
if (app.applicationState == UIApplicationStateActive||app.applicationState==UIApplicationStateInactive) {
Ivar ivar= class_getInstanceVariable([app class],"_statusBar");
id status = object_getIvar(app, ivar);
for (id aview in [status subviews]) {
int batteryLevel = 0;
for (id bview in [aview subviews]) {
if ([NSStringFromClass([bview class]) caseInsensitiveCompare:@"UIStatusBarBatteryItemView"] == NSOrderedSame&&[[[UIDevice currentDevice] systemVersion] floatValue] >=6.0)
{
Ivar ivar= class_getInstanceVariable([bview class],"_capacity");
if(ivar)
{
batteryLevel = ((int (*)(id, Ivar))object_getIvar)(bview, ivar);
//這種方式也可以
/*ptrdiff_t offset = ivar_getOffset(ivar);
unsigned char *stuffBytes = (unsigned char *)(__bridge void *)bview;
batteryLevel = * ((int *)(stuffBytes + offset));*/
NSLog(@"電池電量:%d",batteryLevel);
if (batteryLevel > 0 && batteryLevel <= 100) {
return batteryLevel;
} else {
return 0;
}
}
}
}
}
}
return 0;
}
經(jīng)測試勉痴,此方法獲取電量精度為5%,且在程序退出到后臺后树肃,此方法不能獲取到電量蒸矛,不能滿足要求。
方法三:
通過IOKit framework來獲取
IOKit framework在IOS中用來跟硬件或內(nèi)核服務(wù)通信胸嘴,常用于獲取硬件詳細(xì)信息雏掠。
首先,需要將IOPowerSources.h劣像,IOPSKeys.h乡话,IOKit三個文件導(dǎo)入到工程中。然后即可通過如下代碼獲取1%精確度的電量信息:
-(double) getBatteryLevel{
// returns a blob of power source information in an opaque CFTypeRef
CFTypeRef blob = IOPSCopyPowerSourcesInfo();
// returns a CFArray of power source handles, each of type CFTypeRef
CFArrayRef sources = IOPSCopyPowerSourcesList(blob);
CFDictionaryRef pSource = NULL;
const void *psValue;
// returns the number of values currently in an array
int numOfSources = CFArrayGetCount(sources);
// error in CFArrayGetCount
if (numOfSources == 0) {
NSLog(@"Error in CFArrayGetCount");
return -1.0f;
}
// calculating the remaining energy
for (int i=0; i<numOfSources; i++) {
// returns a CFDictionary with readable information about the specific power source
pSource = IOPSGetPowerSourceDescription(blob, CFArrayGetValueAtIndex(sources, i));
if (!pSource) {
NSLog(@"Error in IOPSGetPowerSourceDescription");
return -1.0f;
}
psValue = (CFStringRef) CFDictionaryGetValue(pSource, CFSTR(kIOPSNameKey));
int curCapacity = 0;
int maxCapacity = 0;
double percentage;
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSCurrentCapacityKey));
CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &curCapacity);
psValue = CFDictionaryGetValue(pSource, CFSTR(kIOPSMaxCapacityKey));
CFNumberGetValue((CFNumberRef)psValue, kCFNumberSInt32Type, &maxCapacity);
percentage = ((double) curCapacity / (double) maxCapacity * 100.0f);
NSLog(@"curCapacity : %d / maxCapacity: %d , percentage: %.1f ", curCapacity, maxCapacity, percentage);
return percentage;
}
return -1.0f;
}
相比方法一耳奕,此方法麻煩很多绑青,不過現(xiàn)在的EFB使用的是這種方式。
本項目demo的GitHub地址:
https://github.com/Frued/BatteryLevel
第五組:陳孚楠 javascript使用的兩項原則
兩項原則之平穩(wěn)退化和漸進(jìn)增強
平穩(wěn)退化
如果正確地使用了JavaScript腳本屋群,就可以讓訪問者在他們?yōu)g覽器不支持javascript的情況下仍能順利地瀏覽你的網(wǎng)站闸婴。
即當(dāng)客戶禁止javascript功能后,仍能看到網(wǎng)頁的內(nèi)容芍躏。漸進(jìn)增強
即用一些額外的信息層去包裹原始數(shù)據(jù)邪乍。若按照“漸進(jìn)增強”原則創(chuàng)建的網(wǎng)頁幾乎都能符合“平穩(wěn)退化”原則。
例如:先只使用常規(guī)的鏈接对竣,然后通過JavaScript去攔截默認(rèn)動作庇楞。同理:先構(gòu)建常規(guī)網(wǎng)站,然后再Hijax它
大概可以說:
“平穩(wěn)退化”是在瀏覽器沒有JavaScript功能柏肪,或沒有開啟JavaScript功能情況下姐刁,我們解決這種問題的方式;
“漸進(jìn)增強”是在瀏覽器開啟JavaScript功能后烦味,如果瀏覽器版本不支持某些JavaScript能力,我們解決這種問題的方式。