<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    wang123

    2009年3月23日

    Hibernate Shard簡介介紹

    HibernateShard
        多數據庫水平分區解決方案。

    1. 簡介
         Hibernate 的一個擴展,用于處理多數據庫水平分區架構。
         由google工程師 2007年 捐獻給 Hibernate社區。 
         http://www.hibernate.org/414.html
         目前版本:   3.0.0 beta2, 未發GA版。
         條件:Hibernate Core 3.2, JDK 5.0

    2. 水平分區原理
         一個庫表如 Order 存在于多個數據庫實例上。按特定的分區邏輯,將該庫表的數據存儲在這些實例中,一條記錄的主鍵 PK,在所有實例中不得重復。
       
        水平分區在大型網站,大型企業應用中經常采用。 像www.sina.com.cn ,www.163.com  www.bt285.cn www.guihua.org
        目的出于海量數據分散存儲,分散操作,分散查詢以便提高數據處理量和整體數據處理性能。
      
        使用:
          google工程師的設計還是非常好的,完全兼容 Hibernate本身的主要接口。
    Java代碼 復制代碼
    1. org.hibernate.Session   
    2. org.hibernate.SessionFactory    
    3.  org.hibernate.Criteria    
    4.  org.hibernate.Query   

         因此程序員開發變化不大,甚至不需要關心后臺使用了分區數據庫。程序遷移問題不大。而且配置上比較簡明。

    3. 三種策略:
       1) ShardAccessStrategy, 查詢操作時,到那個分區執行。
          默認提供兩個實現:
          順序策略:SequentialShardAccessStrategy, 每個query按順序在所有分區上執行。
          平行策略:ParallelShardAccessStrategy, 每個query以多線程方式并發平行的在所有分區上執行。 此策略下,需要使用線程池機制滿足特定的性能需要,java.util.concurrent.ThreadPoolExecutor。

       2) ShardSelectionStrategy, 新增對象時,存儲到哪個分區。
             框架默認提供了一個輪詢選擇策略 RoundRobinShardSelectionStrategy, 但一般不這樣使用。
            通常采用“attribute-based sharding”機制,基于屬性分區。一般是用戶根據表自己實現一個基于屬性分區的策略類ShardSelectionStrategy ,例如,以下WeatherReport基于continent屬性選擇分區:
    Java代碼 復制代碼
    1.   public class WeatherReportShardSelectionStrategy implements ShardSelectionStrategy {   
    2. public ShardId selectShardIdForNewObject(Object obj) {   
    3.     if(obj instanceof WeatherReport) {   
    4.         return ((WeatherReport)obj).getContinent().getShardId();   
    5.     }   
    6.     throw new IllegalArgumentException();   
    7. }   

     

       3) ShardResolutionStrategy, 該策略用于查找單個對象時,判斷它在哪個或哪幾個分區上。
          默認使用 AllShardsShardResolutionStrategy ,可以自定義例如:
    Java代碼 復制代碼
    1. public class WeatherReportShardResolutionStrategy extends AllShardsShardResolutionStrategy {   
    2.     public WeatherReportShardResolutionStrategy(List<ShardId> shardIds) {   
    3.         super(shardIds);   
    4.     }   
    5.   
    6.     public List<ShardId> selectShardIdsFromShardResolutionStrategyData(   
    7.             ShardResolutionStrategyData srsd) {   
    8.         if(srsd.getEntityName().equals(WeatherReport.class.getName())) {   
    9.             return Continent.getContinentByReportId(srsd.getId()).getShardId();   
    10.         }   
    11.         return super.selectShardIdsFromShardResolutionStrategyData(srsd);   
    12.     }   
    13. }  



    4. 水平分區下的查詢

       對于簡單查詢 HibernateShard 可以滿足。

       水平分區下多庫查詢是一個挑戰。主要存在于以下三種操作:
       1) distinct
             因為需要遍歷所有shard分區,并進行合并判斷重復記錄。
       2) order by
             類似 1)
       3) aggregation
             count,sim,avg等聚合操作先分散到分區執行,再進行匯總。
             是不是有點類似于 MapReduce ? 呵呵。
      
       目前 HibernateShard 不支持 1), 2), 對 3) 部分支持

        HibernateShard 目前通過 Criteria 接口的實現對 聚合提供了較好的支持, 因為 Criteria 以API接口指定了 Projection 操作,邏輯相對簡單。

        而HQL,原生 SQL 還不支持此類操作。

        
    5. 再分區和虛擬分區
          當數據庫規模增大,需要調整分區邏輯和數據存儲時, 需要再分區。
          兩種方式: 1)數據庫數據遷移其他分區; 2) 改變記錄和分區映射關系。這兩種方式都比較麻煩。尤其“改變記錄和分區映射關系”,需要調整 ShardResolutionStrategy。

         HibernateShard 提供了一種虛擬分區層。當需要調整分區策略時,只需要調整虛擬分區和物理分區映射關系即可。以下是使用虛擬分區時的配置創建過程:

    Java代碼 復制代碼
    1.     
    2.   Map<Integer, Integer> virtualShardMap = new HashMap<Integer, Integer>();   
    3. virtualShardMap.put(00);   
    4. virtualShardMap.put(10);   
    5. virtualShardMap.put(21);   
    6. virtualShardMap.put(31);   
    7. ShardedConfiguration shardedConfig =   
    8.     new ShardedConfiguration(   
    9.         prototypeConfiguration,   
    10.         configurations,   
    11.         strategyFactory,   
    12.         virtualShardMap);   
    13. return shardedConfig.buildShardedSessionFactory();  


    6.  局限:
        1)HibernateShard 不支持垂直分區, 垂直+水平混合分區。

        2) 水平分區下 查詢功能受到一定限制,有些功能不支持。實踐中,需要在應用層面對水平分區算法進行更多的考慮。
        3) 不支持跨分區的 關系 操作。例如:刪除A分區上的 s 表,B分區上的關聯子表 t的記錄無法進行參照完整性約束檢查。 (其實這個相對 跨分區查詢的挑戰應該說小的多,也許google工程師下個版本會支持,呵呵)

        4) 解析策略接口似乎和對象ID全局唯一性有些自相矛盾,
    AllShardsShardResolutionStrategy 的接口返回的是給定對象ID所在的 shard ID集合,按理應該是明確的一個 shard ID.

    參考資料:HibernateShard 參考指南。

    posted @ 2009-04-01 18:49 王| 編輯 收藏

    GPS經緯度可以用來Java解析

    現在正開發的定位模塊用到的定位設置是塞格車圣導航設備,發送指令返回的經緯度需要轉換成十進制,再到GIS系統獲取地理信息描述。以后需要要經常用到這方面的知識,隨筆寫下。

     

    將經緯度轉換成十進制

     公式:
        Decimal Degrees = Degrees + minutes/60 + seconds/3600
      例:57°55'56.6" =57+55/60+56.6/3600=57.9323888888888
     
    如把經緯度  (longitude,latitude) (205.395583333332,57.9323888888888)轉換據成坐標(Degrees,minutes,seconds)(205°23'44.1",57°55'56.6")。
    步驟如下:

    1、 直接讀取"度":205

    2、(205.395583333332-205)*60=23.734999999920 得到"分":23

    3、(23.734999999920-23)*60=44.099999995200 得到"秒":44.1

     

    發送定位指令,終端返回的經緯度信息如下:

    (ONE072457A3641.2220N11706.2569E000.000240309C0000400)

    按照協議解析

     

    獲得信息體的經緯度是主要,其它不要管,直接用String類的substring()方法截掉,獲取的經緯度

    3641.2220N11706.2569E http://www.bt285.cn

    Java代碼 復制代碼
    1. package com.tdt.test;   
    2.   
    3. import com.tdt.api.gis.LocationInfo;   
    4.   
    5. /**  
    6.  * <p>Title:坐標轉換 </p>  
    7.  *   
    8.  * <p>Description:</p>  
    9.  *   
    10.  * <p>Copyright: Copyright (c) 2009</p>  
    11.  *   
    12.  * <p>Company:</p>  
    13.  *   
    14.  * @author sunnylocus  
    15.  * @version 1.0 [2009-03-24]  
    16.  *   
    17.  */  
    18. public class LonlatConversion {   
    19.   
    20.     /**  
    21.      *   
    22.      * @param dms 坐標  
    23.      * @param type 坐標類型  
    24.      * @return String 解析后的經緯度  
    25.      */  
    26.     public static String xypase(String dms, String type) {   
    27.         if (dms == null || dms.equals("")) {   
    28.             return "0.0";   
    29.         }   
    30.         double result = 0.0D;   
    31.         String temp = "";   
    32.            
    33.         if (type.equals("E")) {//經度   
    34.             String e1 = dms.substring(03);//截取3位數字,經度共3位,最多180度   
    35.                                             //經度是一倫敦為點作南北兩極的線為0度,所有往西和往東各180度    
    36.             String e2 = dms.substring(3, dms.length());//需要運算的小數   
    37.   
    38.             result = Double.parseDouble(e1);   
    39.             result += (Double.parseDouble(e2) / 60.0D);   
    40.             temp = String.valueOf(result);   
    41.             if (temp.length() > 9) {   
    42.                 temp = e1 + temp.substring(temp.indexOf("."), 9);   
    43.             }   
    44.         } else if (type.equals("N")) {      //緯度,緯度是以赤道為基準,相當于把地球分兩半,兩個半球面上的點和平面夾角0~90度   
    45.             String n1 = dms.substring(02);//截取2位,緯度共2位,最多90度   
    46.             String n2 = dms.substring(2, dms.length());   
    47.   
    48.             result = Double.parseDouble(n1);   
    49.             result += Double.parseDouble(n2) / 60.0D;   
    50.             temp = String.valueOf(result);   
    51.             if (temp.length() > 8) {   
    52.                 temp = n1 + temp.substring(temp.indexOf("."), 8);   
    53.             }   
    54.         }   
    55.         return temp;   
    56.     }   
    57.     public static void main(String[] args) {   
    58.         String info="(ONE072457A3641.2220N11706.2569E000.000240309C0000400)";           
    59.         info=info.substring(11,info.length()-13);   
    60.         //緯度   
    61.         String N = info.substring(0, info.indexOf("N"));   
    62.         //經度   
    63.         String E = info.substring(info.indexOf("N")+1,info.indexOf("E"));   
    64.         //請求gis,獲取地理信息描述   
    65.         double x = Double.parseDouble(CoordConversion.xypase(E,"E"));   
    66.         double y = Double.parseDouble(CoordConversion.xypase(N,"N"));   
    67.         String result =LocationInfo.getLocationInfo("test", x, y); //System.out.println("徑度:"+x+","+"緯度:"+y);   
    68.         System.out.println(result);   
    69.     }   
    70. }  

    運行結果

    在濟南市,位于輕騎路和八澗堡路附近;在環保科技園國際商務中心和濟南市區賢文莊附近。

    posted @ 2009-03-26 17:08 王| 編輯 收藏

    用Java來顯示圖片生成器

    一、本圖片生成器具有以下功能特性:

         1、可以設置圖片的寬度、高度、外框顏色、背景色;

         2、可以設置圖片字體的大小、名稱、顏色;

         3、可以設置輸出圖片的格式,如JPEG、GIF等;

         4、可以將圖片存儲到一個文件或者存儲到一個輸出流;

         5、可以為圖片增加若干條干擾線(在生成隨機碼圖片時可用此特性);

         6、打印在圖片上的文字支持自動換行;

     

    另外,本圖片生成器還用到了模板方法模式。

     

    二、下面列出相關的源代碼

         1、抽象類AbstractImageCreator的源代碼

     /**本代碼在 http://www.bt285.cn  http://www.5a520.cn 已使用了 */
    1. public abstract class AbstractImageCreator {   
    2.     private static Random rnd = new Random(new Date().getTime());   
    3.        
    4.     //圖片寬度   
    5.     private int width = 200;   
    6.        
    7.     //圖片高度   
    8.     private int height = 80;   
    9.        
    10.     //外框顏色   
    11.     private Color rectColor;   
    12.        
    13.     //背景色   
    14.     private Color bgColor;   
    15.        
    16.     //干擾線數目   
    17.     private int lineNum = 0;   
    18.        
    19.     //圖片格式   
    20.     private String formatName = "JPEG";   
    21.        
    22.     //字體顏色   
    23.     private Color fontColor = new Color(000);   
    24.        
    25.     //字體名稱   
    26.     private String fontName = "宋體";   
    27.        
    28.     //字體大小   
    29.     private int fontSize = 15;   
    30.        
    31.   
    32.     //##### 這里省略成員變臉的get、set方法 #####   
    33.   
    34.   
    35.     /**  
    36.      * 畫干擾線  
    37.      */  
    38.     private void drawRandomLine(Graphics graph){   
    39.         for(int i=0;i<lineNum;i++){   
    40.             //線條的顏色   
    41.             graph.setColor(getRandomColor(100155));   
    42.                
    43.             //線條兩端坐標值   
    44.             int x1 = rnd.nextInt(width);   
    45.             int y1 = rnd.nextInt(height);   
    46.                
    47.             int x2 = rnd.nextInt(width);   
    48.             int y2 = rnd.nextInt(height);   
    49.                
    50.             //畫線條   
    51.             graph.drawLine(x1, y1, x2, y2);   
    52.         }   
    53.     }   
    54.        
    55.     /**  
    56.      * 隨機獲取顏色對象  
    57.      */  
    58.     private Color getRandomColor(int base, int range){   
    59.         if((base + range) > 255) range = 255 - base;   
    60.            
    61.         int red = base + rnd.nextInt(range);   
    62.         int green = base + rnd.nextInt(range);   
    63.         int blue = base + rnd.nextInt(range);   
    64.            
    65.         return new Color(red, green, blue);   
    66.     }   
    67.            
    68.                 //該方法內應用了模板方法模式   
    69.     public void drawImage(String text)throws IOException{   
    70.         BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);   
    71.            
    72.         if(rectColor == null) rectColor = new Color(000);   
    73.         if(bgColor == null) bgColor = new Color(240251200);   
    74.            
    75.         //獲取畫布   
    76.         Graphics graph = image.getGraphics();   
    77.            
    78.         //畫長方形   
    79.         graph.setColor(bgColor);   
    80.         graph.fillRect(00, width, height);   
    81.            
    82.         //外框   
    83.         graph.setColor(rectColor);   
    84.         graph.drawRect(00, width-1, height-1);   
    85.            
    86.         //畫干擾線   
    87.         drawRandomLine(graph);   
    88.            
    89.         //畫字符串   
    90.         drawString(graph, text);   
    91.            
    92.         //執行   
    93.         graph.dispose();   
    94.            
    95.         //輸出圖片結果   
    96.         saveImage(image);   
    97.     }   
    98.        
    99.     protected abstract void drawString(Graphics graph, String text);   
    100.        
    101.     protected abstract void saveImage(BufferedImage image)throws IOException;   
    102.        
    103. }  

     

         2、類DefaultImageCreator的源代碼

              該類將生成的圖片存儲到一個文件中,需要設置outputFilePath成員變量值,該成員變量值表示圖片的存儲全路徑。

    Java代碼 復制代碼
    1. public class DefaultImageCreator extends AbstractImageCreator {   
    2.     private String outputFilePath;   
    3.        
    4.     public String getOutputFilePath() {   
    5.         return outputFilePath;   
    6.     }   
    7.   
    8.     public void setOutputFilePath(String outputFilePath) {   
    9.         this.outputFilePath = outputFilePath;   
    10.     }   
    11.        
    12.     public DefaultImageCreator(){   
    13.            
    14.     }   
    15.        
    16.     public DefaultImageCreator(String outputFilePath){   
    17.         this.outputFilePath = outputFilePath;   
    18.     }   
    19.   
    20.     @Override  
    21.     protected void drawString(Graphics graph, String text) {   
    22.         graph.setColor(getFontColor());   
    23.         Font font = new Font(getFontName(), Font.PLAIN, getFontSize());   
    24.         graph.setFont(font);   
    25.            
    26.         FontMetrics fm = graph.getFontMetrics(font);   
    27.         int fontHeight = fm.getHeight(); //字符的高度   
    28.            
    29.         int offsetLeft = 0;   
    30.         int rowIndex = 1;   
    31.         for(int i=0;i<text.length();i++){   
    32.             char c = text.charAt(i);   
    33.             int charWidth = fm.charWidth(c); //字符的寬度   
    34.   
    35.             //另起一行   
    36.             if(Character.isISOControl(c) || offsetLeft >= (getWidth()-charWidth)){   
    37.                 rowIndex++;   
    38.                 offsetLeft = 0;   
    39.             }   
    40.                
    41.             graph.drawString(String.valueOf(c), offsetLeft, rowIndex * fontHeight);   
    42.             offsetLeft += charWidth;   
    43.         }   
    44.     }   
    45.        
    46.     @Override  
    47.     protected void saveImage(BufferedImage image)throws IOException{   
    48.         ImageIO.write(image, getFormatName(), new File(outputFilePath));   
    49.     }   
    50.   
    51. }  

     

         3、類OutputStreamImageCreator的源代碼

             該類將生成的圖片存儲到一個輸出流中,需要設置out成員變量值。

    Java代碼 復制代碼
    1. public class OutputStreamImageCreator extends DefaultImageCreator {   
    2.     private OutputStream out ;   
    3.        
    4.     public OutputStream getOut() {   
    5.         return out;   
    6.     }   
    7.   
    8.     public void setOut(OutputStream out) {   
    9.         this.out = out;   
    10.     }   
    11.        
    12.     public OutputStreamImageCreator(){   
    13.            
    14.     }   
    15.        
    16.     public OutputStreamImageCreator(OutputStream out){   
    17.         this.out = out;   
    18.     }   
    19.   
    20.     @Override  
    21.     public String getOutputFilePath() {   
    22.         return null;   
    23.     }   
    24.   
    25.     @Override  
    26.     public void setOutputFilePath(String outputFilePath) {   
    27.         outputFilePath = null;   
    28.     }   
    29.   
    30.     @Override  
    31.     protected void saveImage(BufferedImage image) throws IOException {   
    32.         if(out!=null) ImageIO.write(image, getFontName(), out);   
    33.     }   
    34.        
    35. }  

     

    三、實例代碼

         1、圖片存儲到文件

    StringBuffer sb = new StringBuffer();   
    1. sb.append("中華人民共和國\n");   
    2. sb.append("中華人民共和國\n");   
    3.   
    4. DefaultImageCreator creator = new DefaultImageCreator("c:\\img.jpeg");   
    5. creator.setWidth(150);   
    6. creator.setHeight(100);   
    7. creator.setLineNum(60);   
    8. creator.setFontSize(20);   
    9. creator.drawImage(sb.toString());  

     

    posted @ 2009-03-23 18:49 王| 編輯 收藏

    <2009年3月>
    22232425262728
    1234567
    891011121314
    15161718192021
    22232425262728
    2930311234

    導航

    統計

    常用鏈接

    留言簿(3)

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 国产精品无码亚洲精品2021| 久久久久亚洲AV无码专区体验| 亚洲av无码专区在线电影| 国产卡一卡二卡三免费入口| 亚洲国产精品xo在线观看| 香蕉成人免费看片视频app下载| 亚洲AV无码一区东京热| 久久这里只精品热免费99| 亚洲男人第一av网站| 99在线在线视频免费视频观看| 亚洲性天天干天天摸| 亚洲黄色免费电影| 亚洲AV无码国产精品色| 成人片黄网站色大片免费| 亚洲成AV人影片在线观看| 一本色道久久88综合亚洲精品高清| 亚洲av成本人无码网站| 亚洲成人一区二区| 99久久99这里只有免费的精品| 亚洲精品高清视频| 久久午夜免费视频| 美女啪啪网站又黄又免费| 久久精品国产亚洲精品2020| 亚洲最大免费视频网| 亚洲熟妇成人精品一区| 亚洲国产精品自在拍在线播放 | 亚洲中文字幕乱码AV波多JI | 亚洲日本va中文字幕久久| 亚洲国产精品18久久久久久| 免费少妇a级毛片| 国产成人免费AV在线播放| 亚洲黄色片免费看| 日韩免费视频在线观看| 国产午夜精品理论片免费观看 | 毛片a级毛片免费播放100| 亚洲爆乳精品无码一区二区| 亚洲一区精品无码| 国产v精品成人免费视频400条| 特级毛片A级毛片免费播放| 久久精品国产亚洲av水果派| 成人永久免费高清|