2012-03-13 7 views
6

Henüz aynı şeyi yapan birkaç yöntem var, MySQL veritabanıyla arabirim oluştururken farklı bir parametre türü kaydedin veya yükleyin. Şu anda, her tür için farklı bir yöntem var. Bu yöntemleri, farklı türleri destekleyecek şekilde nasıl birleştirebilirim? tipleri her ikisi sayısal olduğu örnekteAynı kodu kullanan ancak farklı türleri kullanan yeniden düzenleme yöntemleri

public static void saveLongArray(Connection con, int playerID, String tableName, String fieldName, long[] array, long[] originalArray) { 
    try { 
     for (int i = 0; i < array.length; i++) { 
      // Check for change before running query 
      if (array[i] != originalArray[i]) { 
       if (array[i] != 0 && array[i] != -1) { 
        PreparedStatement updateQuery = con.prepareStatement("REPLACE INTO `" + tableName + "` (`player_id`, `index`, `" + fieldName + "`) VALUES(?, ?, ?)"); 
        updateQuery.setInt(1, playerID); 
        updateQuery.setInt(2, i); 
        updateQuery.setLong(3, array[i]); 
        updateQuery.execute(); 
       } else { 
        PreparedStatement deleteQuery = con.prepareStatement("DELETE FROM `" + tableName + "` WHERE `player_id` = ? AND `index` = ?"); 
        deleteQuery.setInt(1, playerID); 
        deleteQuery.setInt(2, i); 
        deleteQuery.execute(); 
       } 

       originalArray[i] = array[i]; 
      } 
     } 
    } catch (SQLException ex) { 
     Logger.getLogger(PlayerSaveHandler.class.getName()).log(Level.SEVERE, "SQL Exception while saving a long array!", ex); 
    } 
} 

public static void saveIntArray(Connection con, int playerID, String tableName, String fieldName, int[] array, int[] originalArray) { 
    try { 
     for (int i = 0; i < array.length; i++) { 
      // Check for change before running query 
      if (array[i] != originalArray[i]) { 
       if (array[i] != 0 && array[i] != -1) { 
        PreparedStatement updateQuery = con.prepareStatement("REPLACE INTO `" + tableName + "` (`player_id`, `index`, `" + fieldName + "`) VALUES(?, ?, ?)"); 
        updateQuery.setInt(1, playerID); 
        updateQuery.setInt(2, i); 
        updateQuery.setInt(3, array[i]); 
        updateQuery.execute(); 
       } else { 
        PreparedStatement deleteQuery = con.prepareStatement("DELETE FROM `" + tableName + "` WHERE `player_id` = ? AND `index` = ?"); 
        deleteQuery.setInt(1, playerID); 
        deleteQuery.setInt(2, i); 
        deleteQuery.execute(); 
       } 

       originalArray[i] = array[i]; 
      } 
     } 
    } catch (SQLException ex) { 
     Logger.getLogger(PlayerSaveHandler.class.getName()).log(Level.SEVERE, "SQL Exception while saving an int array!", ex); 
    } 
} 

Not:

Aşağıda farklı henüz çok benzer kullanımı iki yöntem bir örneğidir. Türlerin tamamen farklı olduğu bir durumda (ör. Int ve String), kaçınmak için kaç tane neyden çoğaltma yöntemine sahip olabilirim?

cevap

12

Sen Strateji uygulayabilirsiniz setInt() vs. ayarı parametrelerin yerine sağlanan nesnelerin toString() yöntemler kullanılarak elle bütün sorgu dizesi yaratabilir desen burada. Bu onun soruya cevap vermez

public static void saveArray<T>(Connection con, int playerID, String tableName, String fieldName, T[] array, T[] originalArray, TypeDependentBehavior<T> behavior) { 
try { 
     for (int i = 0; i < array.length; i++) { 
      // Check for change before running query 
      if (array[i] != originalArray[i]) { 
       if (array[i] != 0 && array[i] != -1) { 
        PreparedStatement updateQuery = con.prepareStatement("REPLACE INTO `" + tableName + "` (`player_id`, `index`, `" + fieldName + "`) VALUES(?, ?, ?)"); 
        updateQuery.setInt(1, playerID); 
        updateQuery.setInt(2, i); 
        behavior.setFieldValue(updateQuery, array[i]); 
        updateQuery.execute(); 
       } else { 
        PreparedStatement deleteQuery = con.prepareStatement("DELETE FROM `" + tableName + "` WHERE `player_id` = ? AND `index` = ?"); 
        deleteQuery.setInt(1, playerID); 
        deleteQuery.setInt(2, i); 
        deleteQuery.execute(); 
       } 

       originalArray[i] = array[i]; 
      } 
     } 
    } catch (SQLException ex) { 
     Logger.getLogger(PlayerSaveHandler.class.getName()).log(Level.SEVERE, "SQL Exception while saving an int array!", ex); 
    } 
} 
+0

Bu tasarım modelini inceledim, ancak bu durumda kullanmayı asla düşünmemiştim. Teşekkür ederim! – jSherz

+0

Burada ekleyeceğim tek şey, diziler artık ilkeller yerine nesneleri taşıyacağından, 'equals() '(örn.'! Array [i] .equals (originalArray [i]) 'veya "compareTo()" Ayrıca, dizilerin yalnızca sayısal türler içerdiği varsayılır, bu nedenle String için bir davranışa ihtiyacımız yoktur ve tip argümanı muhtemelen güvenli olması için 'olmalıdır. – jpm

+0

Arabirim içine uygulama eklemek Java'da iyi bir fikir mi? Bu soyut bir sınıf olarak daha iyi olmaz mıydı? – flurdy

3

int[] yerine long[] kullanırım. Bellek farkı, JDBC kullanımı maliyetine kıyasla çok küçüktür.

Dize işlemeniz gerekiyorsa bir nesne türü kullanabilirsiniz.

public static void saveArray(Connection con, int playerID, String tableName, 
    String fieldName, Object[] array, Object[] originalArray) { 

Eğer jenerik olarak tüm dizi türlerini erişmek için Array.getLength() ve Array.get() yöntemi kullanabilirsiniz long[] ve Object[] için bir yöntem istiyorum. Bu, kaydettiğinden daha fazla karmaşıklık ekleyebilir.

+2

interface TypeDependentBehavior<T> { void setFieldValue(PreparedStatement st, T value); } interface StringBehavior extends TypeDependentBehavior<String> { void setFieldValue(PreparedStatement st, String value) { st.setString(3, value); } } interface IntBehavior extends TypeDependentBehavior<Integer> { void setFieldValue(PreparedStatement st, Integer value) { st.setInt(3, value); } } 

..... "what' eğer int' ve 'String'?" – ggrigery

2

Sen

void doSomething(int[] array) { 
    for (int i = 0; i < array.length; i++) 
     System.out.println(array[i]); 
} 

void doSomething(long[] array) { 
    for (int i = 0; i < array.length; i++) 
     System.out.println(array[i]); 
} 

Şimdi

int[] array1 = new int[] { 1, 2, 3 }; 
doSomething(array1); 

long[] array2 = new long[] { 1L, 2L, 3L }; 
doSomething(array2); 

String[] array3 = new String[] { "one", "two", "three" }; 
doSomething(array3); 

çağırabilir

<T> void doSomething(T[] array) { 
    for (int i = 0; i < array.length; i++) 
     System.out.println(array[i]); 
} 

içine jeneralize olabilir örneğin, bunun için jenerikleri kullanabilirsiniz Ama sen yöntem uygulamayı kontrol edilmeli ve herhangi bir dizi türü, özellikle SQL deyimi ile hala çalışacağından emin olun.

1

Karşılaştırma işlevlerinizi bozar ve yöntemlerinizi en ayrıntılı seviyeye indirdiyseniz ne olur? Örneğin:

public static void update(Connection con, int playerID, String tableName, String fieldName, String value) { 
    // update query logic here 
} 

Ve delete() için aynı. Bu işleve hem "yeni" hem de "orijinal" değerleri iletmek için bir neden yoktur ve içte karşılaştırın. Diziler arasında döngü yapmayı öneririm, karşılaştırma yaparak ve gereksinimlerinize göre update() veya delete()'u çağırabilirim. Farklı veri tipleriyle uğraşmak için, veritabanında istediğin şeyin her zaman String değerini geçecektim. geçirilen değerlerden long[] oluşturur, bir bağımsız değişken bir int[] olarak alan bir yöntem ve fiili çalışma gerçekleştirmek için bağımsız değişken olarak long[] alır yöntem varyantı çağrısı -

0

benzer türleri ile, bir sarıcı oluşturabilir. Bazı yükleri vardır, ancak dizilerinizin milyonlarca giriş olmadığı varsayılırsa, veritabanıyla iletişim maliyetine kıyasla ihmal edilebilir.

Tamamen farklı türlerde, Object[] kullanmayı deneyebilirsiniz (veya bir şekilde jenerikleri kullanabilir), ancak bazı tuzaklar olabilir. 0 veya -1 yerine farklı bir silme işareti kullanmanız gerekir (null bariz bir seçim gibi görünüyor).Farklı yöntemler çağrılması gerekiyor beri büyük bir sorun PreparedStatement parametreleri kuruyor ama