Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Использование PreparedStatement / 10 сообщений из 10, страница 1 из 1
25.06.2015, 18:00
    #38993008
alexander30
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
Добрый день ,возник вопрос
Есть код

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
    public class MarkDao extends Dao<Mark> {
     
    Connection connection=null;
    ResultSet resultSet=null;
    PreparedStatement insert=null;
        PreparedStatement select=null;
        PreparedStatement delete=null;
        PreparedStatement update=null;
     
    private String url="jdbc:mysql://localhost:3306/student";
    private String password="root";
    private String user="root";
    public Connection getConnection() {
     
    try {
    Class.forName("com.mysql.jdbc.Driver");
    if(connection==null){
    connection= DriverManager.getConnection(url, password, user);
    }
    } catch (ClassNotFoundException e) {
    e.printStackTrace();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    return connection;
    }
     
     
     
    @Override
    public void insert(Mark obj) {
    String sql="insert into mark ( student_id, discipline_id, mark) values (?,?,?);";
    try {
    insert=connection.prepareStatement(sql);
    insert.setInt(1, obj.getStudent_id());
    insert.setInt(2, obj.getDiscipline_id());
    insert.setInt(3, obj.getMark());
    insert.executeUpdate();
    } catch (SQLException e) {
    e.printStackTrace();
        closePreparedStatement();
    }
    }
     
    @Override
    public List<Mark> select() {
    List<Mark> marks=new LinkedList<>();
    String sql="select id, student_id, discipline_id, mark from mark" ;
    Mark mark=null;
    try {
    select=connection.prepareStatement(sql);
    resultSet=select.executeQuery();
    while(resultSet.next()){
    mark=new Mark();
    mark.setId(resultSet.getInt("id"));
     
    mark.setStudent_id(resultSet.getInt("student_id"));
    mark.setDiscipline_id(resultSet.getInt("discipline_id"));
    mark.setMark(resultSet.getInt("mark"));
    marks.add(mark);
    }
    } catch (SQLException e) {
    e.printStackTrace();
    }finally {
    if(resultSet!=null){
    try {
    resultSet.close();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    }
    }
        closePreparedStatement();
    System.out.println(marks);
    return marks;
      
    }
     
    @Override
    public void delete(Mark obj, int id) {
    String sql="delete from mark where id=?;";
    try {
    delete=connection.prepareStatement(sql);
    delete.setInt(1, id);
    delete.executeUpdate();
     
    } catch (SQLException e) {
    e.printStackTrace();
    }
        closePreparedStatement();
    }
     
    @Override
    public void update(Mark obj) {
    String sql="Update mark set mark=? where id=?;";
    try {
    update=connection.prepareStatement(sql);
     
    update.setInt(1, obj.getId());
    update.executeUpdate();
    } catch (SQLException e) {
    e.printStackTrace();
    }
    closePreparedStatement();
    }
     
    public void closeConnection() {
    try {
    if (connection != null) {
    connection.close();
    }
    } catch (Exception e) {
     
    }
     
    }
     
        public void closePreparedStatement() {
            try{
                if (insert!=null ){
                    insert.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try{
                if (select!=null ){
                    select.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try{
                if (update!=null ){
                    update.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
            try{
                if (delete!=null ){
                    delete.close();
                }
            }catch (SQLException e){
                e.printStackTrace();
            }
     
        }
    }





Мне говорят,что я не правильно использую PS , нужно "Один раз инициализировать , много раз его использовать и потом один раз каждый закрыть"

а у меня ,например здесь ,сколько раз будет вызываться insert - столько будет вызываться создание PS.
А должно быть один раз создать перед всеми вызовами, и одни раз закрыть после всех вызовов .

Код: java
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
    public void insert(Mark obj) {
    String sql="insert into mark ( student_id, discipline_id, mark) values (?,?,?);";
    try {
    insert=connection.prepareStatement(sql);
    insert.setInt(1, obj.getStudent_id());
    insert.setInt(2, obj.getDiscipline_id());
    insert.setInt(3, obj.getMark());
    insert.executeUpdate();
    } catch (SQLException e) {
    e.printStackTrace();
        closePreparedStatement();
    }
    }
     



Я не понимаю ,что мне нужно деалать(точнее как).
...
Рейтинг: 0 / 0
25.06.2015, 19:10
    #38993050
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
alexander30Мне говорят,что я не правильно использую PS , нужно "Один раз инициализировать , много раз его использовать и потом один раз каждый закрыть"

По-моему ваши советчики заблуждаются.

alexander30Я не понимаю ,что мне нужно деалать(точнее как).
Для начала перейти на try with resource
http://stackoverflow.com/questions/8066501/how-should-i-use-try-with-resources-with-jdbc
...
Рейтинг: 0 / 0
25.06.2015, 21:25
    #38993110
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
Blazkowiczalexander30Мне говорят,что я не правильно использую PS , нужно "Один раз инициализировать , много раз его использовать и потом один раз каждый закрыть"

По-моему ваши советчики заблуждаются.

Почему они заблуждаются?
...
Рейтинг: 0 / 0
26.06.2015, 07:48
    #38993241
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
Leonid KudryavtsevПочему они заблуждаются?
Потому что смысл фразы "один раз инициализировать" странный.
Переиспользовать PreparedStatement имеет смысл только для batch update. Я не вижу чтобы он здесь сильно нужен был. И топикастеру про batch\пакетную обработку тоже ничего не сказали.
План же самого запроса в RDBMS будет и так переиспользоваться, как раз из-за PreparedStatement и отсутствия динамических запросов. Основные проблемы приведенного кода в работе с Connection без DataSource, закрытием без finally и с полями, которые не только бесполезны но ещё и вылезут боком в многопоточном окружении.
...
Рейтинг: 0 / 0
26.06.2015, 09:07
    #38993273
Alexey Tomin
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
alexander30Есть код

Многабукв ;)

В коде каша.
В создание запроса каждый раз нет большой проблемы, если операции не идут часто. Т.е. это МОЖЕТ быть проблемой, но не факт, что будет. Но хранение PreparedStatement создаёт другие проблемы- протухания коннекта, к примеру. Или многопоточного вызова :D
А вот что надо сделать в первую очредь, так это:

1. Т.к. есть некое "extends Dao", то логично вынести создание коннекта в отдельный класс- вот он-то как раз пусть будет один на всех. Заодно, если случится, легко сделать пересоздание коннекта (реально связь с БД может теряться, если это не студенческий проект)
2. Если PreparedStatement создаётся каждый раз, то не надо полей в классе.
3. Надо использовать try-with-resource
4. Ещё плохо в Вашем поде явное указание пути к БД и логина/пароля. Это должно быть в ресурсах, или ХОТЯ БЫ константах.

alexander30Я не понимаю ,что мне нужно деалать(точнее как).

А это не вопрос. Это диагноз.
...
Рейтинг: 0 / 0
26.06.2015, 11:26
    #38993432
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
BlazkowiczПлан же самого запроса в RDBMS будет и так переиспользоваться, как раз из-за PreparedStatement и отсутствия динамических запросов.
Не скажи. На днях показывал челу, что вынос создания PreparedStatement из цикла и его переиспользование убирает ошибку Oracle про количество открытых курсоров.
Так что на RDBMS надейся, а сам не плошай.
...
Рейтинг: 0 / 0
26.06.2015, 11:42
    #38993452
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
Сергей Арсеньев Не скажи. На днях показывал челу, что вынос создания PreparedStatement из цикла и его переиспользование убирает ошибку Oracle про количество открытых курсоров.
Так что на RDBMS надейся, а сам не плошай.
Натянул сову на глобус. Я тут цикла не вижу.
...
Рейтинг: 0 / 0
26.06.2015, 15:04
    #38993780
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
Blazkowicz,

alexander30 а у меня ,например здесь ,сколько раз будет вызываться insert - столько будет вызываться создание PS.
А должно быть один раз создать перед всеми вызовами, и одни раз закрыть после всех вызовов .
То есть предполагается многократное количество вызовов insert подряд извне.
В теле класса его и не увидишь.

М.б. надо было создать, что-то типа static void insertAll(...)
...
Рейтинг: 0 / 0
26.06.2015, 15:07
    #38993786
Сергей Арсеньев
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
но в любом случае хранить в каждом DAO connection - это не совсем верно...
...
Рейтинг: 0 / 0
26.06.2015, 16:35
    #38993962
Leonid Kudryavtsev
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Использование PreparedStatement
Народ, не путайте божий дар с яичницей.

PreparedStatement он по тому и PREPARED, что его можно создать один раз, один раз разпарсить SQL команду и дальше много раз делать INSERT.

С этой точки зрения, коллеги абсолютно правы. Будет экономиться как heap в java (меньше мусора), сетевой трафик (роунд-трипы), ресурсы сервера (не нужно будет делать лишних парсе) etc...

Дальше начинается яичница, то бишь Java. В которой разработчики решили не вводить ООП-диструкторы. Соответственно инициализируя PreparedStatement один раз и сохраняя его например в данных класса, есть риск получить resource leak.

IMHO & AFAIK
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Использование PreparedStatement / 10 сообщений из 10, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]