2010-06-07 12 views
19

ile hazırlanmış ifadeleri kullanmak JDBC şablonunu kullanıyorum ve hazırlanmış ifadeleri kullanarak bir veritabanından okumak istiyorum. Bir .csv dosyasında birçok satır üzerinde yineliyorum ve her satırda, ilgili SQL değer sorgularını karşılık gelen değerlerle çalıştırıyorum.JDBCTemplate

Okumalarımı veritabanından hızlandırmak istiyorum ancak JDBC şablonunun hazırlanmış ifadelerle nasıl çalışacağını bilmiyorum.

PreparedStatementCreator ve PreparedStatementSetter vardır. this example'da olduğu gibi her ikisi de anonim iç sınıflar ile oluşturulur. Ancak PreparedStatementSetter sınıfının içinde, hazırlanan bildirimde ayarlamak istediğim değerlere erişimim yok.

Bir .csv dosyası boyunca yinelemeye başladığımdan, onları bir Dize olarak kodlayamıyorum çünkü onları tanımıyorum. Ayrıca bunları PreparedStatementSetter'a iletemiyorum çünkü yapıcı için argüman yoktur. Ve değerlerimi son haline getirmek de aptalca olurdu.

Hazırlanan ifadelerin oluşturulmasında oldukça basit bir şekilde kullanıldı. Bu Java tutorial gibi

PreparedStatement updateSales = con.prepareStatement(
    "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); 
updateSales.setInt(1, 75); 
updateSales.setString(2, "Colombian"); 
updateSales.executeUpdate(): 

gibi bir şey.

cevap

2

PreparedStatement ile şimdi bir deyim denedim, ancak Jdbc şablonundan daha hızlı olmadığı ortaya çıktı. Belki, mezo önerdiği gibi, otomatik olarak hazırlanmış ifadeler oluşturur.

Her neyse, benim sql SELECT s yavaş olmasının nedeni başka biriydi. WHERE maddesinde, tek istediğim tam bir eşleşme bulmak istediğimde, daima LIKE numaralı telefonu kullandım. Ben LIKE bir desen arar ve bu nedenle oldukça yavaş olduğunu öğrendim.

Şimdi = numaralı telefonu kullanıyorum ve çok daha hızlı.

9

aşağıdaki deneyin:

PreparedStatementCreator creator = new PreparedStatementCreator() { 
    @Override 
    public PreparedStatement createPreparedStatement(Connection con) throws SQLException { 
     PreparedStatement updateSales = con.prepareStatement(
     "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ? "); 
     updateSales.setInt(1, 75); 
     updateSales.setString(2, "Colombian"); 
     return updateSales; 
    } 
}; 
+0

Bu, çalışır, ancak ayarlamak istediğim değerler iç anonim sınıfın dışındadır. Sınıf içinde 'updateSales.setString (2, fileRow.getName())' gibi bir şey olmalı ama sınıf içinde 'fileRow 'formuna erişemiyorum. –

+6

var dosyası işaretle Son olarak – Inv3r53

3

Ben en azından bir yönteme taşıma hazırlanmış deyimi çarpanlarına ederim. o zaman çağırarak meselesi olduğunu

private PreparedStatement updateSales; 
public void updateSales(int sales, String cof_name) throws SQLException { 
    if (updateSales == null) { 
     updateSales = con.prepareStatement(
      "UPDATE COFFEES SET SALES = ? WHERE COF_NAME LIKE ?"); 
    } 
    updateSales.setInt(1, sales); 
    updateSales.setString(2, cof_name); 
    updateSales.executeUpdate(); 
} 

Bu noktada: sonuç olduğundan bu durumda, oldukça basit (ve bağlantı değişmez bir örnek değişkeni olduğunu varsayarak) 'dir:

updateSales(75, "Colombian"); 

Başka şeylerle bütünleştirmek oldukça basit, evet? Yöntemi birçok kez çağırırsanız, güncelleme yalnızca bir kez oluşturulacak ve bu da işleri daha hızlı hale getirecektir. Her güncellemeyi kendi işleminde yapmak gibi çılgın şeyler yapmadığınızı varsayalım ...

Türlerin sabit olduğunu unutmayın. Bunun nedeni, belirli bir sorgu/güncelleme için, 'un veritabanının işini verimli bir şekilde yapmasını sağlamak için'un düzeltilmesidir. Bir CSV dosyasından yalnızca rasgele dizeler çekiyorsanız, bunları dizeler olarak geçirin. Ayrıca kilitleme yok; Tekil bağlantıların tek bir iş parçacığından kullanılmasını sağlamak için çok daha iyi. Varsayılan olarak

+0

Tek bir değer döndüren sorgular için bu tekniği de kullanmak oldukça kolaydır. Ana karmaşıklık, birçok değer döndüren sorgularınız olduğunda gelir; ya bir "ResultSet" döndürün ya da her bir döndürülen satırın işleyeceği bir geri aramada (elbette "ResultSet" öğesinden ayrılan değerler ile) geçin. –

+1

Üzgünüz, ama jdbc şablon sorunumla ne ilgisi olduğunu bilmiyorum. Bir jdbc şablon sorgusunu bir PreparedStatement ile besleyemiyorum. Görünüşe göre bir 'PreparedStatementCreator' veya 'PreparedStatementSetter' gerekiyor. –

24

, JDBCTemplate yapar onun kendi PreparedStatement içten, sadece .update(String sql, Object ... args) formu kullanın eğer. Spring ve veritabanınız, derlenmiş sorguyu sizin için yönetecek, böylece açılış, kapanış, kaynak koruması vb. Için endişelenmenize gerek yok. İlkbaharın tasarruflarından biri. A link to Spring 2.5's documentation on this. Umut, işleri daha net hale getirir. Ayrıca, önbellekleme, JDBC seviyesinde, at least some of Oracle's JDBC drivers. durumunda olduğu gibi yapılabilir. Bu, yetkin bir şekilde yapabileceğime göre çok daha fazla ayrıntıya girecektir.

+3

Ancak veritabanında bir seçim yapmak istiyorum, güncelleme değil. Spring referansında http://static.springsource.org/spring/docs/2.0.x/api/org/springframework/jdbc/core/JdbcTemplate.html yazılmıştır, "update" ile sadece bir ekleme, güncelleme veya silme gerçekleştirilebilir. –

+0

@ user3211068 – linqu

+1

@mezmo için seçebileceğiniz bir 'sorgu' yöntemi var mıdır? Ve aynı sorgu için doğrudur (Dize sql, ...)? – leo

14
class Main { 
    public static void main(String args[]) throws Exception { 
     ApplicationContext ac = new 
      ClassPathXmlApplicationContext("context.xml", Main.class); 
     DataSource dataSource = (DataSource) ac.getBean("dataSource"); 
// DataSource mysqlDataSource = (DataSource) ac.getBean("mysqlDataSource"); 

     JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource); 

     String prasobhName = 
     jdbcTemplate.query(
      "select first_name from customer where last_name like ?", 
      new PreparedStatementSetter() { 
       public void setValues(PreparedStatement preparedStatement) throws 
       SQLException { 
        preparedStatement.setString(1, "nair%"); 
       } 
      }, 
      new ResultSetExtractor<Long>() { 
       public Long extractData(ResultSet resultSet) throws SQLException, 
       DataAccessException { 
        if (resultSet.next()) { 
         return resultSet.getLong(1); 
        } 
        return null; 
       } 
      } 
     ); 
     System.out.println(machaceksName); 
    } 
} 
+0

java 8 lambda stili sorgu parçası: 'jdbcTemplate.query (sql, ps -> ps.setString (1," değer "), (rs, i) -> rs.getLong (1)' –