powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Java [игнор отключен] [закрыт для гостей] / Занесение данных из JTable в БД
12 сообщений из 12, страница 1 из 1
Занесение данных из JTable в БД
    #39211946
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.
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
Занесение данных из JTable в БД
    #39211948
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mycodeurnghtmrА как теперь сделать, чтобы при изменении данных в таблице(автоматически или по нажатию на кнопку) они отправлялись в бд?

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

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

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

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

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

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

У Jtable переопределить метод isCellEditable() и в нем реализовать нужную логику, в зависимости от столбца и состояния.
...
Рейтинг: 0 / 0
Занесение данных из JTable в БД
    #39211950
mycodeurnghtmr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Если можно, то с примерами кода. :3
Сложно сразу влиться в яву после ассемблера.
Спасибо ещё раз.
...
Рейтинг: 0 / 0
Занесение данных из JTable в БД
    #39211954
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Занесение данных из JTable в БД
    #39211959
mycodeurnghtmr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Blazkowicz,
о, спасибо огромное, поиск в JXTable есть, ещё раз спасибо за наводку. :3
...
Рейтинг: 0 / 0
Занесение данных из JTable в БД
    #39212079
mycodeurnghtmr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот, исправил некоторые места.
Но, строки удаляются, а вот добавить строку не получается. И можно ли как-то нормально нестатический метод в статическом вызвать?
И так и не понял, как запрос сформировать, чтобы данные из 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
Занесение данных из JTable в БД
    #39212122
Фотография Blazkowicz
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
mycodeurnghtmrНо, строки удаляются, а вот добавить строку не получается.

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

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

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

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

Начните с простого SQL INSERT/UPDATE запроса в JDBC по примерам из интернета. Потом добавите передачу данных из TableModel в этот запрос.
...
Рейтинг: 0 / 0
Занесение данных из JTable в БД
    #39213056
mycodeurnghtmr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Вот, теперь запрос формируется при изменении значения, т.к. в бд во всех таблицах первая колонка-ключ автоинкрементируемый, то через неё и делал "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
Занесение данных из JTable в БД
    #39213065
golovonometr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Занесение данных из JTable в БД
    #39213074
mycodeurnghtmr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
golovonometr,

Спасибо, попробую использовать PreparedStatement. :3
А как на модель листенеры вешать?
Столько нового сразу, не знаю, за что браться.
...
Рейтинг: 0 / 0
Занесение данных из JTable в БД
    #39213075
golovonometr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
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
Занесение данных из JTable в БД
    #39213076
mycodeurnghtmr
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
golovonometr,

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


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