Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / Java [игнор отключен] [закрыт для гостей] / Занесение данных из JTable в БД / 12 сообщений из 12, страница 1 из 1
10.04.2016, 15:44
    #39211946
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
Доброго времени суток!
В общем, есть такой код, таблица берется из БД и на её основе формируется JTable.
А как теперь сделать, чтобы при изменении данных в таблице(автоматически или по нажатию на кнопку) они отправлялись в бд? Как реализовать удаление и добавление строк в JTable? Как осуществлять поиск по таблице?
А ещё, в одном случае в таблице разрешить редактирование только третьего столбца, а в другом-всю таблицу.
Спасибо большое за любую помощь. :3
Код: 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.
150.
151.
package bd_conn;

import javax.swing.table.*;
import java.sql.*;
import java.util.*;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.RowSorter;

public class DatabaseTableModel
        extends AbstractTableModel {
    // здесь названия столбцов
    private ArrayList columnNames = new ArrayList();
    // список типов столбцов
    private ArrayList columnTypes = new ArrayList();
    // хранилище для полученных данных из базы данных
    private ArrayList data = new ArrayList();

    // конструктор позволяет задать возможность редактирования
    public DatabaseTableModel(boolean editable) {
        this.editable = editable;
    }
    private boolean editable;

    // количество строк
    @Override
    public int getRowCount() {
        synchronized (data) {
            return data.size();
        }
    }
    // количество столбцов

    @Override
    public int getColumnCount() {
        return columnNames.size();
    }
    // тип данных столбца

    @Override
    public Class getColumnClass(int column) {
        return (Class) columnTypes.get(column);
    }
    // название столбца

    @Override
    public String getColumnName(int column) {
        return (String) columnNames.get(column);
    }
    // данные в ячейке

    @Override
    public Object getValueAt(int row, int column) {
        synchronized (data) {
            return ((ArrayList) data.get(row)).get(column);
        }
    }
    // возможность редактирования

    @Override
    public boolean isCellEditable(int row, int column) {
        return editable;
    }

    // замена значения ячейки
    @Override
    public void setValueAt(
            Object value, int row, int column) {
        synchronized (data) {
            ((ArrayList) data.get(row)).set(column, value);
        }
    }
    // получение данных из объекта ResultSet

    public void setDataSource(
            ResultSet rs) throws Exception {
        // удаляем прежние данные
        data.clear();
        columnNames.clear();
        columnTypes.clear();
        // получаем вспомогательную информацию о столбцах
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        for (int i = 0; i < columnCount; i++) {
            // название столбца
            columnNames.add(rsmd.getColumnName(i + 1));
            // тип столбца
            Class type
                    = Class.forName(rsmd.getColumnClassName(i + 1));
            columnTypes.add(type);
        }
        // сообщаем об изменениях в структуре данных
        fireTableStructureChanged();
        // получаем данные
        while (rs.next()) {
            // здесь будем хранить ячейки одной строки
            ArrayList row = new ArrayList();
            for (int i = 0; i < columnCount; i++) {
                if (columnTypes.get(i) == String.class) {
                    row.add(rs.getString(i + 1));
                } else {
                    row.add(rs.getObject(i + 1));
                }
            }
            synchronized (data) {
                data.add(row);
                // сообщаем о прибавлении строки
                fireTableRowsInserted(
                        data.size() - 1, data.size() - 1);

            }
        }
    }

   public static void main(String[] args) {
        // инициализация JDBC
        Connection conn;
        try {

            Class.forName("com.mysql.jdbc.Driver");

            String url = "jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8";
            String name = "root";
            String password = "1234";
            conn = DriverManager.getConnection(url, name, password);
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(
                    "select * from goods_t");
            DatabaseTableModel dbm
                    = new DatabaseTableModel(true);
            JTable table = new JTable(dbm);
            RowSorter<TableModel> sorter
                    = new TableRowSorter<>(dbm);
            table.setRowSorter(sorter);
            JFrame frame = new JFrame("DataBaseTable");
            frame.setSize(400, 300);
            frame.getContentPane().add(new JScrollPane(table));
            frame.setVisible(true);
            dbm.setDataSource(rs);
            rs.close();
            conn.close();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null,
                    ex.getMessage(), "Ошибка подключения к БД!",
                    JOptionPane.ERROR_MESSAGE);
        }

    }
}
...
Рейтинг: 0 / 0
10.04.2016, 15:51
    #39211948
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
mycodeurnghtmrА как теперь сделать, чтобы при изменении данных в таблице(автоматически или по нажатию на кнопку) они отправлялись в бд?

Из columnNames/columnTypes формируешь SQL и preparedStatement и выполняешь его.

mycodeurnghtmrКак реализовать удаление и добавление строк в JTable?

Удаляешь или обновляешь значение в поле data, а затем вызываешь у AbstractTableModel методы fire...(), соответствующие изменениям.

mycodeurnghtmrКак осуществлять поиск по таблице?

Написать самому через KeyListener, либо взять готовую реализацию SwingLabs, JGoodies

mycodeurnghtmrА ещё, в одном случае в таблице разрешить редактирование только третьего столбца, а в другом-всю таблицу.

У Jtable переопределить метод isCellEditable() и в нем реализовать нужную логику, в зависимости от столбца и состояния.
...
Рейтинг: 0 / 0
10.04.2016, 16:13
    #39211950
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
Если можно, то с примерами кода. :3
Сложно сразу влиться в яву после ассемблера.
Спасибо ещё раз.
...
Рейтинг: 0 / 0
10.04.2016, 16:33
    #39211954
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
mycodeurnghtmrЕсли можно, то с примерами кода. :3
Сложно сразу влиться в яву после ассемблера.
Спасибо ещё раз.
1) https://docs.oracle.com/javase/tutorial/jdbc/basics/prepared.html
2)
Код: java
1.
2.
data.remove(row);
fireTableRowsDeleted(row, row);


3) Я бы отложил этот пункт.
http://stackoverflow.com/questions/22066387/how-to-search-an-element-in-a-jtable-java
http://stackoverflow.com/questions/31158089/how-to-search-data-in-jtable-using-jtextfield
http://stackoverflow.com/questions/12123456/how-to-implement-search-in-a-jtable
4)
Код: java
1.
2.
3.
4.
@Override
    public boolean isCellEditable(int row, int column) {
        return editable || row == 2;
    }
...
Рейтинг: 0 / 0
10.04.2016, 16:46
    #39211959
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
Blazkowicz,
о, спасибо огромное, поиск в JXTable есть, ещё раз спасибо за наводку. :3
...
Рейтинг: 0 / 0
11.04.2016, 00:06
    #39212079
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
Вот, исправил некоторые места.
Но, строки удаляются, а вот добавить строку не получается. И можно ли как-то нормально нестатический метод в статическом вызвать?
И так и не понял, как запрос сформировать, чтобы данные из JTable в бд сохранить.
Ещё раз спасибо за помощь, кто откликнется. :3
Код: 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.
public void addRow() {

        ArrayList row = new ArrayList();
        row.add(getRowCount() + 1);
        data.add(row);
        fireTableRowsInserted(data.size() - 1, data.size() - 1);

    }

    public static void main_mm() {
        // инициализация JDBC
        Connection conn;
        try {

            Class.forName("com.mysql.jdbc.Driver");

            String url = "jdbc:mysql://localhost:3306/mydb?characterEncoding=utf8";
            String name = "root";
            String password = "1234";
            conn = DriverManager.getConnection(url, name, password);
            Statement st = conn.createStatement();
            ResultSet rs = st.executeQuery(
                    "select * from goods_t");
            DatabaseTableModel dbm
                    = new DatabaseTableModel(true);
            JXTable table = new JXTable(dbm);

            table.setAutoCreateColumnsFromModel(true);
            table.setIgnoreRepaint(false);
            JFrame frame = new JFrame("DataBaseTable");
            JXButton button = new JXButton("Сохранить данные");
            button.addActionListener((ActionEvent evt) -> {
                System.out.println(data.toString());
            });
            JXButton button1 = new JXButton("Удалить строку");
            button1.addActionListener((ActionEvent evt) -> {
                int row = table.getSelectedRow();
                if (row < 0) {
                } else {
                    int recNum = table.convertRowIndexToModel(row);
                    try {
                        ((DatabaseTableModel) table.getModel()).removeRow(recNum);
                        table.clearSelection();
                    } catch (Exception ex) {
                    }
                }

            });

            JXButton button2 = new JXButton("Добавить строку");
            button2.addActionListener((ActionEvent evt) -> {
                new DatabaseTableModel(true).addRow();

            });
            FlowLayout experimentLayout = new FlowLayout();
            frame.setLayout(experimentLayout);
            frame.setSize(400, 300);
            frame.getContentPane().add(new JScrollPane(table));

            frame.getContentPane().add(button);
            frame.getContentPane().add(button1);
            frame.getContentPane().add(button2);
            frame.setVisible(true);
            frame.setLocationRelativeTo(null);
            dbm.setDataSource(rs);
            rs.close();
            conn.close();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null,
                    ex.getMessage(), "Ошибка подключения к БД!",
                    JOptionPane.ERROR_MESSAGE);
        }

    }
}
...
Рейтинг: 0 / 0
11.04.2016, 08:03
    #39212122
Blazkowicz
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
mycodeurnghtmrНо, строки удаляются, а вот добавить строку не получается.

А зачем для этого создавать новую модель? Строку, ведь, нужно добавить в существующую.

mycodeurnghtmrИ можно ли как-то нормально нестатический метод в статическом вызвать?

Можно, если разобраться что такое объекты и классы.

mycodeurnghtmrИ так и не понял, как запрос сформировать, чтобы данные из JTable в бд сохранить.

Начните с простого SQL INSERT/UPDATE запроса в JDBC по примерам из интернета. Потом добавите передачу данных из TableModel в этот запрос.
...
Рейтинг: 0 / 0
11.04.2016, 21:27
    #39213056
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
Вот, теперь запрос формируется при изменении значения, т.к. в бд во всех таблицах первая колонка-ключ автоинкрементируемый, то через неё и делал "where", если подскажите, как сделать более универсальный вариант-не откажусь.
Но так и не разобрался с добавлением строк и при удалении строки не синхронизируется с бд.
А ещё, в этом классе надо будет реализовать работу с тремя таблицами, либо на каждом фрейме вывести свою таблицу, предварительно показав список таблиц для выбора.
Как это правильнее и с наименьшими затратами реализовать?
Причем одна таблица должна быть нередактируемой.
Спасибо огромное за помощь?
Код: 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.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.swing.table.*;
import java.sql.*;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import org.jdesktop.swingx.JXButton;
import org.jdesktop.swingx.JXTable;

public class DatabaseTableModel
        extends AbstractTableModel {

    public String tableName;
    public Connection conn;
    public ResultSetMetaData metaData = null;
    // здесь мы будем хранить названия столбцов
    private ArrayList columnNames = new ArrayList();
    // список типов столбцов
    private ArrayList columnTypes = new ArrayList();
    // хранилище для полученных данных из базы данных
    private static ArrayList data = new ArrayList();

    // конструктор позволяет задать возможность редактирования
    public DatabaseTableModel(boolean editable) {
        this.editable = editable;
    }
    private boolean editable;

    // количество строк
    @Override
    public int getRowCount() {
        synchronized (data) {
            return data.size();
        }
    }
    // количество столбцов

    @Override
    public int getColumnCount() {
        return columnNames.size();
    }
    // тип данных столбца

    @Override
    public Class getColumnClass(int column) {
        return (Class) columnTypes.get(column);
    }
    // название столбца

    @Override
    public String getColumnName(int column) {
        return (String) columnNames.get(column);
    }
    // данные в ячейке

    @Override
    public Object getValueAt(int row, int column) {
        synchronized (data) {
            return ((ArrayList) data.get(row)).get(column);
        }
    }

    public boolean isCellEditable(int row, int column) {
        return true;
    }

    public void removeRow(int rowIndex) {

        data.remove(rowIndex);
        fireTableRowsDeleted(rowIndex, rowIndex);

    }

    // получение данных из объекта ResultSet
    public void setDataSource(
            ResultSet rs) throws Exception {
        // удаляем прежние данные
        data.clear();
        columnNames.clear();
        columnTypes.clear();
        // получаем вспомогательную информацию о столбцах
        ResultSetMetaData rsmd = rs.getMetaData();
        int columnCount = rsmd.getColumnCount();
        for (int i = 0; i < columnCount; i++) {
            // название столбца
            columnNames.add(rsmd.getColumnName(i + 1));
            // тип столбца
            Class type
                    = Class.forName(rsmd.getColumnClassName(i + 1));
            columnTypes.add(type);
        }
        // сообщаем об изменениях в структуре данных
        fireTableStructureChanged();
        // получаем данные
        while (rs.next()) {
            // здесь будем хранить ячейки одной строки
            ArrayList row = new ArrayList();
            for (int i = 0; i < columnCount; i++) {
                if (columnTypes.get(i) == String.class) {
                    row.add(rs.getString(i + 1));
                } else {
                    row.add(rs.getObject(i + 1));
                }
            }
            synchronized (data) {
                data.add(row);
                // сообщаем о прибавлении строки
                fireTableRowsInserted(
                        data.size() - 1, data.size() - 1);

            }
        }
    }

    public void addRow() {
        ArrayList row = new ArrayList();
        row.add(getRowCount() + 1);
        data.add(row);
        fireTableRowsInserted(data.size() - 1, data.size() - 1);

    }

    @Override
    public void setValueAt(
            Object value, int row, int column) {
        synchronized (data) {
            ((ArrayList) data.get(row)).set(column, value);
        }
        try {
            String columnName = getColumnName(column);
            String query
                    = "UPDATE " + "goods_t"
                    + " SET " + columnName + " = "
                    + value
                    + " WHERE "
                    + getColumnName(0) + " = "
                    + getValueAt(row, 0);

            System.out.println(value);
            System.out.println(columnName);

            connect().executeUpdate(query);
        } catch (SQLException | ClassNotFoundException | IOException ex) {
            Logger.getLogger(DatabaseTableModel.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public Statement connect() throws ClassNotFoundException, SQLException, FileNotFoundException, IOException {
        Properties props = new Properties();
        FileInputStream in = new FileInputStream("db_properties.txt");
        props.load(in);
        in.close();
        String driver = props.getProperty("driver");
        Class.forName(driver);
        String url = props.getProperty("url");
        String name = props.getProperty("user");
        String password = props.getProperty("password");
        conn = DriverManager.getConnection(url, name, password);
        Statement st = conn.createStatement();
        return st;
    }

    public void main_mm() {
        // инициализация JDBC
        try {
            ResultSet rs = connect().executeQuery(
                    "select * from goods_t");
            DatabaseTableModel dbm
                    = new DatabaseTableModel(true);
            JXTable table = new JXTable(dbm);

            table.setAutoCreateColumnsFromModel(true);
            table.setIgnoreRepaint(false);
            JFrame frame = new JFrame("DataBaseTable");
            JXButton button = new JXButton("Сохранить данные");
            button.addActionListener((ActionEvent evt) -> {
                System.out.println(data.toString());
            });
            JXButton button1 = new JXButton("Удалить строку");
            button1.addActionListener((ActionEvent evt) -> {
                int row = table.getSelectedRow();
                if (row < 0) {
                } else {
                    int recNum = table.convertRowIndexToModel(row);
                    try {
                        ((DatabaseTableModel) table.getModel()).removeRow(recNum);
                        table.clearSelection();
                    } catch (Exception ex) {
                    }
                }

            });

            JXButton button2 = new JXButton("Добавить строку");
            button2.addActionListener((ActionEvent evt) -> {
                new DatabaseTableModel(true).addRow();
                addRow();
            });
            FlowLayout experimentLayout = new FlowLayout();
            frame.setLayout(experimentLayout);
            frame.setSize(400, 300);
            frame.getContentPane().add(new JScrollPane(table));

            frame.getContentPane().add(button);
            frame.getContentPane().add(button1);
            frame.getContentPane().add(button2);
            frame.setVisible(true);
            frame.setLocationRelativeTo(null);
            dbm.setDataSource(rs);
            rs.close();
            conn.close();
        } catch (Exception ex) {
            JOptionPane.showMessageDialog(null,
                    ex.getMessage(), "Ошибка подключения к БД!",
                    JOptionPane.ERROR_MESSAGE);
        }

    }
}
...
Рейтинг: 0 / 0
11.04.2016, 21:56
    #39213065
golovonometr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
mycodeurnghtmr, мне кажется тебе стоит формировать запросы в бд, когда изменяется сама модель. На модель вешать свои листенеры.

Но никогда, никогда, не пиши вот так:
Код: java
1.
2.
3.
4.
5.
6.
7.
            String query
                    = "UPDATE " + "goods_t"
                    + " SET " + columnName + " = "
                    + value
                    + " WHERE "
                    + getColumnName(0) + " = "
                    + getValueAt(row, 0);


Забудь, используй PreparedStatement!

Если твое поле в базе автоинкремент, уникально, и ты используешь как айди - гуд, какие сомнения?
...
Рейтинг: 0 / 0
11.04.2016, 22:05
    #39213074
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
golovonometr,

Спасибо, попробую использовать PreparedStatement. :3
А как на модель листенеры вешать?
Столько нового сразу, не знаю, за что браться.
...
Рейтинг: 0 / 0
11.04.2016, 22:09
    #39213075
golovonometr
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
mycodeurnghtmrgolovonometr,

Спасибо, попробую использовать PreparedStatement. :3
А как на модель листенеры вешать?
Столько нового сразу, не знаю, за что браться.

Может так?

Код: java
1.
2.
3.
4.
5.
6.
table.getModel().addTableModelListener(new TableModelListener() {

      public void tableChanged(TableModelEvent e) {
         // your code goes here;
      }
    });
...
Рейтинг: 0 / 0
11.04.2016, 22:13
    #39213076
mycodeurnghtmr
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Занесение данных из JTable в БД
golovonometr,

Вероятно так. :3
Да, и спасибо ещё раз за помощь с дизассемблером.
...
Рейтинг: 0 / 0
Форумы / Java [игнор отключен] [закрыт для гостей] / Занесение данных из JTable в БД / 12 сообщений из 12, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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