1、當主鍵Id命名不是“id”時,應該顯式地將自定義的id指出來
例如:
Db.deleteById("post_user","user_id", 5);
2、聲明式事務實現方式為攔截器
例如:
1 @Override 2 public void configInterceptor(Interceptors me) { 3 // TODO Auto-generated method stub 4 // 聲明式事務 5 // actionKey 正則 實現方式---攔截器 6 me.add(new TxByActionKeyRegex("/user.*")); 7 // actionKeys 8 me.add(new TxByActionKeys("/user/save","/user/testDb")); 9 // actionMethods 10 me.add(new TxByMethods("save","update")); 11 // action methodRegex 12 me.add(new TxByMethodRegex("(.*save.*|.*update.*)")); 13 14 }
MySqlMySqlMySqlMySql 數據庫表必須設置為 InnoDBInnoDB InnoDB 引擎時才支持事務, 引擎時才支持事務, MyISAMMyISAMMyISAM 並不支持事務。
3、復合主鍵
當一個字段無法確定唯一性的時候,需要其他字段來一起形成唯一性。就是說用來組成唯一性的字段如果有多個就是聯合主鍵
例如:
學生成績(學號,課程號,成績)
那學號和課程號就可以做為聯合主鍵.
因為學號和課程號決定了成績.也就是說.你要知道成績..你就要知道學號,知道學號,但還不能知道某一科的成績.還要知道課程號.
所以函數依賴關系是{學號,課程號}->{成績}
JFinal中復合主鍵實現:
<1>.
arp.addMapping("post_user", "user_id,user_class_id",User.class);
<2>.
1 // 復合主鍵 select * from "post_user" where "user_id" = ? and "user_class_id" = ? 2 user = Db.findById("post_user", "user_id,user_class_id",33,1); 3 System.out.println("測試復合主鍵:"+user.getStr("user_password"));
4、緩存
CacheInterceptor可以將action所需要的數據全部緩存下來,下次請求來時如果cache存在則直接使用數據並render,而不去調用action,
這樣可以使action完全不受cache相關代碼污染,即插即用。
示例代碼如下:
1 // 測試緩存 需要在ehcache.xml 中進行配置 例如:<cache name="/user/testCache"...> 2 @Before(CacheInterceptor.class) 3 public void testCache() { 4 System.out.println("測試Cache"); 5 String sql = "select * from post_user u inner join post_class c on u.user_class_id = c.class_id" 6 + " where u.user_name= ?"; 7 User user = User.user.findFirst(sql,"liubaohua"); 8 9 System.out.println("多表關聯-操作成功!"+"\n學生:" 10 +user.getStr("user_name")+"所在班級是:"+user.getStr("class_name")); 11 // 傳參 12 setAttr("userName", user.getStr("user_name")); 13 setAttr("userClass", user.getStr("class_name")); 14 15 renderJsp("/login.jsp"); 16 }
ps: 需要在ehcache.xml 中進行配置 例如:<cache name="/user/testCache"...>
方式二:使用注解
// 使用注解的方式,取代默認的actionKey作為actionName 需要在ehcache.xml 中進行配置 例如:<cache name="testCache"...>
@CacheName("testCache")
清除緩存:
1 /** 2 * EvictInterceptor可以根據CacheName注解自動清除緩存 3 */ 4 @Before(EvictInterceptor.class) 5 @CacheName("testCache") 6 public void testEvict() { 7 8 redirect("login.html"); 9 }
5、forward內部跳轉 和redirect重定向跳轉的區別(面試經常被問到)
<1>.從地址欄顯示來說
forward是服務器請求資源,服務器直接訪問目標地址的URL,把那個URL的響應內容讀取過來,然后把這些內容再發給瀏覽器.瀏覽器根本不知道服務器發送的內容從哪里來的,所以它的地址欄還是原來的地址.
redirect是服務端根據邏輯,發送一個狀態碼,告訴瀏覽器重新去請求那個地址.所以地址欄顯示的是新的URL.
<2>.從數據共享來說
forward:轉發頁面和轉發到的頁面可以共享request里面的數據.
redirect:不能共享數據.
<3>.從運用地方來說
forward:一般用於用戶登陸的時候,根據角色轉發到相應的模塊.
redirect:一般用於用戶注銷登陸時返回主頁面和跳轉到其它的網站等.
<4>.從效率來說
forward:高.
redirect:低.
6、CacheKit 緩存操作工具
示例如下:
1 /** 2 * CacheKit 是緩存操作工具類 3 */ 4 public void testCacheKit() { 5 final String sql = "select * from post_user u inner join post_class c on u.user_class_id = c.class_id" 6 + " where u.user_name= ?"; 7 // 從緩存中取出 8 User user = CacheKit.get("testCache", "user"); 9 if(user == null) { 10 user = User.user.findFirst(sql,"張三豐"); 11 // 放入到緩存 12 CacheKit.put("testCache", "user",user); 13 } 14 setAttr("userName", user.getStr("user_name")); 15 setAttr("userClass", user.getStr("class_name")); 16 17 render("/login.html"); 18 19 /** 20 *CacheKit重載CacheKit.get(String,String,IDataLoader)方法示例 21 * 22 * CacheKit.get方法提供一個IDataLoader接口,該接口中的load方法在緩存不存在時才會被調用 23 * 24 */ 25 user = CacheKit.get("testCache", "user",new IDataLoader() { 26 27 public Object load() { 28 // TODO Auto-generated method stub 29 return User.user.findFirst(sql,"張三豐"); 30 } 31 }); 32 33 } 34
35