Participer au site avec un Tip
Rechercher
 

Améliorations / Corrections

Vous avez des améliorations (ou des corrections) à proposer pour ce document : je vous remerçie par avance de m'en faire part, cela m'aide à améliorer le site.

Emplacement :

Description des améliorations :

Swing - KSqlQueryTable - Lister le contenu d'une requête SQL

KDatabaseTree - lister le contenu d'une BD SQL Coder un explorateur de BD SQL



Accès rapide :
Présentation du composant KSqlQueryTable
Testons notre composant graphique

Présentation du composant KSqlQueryTable

Une requête SQL renvoie, avec l'API JDBC, un objet de type java.sql.ResultSet. Cet objet correspond, en simplifiant les choses, à une grille de données : un composant javax.swing.JTable semble donc tout indiqué pour afficher les informations contenues dans ce jeu de résultats. En fait, un ResultSet est un peu plus compliqué que ça, étant donné qu'il contient des méta-données sur la structure des données retournées. C'est une très bonne nouvelle pour nous, car nous allons pouvoir aussi affiché une colonne de titre et correctement gérer le tri des colonnes (si on connaît le type de chaque colonne, on saura comment les trier).

Outre la grille de données (le composant JTable), le vous propose aussi d'ajouter une zone d'édition de texte permettant d'éditer la requête à exécuter. Voir un aperçu du composant que nous allons produire.

Exemple d'utilisation du composant KSqlQueryTable

Il faut savoir qu'un composant graphique JTable implémente un pattern MVC : il faudra donc fournir un modèle de données à afficher. Voici le code de la classe KSqlQueryTable.

 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 
package fr.koor.swing.jdbc;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.net.URL;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToggleButton;
import javax.swing.JToolBar;


public class KSqlQueryTable extends JPanel {

    private static final long serialVersionUID = 49430999630928568L;

    
    private Connection connection = null;

    private JSplitPane horizontalSplitPane = null;
    private JTextArea txtSqlCode = new JTextArea();
    private JTable sqlResultTable = new JTable();
    

    public KSqlQueryTable() {
        super( new BorderLayout() );
        

        txtSqlCode.setBorder( BorderFactory.createLineBorder( Color.WHITE ) );
        txtSqlCode.addKeyListener( new KeyAdapter() {
            @Override
            public void keyReleased( KeyEvent event  ) {
                if ( event.getKeyCode() == KeyEvent.VK_ENTER && 
                     ( event.getModifiersEx() & KeyEvent.CTRL_DOWN_MASK ) > 0 ) {
                    setQuery( txtSqlCode.getText() );
                }
            }
        });
        
        sqlResultTable.setAutoCreateRowSorter( true );

        horizontalSplitPane = new JSplitPane( JSplitPane.VERTICAL_SPLIT, 
                                              null /*new JScrollPane( txtSqlCode )*/, 
                                              new JScrollPane( sqlResultTable ) );
        
        this.add( createToolBar(), BorderLayout.NORTH );
        this.add( horizontalSplitPane, BorderLayout.CENTER );
    }

    private JToolBar createToolBar() {
        JToolBar toolBar = new JToolBar();

        URL url = getClass().getResource( "/images/sql.png" );
        JToggleButton btnViewCode = new JToggleButton( new ImageIcon( url ) );
        btnViewCode.addItemListener( (e) -> {
            horizontalSplitPane.setTopComponent( btnViewCode.isSelected() ? txtSqlCode : null );
            horizontalSplitPane.setDividerLocation(40);
            updateUI();
        });
        toolBar.add( btnViewCode );

        url = getClass().getResource( "/images/run.png" );
        JButton btnExecuteSql = new JButton( new ImageIcon( url ) );
        btnExecuteSql.addActionListener( (e) -> setQuery( txtSqlCode.getText() ) );     
        toolBar.add( btnExecuteSql );
        
        return toolBar;
    }
    

    public void setConnection( Connection connection ) {
        if ( connection == null ) throw new NullPointerException();
        this.connection = connection;
    }

    public void setQuery( String query ) {
        try ( Statement statement = this.connection.createStatement();
              ResultSet resultSet = statement.executeQuery( query ) ) {
            
            KSqlQueryTableModel model = new KSqlQueryTableModel( resultSet );
            sqlResultTable.setModel( model );

            txtSqlCode.setText( query );
        } catch ( Exception exception ) {
            exception.printStackTrace();
            sqlResultTable.setModel( null );
        }
    }
    
}
KSqlQueryTable - Lister le contenu d'une requête SQL

Et voici maintenant le code du modèle de données de la grille : il dérive de la classe javax.swing.table.AbstractTableModel.

 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 
package fr.koor.swing.jdbc;

import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;

import javax.swing.table.AbstractTableModel;

public class KSqlQueryTableModel extends AbstractTableModel {

    private static final long serialVersionUID = 5618868029037443430L;
    
    private ArrayList<String> columnsNames = new ArrayList<String>();
    private ArrayList<String> columnsTypes = new ArrayList<String>();
    
    private ArrayList< ArrayList<Object> > values = new ArrayList<ArrayList<Object>>();
    
    public KSqlQueryTableModel( ResultSet resultSet ) throws SQLException {
        ResultSetMetaData rsmd = resultSet.getMetaData();
        int columnCounts = rsmd.getColumnCount();
        for( int i=1; i<= columnCounts; i++ ) {
            columnsNames.add( rsmd.getColumnName( i ) );
            columnsTypes.add( rsmd.getColumnClassName( i ) );
        }
        while( resultSet.next() ) {
            ArrayList<Object> line = new ArrayList<Object>();
            for( int i=1; i<= columnCounts; i++ ) {
                line.add( resultSet.getObject( i ) );
            }
            values.add( line );
        }
    }
    
    @Override public Class<?> getColumnClass( int column ) {
        String type = this.columnsTypes.get( column );
        try {
            return Class.forName( type );
        } catch( Exception e ) {
            return String.class;
        }
    }
    
    @Override public String getColumnName(int i) {
        return columnsNames.get( i );
    }

    @Override public int getColumnCount() {
        return columnsNames.size();
    }

    @Override public int getRowCount() {
        return values.size();
    }

    @Override public Object getValueAt( int line, int column ) {
        return values.get( line ).get( column );
    }
    
}
Les diverses classes de noeuds utilisés pour l'arborescence.

Testons notre composant graphique

Pour tester ce composant, il nous suffit de créer une fenêtre, d'y injecter notre composant et, enfin, de fournir une connexion à une base de données, ainsi que la requête à y exécuter. Voici ma proposition de code.

 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 
import java.awt.BorderLayout;
import java.sql.Connection;
import java.sql.DriverManager;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.nimbus.NimbusLookAndFeel;

import fr.koor.swing.jdbc.KDatabaseTree.DatabaseSelectionEvent;
import fr.koor.swing.jdbc.KSqlQueryTable;


public class Test extends JFrame {
    
    private static final long serialVersionUID = 4443303248990993973L;
    
    
    public Test() {
        super( "KSqlQueryTable component test" );
        this.setSize( 600, 300 );
        this.setLocationRelativeTo( null );
        this.setDefaultCloseOperation( DISPOSE_ON_CLOSE );
        
        // --- On récupère le contentPane ---
        JPanel contentPane = (JPanel) getContentPane();
        
        // --- On ajoute le composant d'affichage de contenu de la base ---
        String driver = "org.mariadb.jdbc.Driver";
        String url = "jdbc:mariadb://localhost:3306/WebStore";
        String login = "root";
        String password = "";
        try {
            Class.forName( driver );
            try ( Connection connection = DriverManager.getConnection( url, login, password ) ) {
                KSqlQueryTable table = new KSqlQueryTable();
                table.setConnection( connection );
                table.setQuery( "SELECT * FROM T_Articles" );
                contentPane.add( table, BorderLayout.CENTER );
            }           
        } catch (Exception exception) {
            exception.printStackTrace();
        }
    }
    
    // --- Affiche le nom de la table double-cliquée ---
    public void displayTableName( DatabaseSelectionEvent event ) {
        System.out.println( event.getTableName() );
    }

    // --- Point d'entrée du programme ---
    public static void main(String[] args) throws Exception {
        UIManager.setLookAndFeel( new NimbusLookAndFeel() );
        Test frame = new Test();
        frame.setVisible(true);
    }
    
}
Classe de test du composant KSqlQueryTable


KDatabaseTree - lister le contenu d'une BD SQL Coder un explorateur de BD SQL