2008-12-23 15 views
22

Me gustaría saber si podemos reutilizar el mismo objeto Statement para ejecutar más de una consulta. O bien, deberíamos crear una nueva declaración para diferentes consultas.Reutilización de objetos de instrucciones Java?

Por ejemplo,

Connection con = getDBConnection(); 
Statement st1 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
int i = st1.executeUpdate("update tbl_domu set domU_status=1 where domU_id=" + dom_U_id); 
Statement st2 = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY); 
String date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(Calendar.getInstance().getTime()); 
int j = st2.executeUpdate("insert into tbl_domU_action_history values('" + dom_U_name + "', 1, '" + date + "')"); 

En el caso anterior, ¿hay algún daño en el uso de la misma st1 comunicado tanto para las consultas executeUpdate()? ¿Puedo usar el mismo objeto Statement st1 para otro executeQuery()?

Respuesta

15

Sí, puedes. Sin embargo, es mucho mejor usar PreparedStatement para evitar vulnerabilidades de inyección de SQL.

0

Cuando asigna algo a un tipo de referencia, reemplaza la referencia anterior por una nueva.

Por ejemplo ...

MyObject obj = new MyObject("foo"); 
obj = new MyObject("bar"); 

tendría una instancia ya no hace referencia de MiObjeto con alguna propiedad establecida en "foo" que con el tiempo será el recolector de basura.

obj almacena una referencia a un objeto MyObject con alguna propiedad establecida en "barra".

+1

Esto no es exactamente lo que está haciendo. Él está preguntando si puede reutilizar la * misma * instancia, no solo la misma referencia – n4rzul

2

El punto original de utilizar declaraciones preparadas fue evitar tener el análisis de la base de datos y volver a compilar la declaración, por lo que se supone que es más rápido.

No había considerado el uso de las vulnerabilidades de inyección SQL, pero no estoy seguro de qué hacer, si se realiza alguna comprobación de datos. Sospecho que depende del conductor, ya que la implementación del controlador es libre de unir las declaraciones. Si alguien tiene más detalles, por favor publique.

+0

Parece que la especificación JDBC no requiere el manejo correcto de caracteres especiales. Me gustaría escuchar acerca de cualquier controlador que no lo haga para que puedan evitarse. –

+0

Steve, la idea re: la inyección de SQL es que el uso de declaraciones parametrizadas evita el riesgo. Ver http://en.wikipedia.org/wiki/SQL_injection#Preventing_SQL_Injection. Por supuesto, tienes razón en que su propósito original era evitar un análisis innecesario. –

+0

Sí, sin embargo, como los controladores simplemente implementan la (s) interfaz (es) JDBC, no está claro en qué medida esto está sucediendo en realidad, y es totalmente dependiente de los implementadores del controlador. Esperaba que alguien tuviera un conocimiento más específico basado en haber tenido que lidiar con este problema en el pasado. –

19

me encontré con la respuesta que estaba buscando en el Javadocs

Por defecto, sólo un objeto ResultSet por objeto Statement se puede abrir al mismo tiempo. Por lo tanto, si la lectura de un objeto ResultSet se intercala con la lectura de otro, cada uno debe haber sido generado por diferentes objetos Statement.

+6

No veo cómo responde esto a la pregunta: ¿debemos llamar al método close() en el extracto? –

1

No estoy seguro de que los conjuntos de resultados obtengan basura si solo están cerrados. Creo que tuve una pérdida de memoria genial cuando estaba escribiendo un grupo de conexiones, por lo que la misma declaración/conexión se reutilizó un millón de veces. Seguí derribando mi JVM. Supongo que esto también podría ser específico de la implementación ya que la recolección de garabatos de un conjunto cerrado de resultados puede no ser probado.

Cuestiones relacionadas