2016-02-11 1 views
1

В классе для обработки транзакций SQL в Java я все время использую классы PreparedStatement и ResultSet.Переменное повторное использование в java

Мне было интересно узнать, что было бы лучше (более эффективной) практикой в ​​Java; объявив их членами класса ...

class SqlThingy { 
    PreparedStatement pstx; 
    ResultSet rs; 
    public void SqlThingyMethod() { 
     pstx = database.connection.prepareStatement("..."); 
     .... 
    } 
} 

... или как локальные переменные отдельных методов?

class SqlThingy { 
    public void SqlThingyMethod() { 
     PreparedStatement pstx; 
     ResultSet rs; 
     pstx = database.connection.prepareStatement("..."); 
    } 
} 

ли VM просто перезаписать содержимое члена класса с (ссылка на) новый PreparedStatement, или это будет сделать некоторые дополнительные инициализации, который также утверждает, ресурсы и даже из-за разницы распределения локальных переменных каждый раз ?

+0

Thats upto зависит от ваших потребностей. Если вы хотите использовать эти переменные далее в одном классе, объявляет его вне любого метода (1). – Satya

+0

Существует незначительное увеличение производительности при использовании локальной переменной. Тем не менее, вы должны больше сосредоточиться на том, чтобы сделать код Java понятным. Если вам нужно повторно использовать переменную, сделайте это поле, если нет, сделайте его локальным. Вы должны прочитать этот ответ, который содержит некоторые тесты http://stackoverflow.com/a/21614413/3280538 – flakes

+0

Вы даже не используете правильный синтаксис для методов в вашем примере, поэтому у вас есть более важные вещи, о которых стоит беспокоиться, чем эффективности. – Kayaman

ответ

0

Поля уровня экземпляра не являются потокобезопасными, поэтому JVM должен будет гарантировать, что к ним обращаются/используются должным образом (хотя escape-анализ оптимизирует это до действительно хорошей степени).

Локальные переменные метода являются потокобезопасными, поэтому JVM не нужно беспокоиться слишком много о том, как используются экземпляры.

Итак, лучше использовать метод 2 (если вы не получаете ссылки из другого места и ссылки не содержатся в методе).

0

Ваша переменная экземпляра pstx - это просто слот, содержащий ссылку. Вы на самом деле не используете один и тот же объект, вы просто держитесь за устаревшую ссылку, пока другой вызов метода не перезапишет ее.

PreparedStatement и ResultSet создаются из соединения с базой данных, если вы получаете новое соединение с базой данных, вы также должны получить новое PreparedStatement. Вы не можете повторно использовать PreparedStatement или ResultSet для всех подключений.

Используйте локальные переменные для PreparedStatements и ResultSets и закройте их, когда вы закончите с ними: получите свое соединение, выполните свои операции и закройте все ресурсы jdbc на выходе из метода. Предоставление этим объектам зависания дольше, чем абсолютно необходимо, не приносит вам никакой пользы, и оно может освобождать ресурсы сервера базы данных так быстро, как только может быть.

Единственная оптимизация в том, что если вы выполняете повторные операции с использованием одного и того же соединения, имеет смысл сохранить один и тот же экземпляр PreparedStatement для всех из них, чтобы сервер базы данных мог подготовить и повторно использовать этот sql.

Вы не говорите, в каком контексте вы пишете этот код. Для веб-приложений вам нужен пул соединений, см. Is there a reason for never closing a JDBC connection?, если вы повторно используете одно и то же соединение для всех запросов в веб-приложении.

0

Короткий ответ: Это зависит.

Длинный ответ:

  • Если переменная будет использоваться во всей программе, а затем объявить их как члены класса будет лучшим вариантом.
  • Если переменная должна использоваться только в одном методе или блоке, то объявление ее в блоке было бы лучше.
0

Вы, кажется, думаете, что используете что-то повторно, но это не так. Каждый раз, когда вызывается метод, в обоих примерах создается новый объект.

Два основных отличия:

  • в вашем втором примере объекты имеют право на сбор мусора, как только выходит метод - в первом они не будут собираться, пока не будет вызван метод снова или содержащийся объект становится пригодным для сбора мусора
  • во втором примере внешний код не может изменять ваше утверждение во время его использования - в первом примере другой код со ссылкой на ваш класс может изменить подготовленный оператор и испортить с которыми вы работаете

Нижняя линия: всегда старайтесь как можно меньше сохранять области (т. Е. используйте локальную переменную, если можете).

0

Считается хорошей практикой ограничить область действия переменных до минимума, который вы будете использовать. В этом конкретном случае, хотя вы будете повторно использовать свои переменные, учтите, что переменные будут ссылаться на объекты, и, например, ResultSet будет ссылаться на результат вашего запроса. Если вы позволите переменной выйти из области действия (вы объявите ее локальной), ссылочные значения (и заполняемая память) будут готовы к сбору GC. Если вы укажете его как переменную класса, время пройдет, и ваша память останется ссылкой на переменную, поэтому она не будет бесплатной до тех пор, пока экземпляр класса «SqlThingy» не выйдет из сферы действия.

0

Ответ «это зависит», но в целом второе лучше для производительности и безопасности.

Первый может привести к pstx иметь более длительный срок службы, чем второй, и также отключить JVM оптимизаций, таких как анализ побега, стек распределения и т.д.

Практически единственная причина, когда первый из них предпочтительнее, когда экземпляр можно повторно использовать и, таким образом, избежать затрат на инициализацию.

1

Обязательно различайте переменные и объекты, на которые они указывают. Как общий принцип, не используйте повторно переменные для обозначения разных объектов. Это чрезвычайно подвержено ошибкам.

В вашем конкретном примере, поскольку вы воссоздаете объект соединения в каждом вызове до SqlThingyMethod, скорее всего, нет никакой пользы для его хранения в поле. Используйте локальную переменную.

Переменные дешевые. Объекты, если не совсем дорогие, дешевле. В этом случае объект может быть действительно дорогим, но переменной нет.