[Java] Créons une bibliothèque d'accès à la base de données!

Public cible

Je veux en faire une bibliothèque, mais je ne sais pas quoi faire ... Pour ceux qui ont de tels problèmes, je vais expliquer en utilisant DAO (Data Access Object) comme exemple.

Le secret pour créer une bibliothèque

Autrement dit, ne pensez pas soudainement à la logique du contenu. Penser aux choses de l'extérieur. Cela conduit également à l'orientation de l'objet.

Plus précisément, je pense que ce qui suit devrait être considéré du point de vue de l'utilisateur de la bibliothèque.

Essayons réellement

Thème à créer dans la bibliothèque

Je voudrais faire de DAO (Data Access Object) le thème.

Tout d'abord, jetez un œil au code ci-dessous Ensuite, réfléchissons au type de constructeur et de méthode faciles à utiliser.

Code d'accès DB


import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;

/**Maître utilisateur DAO*/
public class UserMstDao{
    private Connection connection;
    public UserMstDao(Connection connection){
        this.connection = connection;
    }

    /**Obtenez 1 enregistrement d'utilisateur*/
     * @throws SQLException */
    public UserMst selectUser(String userId) throws SQLException{
        PreparedStatement ps = connection.prepareStatement("select * from UserMst where userId = ?");
        ps.setObject(1, userId);
        ResultSet rs = ps.executeQuery();
        UserMst bean = null;
        if (rs.next()) {
            bean= new UserMst();
            bean.userId = (Integer)rs.getObject("userId");
            bean.userName = (String)rs.getObject("userName");
        }
        return bean;
    }

    /**Obtenez tous les enregistrements d'utilisateurs*/
     * @throws SQLException */
    public List<UserMst> selectUserList() throws SQLException{
    	PreparedStatement ps = connection.prepareStatement("select * from UserMst");
    	ResultSet rs = ps.executeQuery();
        List<UserMst> list = new ArrayList<>();
        while (rs.next()) {
            UserMst bean = new UserMst();
            bean.userId = (Integer)rs.getObject("userId");
            bean.userName = (String)rs.getObject("userName");
            list.add(bean);
        }
        return list;
    }
    
    /**Maître des utilisateurs*/
    public static class UserMst{
        //Il n'y a pas de setter getter car il s'agit d'une implémentation découpée.
        public Integer userId;
        public String userName;
    }
}

Si vous l'écrivez sans utiliser la bibliothèque, presque tout le monde écrira le code comme celui-ci. Utilisation de ResultSet # getObject au lieu de ResultSet # getInt Étant donné que la valeur de retour de getInt est un type primitif, il existe une interruption indiquant qu'elle devient 0 si la valeur de la base de données est nulle, il s'agit donc d'une prévention. Pour plus de détails, voir ci-dessous ResultSet getXxxx était accro au type primitif (Java) --Qiita

Quel type d'API dois-je utiliser?

Basé sur ce que vous avez dit dans "Le secret pour créer une bibliothèque" ensemble Réfléchissons à ce qu'il faut faire avec les deux points suivants.

Tout le monde aura probablement des réponses différentes, mais ne vous inquiétez pas des bibliothèques comme ça.

En fait, imaginez la bibliothèque!

Tout d'abord, j'ai inventé ce genre de code.

Jdbc jdbc = new Jdbc(connection);

List<UserMst> userList = jdbc.selectList("select * from UserMst", UserMst.class);

UserMst user = jdbc.selectOne("select * from UserMst where userId = ?", UserMst.class, 0);

Si vous ne transmettez que des informations SQL et de classe et des paramètres SQL à la méthode, le résultat sera renvoyé! Sur la base des informations de classe, créez un objet de cette classe, et si le nom du champ et le nom de l'élément de base de données correspondent, définissez-le dans ce champ! C'est beaucoup moins de code que le code précédent!

Vous pouvez utiliser pleinement le moteur de modèle pour créer un fichier SQL externe, ou vous pouvez décrire des variables dans des instructions SQL, L'échelle sera énorme, alors n'allons pas aussi loin cette fois.

Codez-le!

import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 *Rendre Jdbc facile à utiliser.
 */
public class Jdbc {
    private Connection conn;

    public Jdbc(Connection conn) {
        this.conn = conn;
    }

    /**
     *Définir les paramètres sur PreparedStatement.
     * @relevé param Relevé prépayé
     * @param paramètre params
     * @throws SQLException
     */
    private void setParams(PreparedStatement statement, Object... params) throws SQLException {
        int paramNo = 1;
        for( Object param : params ) {
            statement.setObject(paramNo++, param);
        }
    }


    /**
     *Convertir des données de base de données en un objet de la classe spécifiée.
     *Si vous spécifiez une classe sous le package java pour clazz, définissez un seul élément
     * @jeu de résultats param rs
     * @classe de haricots clazz param
     * @haricot de retour
     * @throws IllegalAccessException
     * @throws InstantiationException
     * @throws SQLException
     */
    private <E> E toObject(ResultSet rs, Class<E> clazz) throws InstantiationException, IllegalAccessException, SQLException {
        E bean = null;
        if( rs.next() ) {
            Field[] fields = clazz.getFields();
            bean = clazz.newInstance();
            for( Field f: fields ) {
                Object val = rs.getObject( f.getName() );
                f.set(bean, val);
            }
        }
        return bean;
    }

    /**
     *Conversion des données DB en une liste d'objets de la classe spécifiée.
     * @jeu de résultats param rs
     * @classe de haricots clazz param
     * @retourner la liste des grains
     * @throws SQLException
     * @throws IllegalAccessException
     * @throws InstantiationException
     */
    private <E> List<E> toObjectList(ResultSet rs, Class<E> clazz) throws SQLException, InstantiationException, IllegalAccessException  {
        List<E> rsList = new ArrayList<>();
        while (rs.next()) {
            Field[] fields = clazz.getFields();
            E bean = clazz.newInstance();
            for( Field f: fields ) {
                Object val = rs.getObject( f.getName() );
                f.set(bean, val);
            }
            rsList.add(bean);
        }
        return rsList;
    }

    /**
     *Gestion des erreurs SQL
     * @exception de param e
     * @instruction SQL param sql
     * @exception de retour
     */
    private SQLException sqlErr(Throwable e, CharSequence sql) {
        return new SQLException("sql error!\nerror occurred sql="+sql, e);
    }

    /**
     *Exécutez l'insertion, la mise à jour, etc..
     * @param sql
     * @param params
     * @return
     * @throws SQLException
     */
    public int update(String sql, Object...params) throws SQLException {
        try (PreparedStatement statement = conn.prepareStatement(sql.toString())){
            setParams(statement,
                    params);

            return statement.executeUpdate();
        }catch (SQLException e){
            throw sqlErr(e, sql);
        }
    }

    /**
     *Obtenez seulement 1 enregistrement ou 1 colonne.
     * @param sql
     * @param clazz
     * @param params
     * @return
     * @throws SQLException
     */
    public <E> E selectOne(String sql, Class<E> clazz, Object...params) throws SQLException {
        ResultSet rs = null;
        try (PreparedStatement statement = conn.prepareStatement(sql.toString())){
            setParams(statement,
                    params);

            rs = statement.executeQuery();

            E val = toObject(rs, clazz);
            return val;
        }catch(SQLException | InstantiationException | IllegalAccessException e) {
            throw sqlErr(e, sql);
        }finally {
            try {
                if( rs != null ) {
                    rs.close();
                }
            } catch (SQLException e) {
                throw sqlErr(e, sql);
            }
        }
    }

    /**
     *Obtenez plusieurs enregistrements.
     * @param sql
     * @param clazz
     * @param params
     * @return
     * @throws SQLException
     */
    public <E> List<E> selectList(String sql, Class<E> clazz, Object...params) throws SQLException {
        ResultSet rs = null;
        try (PreparedStatement statement = conn.prepareStatement(sql.toString())){
            setParams(statement,
                    params);

            rs = statement.executeQuery();
            List<E> rsList = toObjectList(rs, clazz);
            return rsList;
        }catch(SQLException | InstantiationException | IllegalAccessException e) {
            throw sqlErr(e, sql);
        }finally {
            try {
                if( rs != null ) {
                    rs.close();
                }
            } catch (SQLException e) {
                throw sqlErr(e, sql);
            }
        }
    }

}

Le but de ce code est Vous obtenez le tableau de java.lang.reflect.Field de Class et vous le tournez. C'est ce qu'on appelle la réflexion. Utilisé dans de nombreux FW / bibliothèques.

Recommended Posts

[Java] Créons une bibliothèque d'accès à la base de données!
[Bases de Java] Créons un triangle avec une instruction for
Faisons un robot! "Une simple démo de Java AWT Robot"
[Java] Rendez-le constant
Faire un diamant en utilisant Java
Faisons une application de calcul avec Java ~ Afficher la fenêtre de l'application
Comment créer un conteneur Java
Accéder à Teradata depuis une application Java
Comment créer un tableau Java
Comment créer un résumé de calendrier Java
Faisons une carte de Noël avec Processing!
Créons un environnement de développement Java (mise à jour)
Comment créer un robot Discord (Java)
Migrons pour rendre Java plus confortable
Modificateur d'accès [Java]
Étudions Java
Faisons une application de calculatrice avec Java ~ Créez une zone d'affichage dans la fenêtre
Créons un processus chronométré avec la minuterie de Java! !!
Je l'ai fait en Java pour toujours rendre (a == 1 && a == 2 && a == 3) vrai
Faisons un site de shopping en utilisant Stripe! (Achat)
Je voulais que (a == 1 && a == 2 && a == 3) vrai en Java
Créons un framework Web ultra-simple avec Java
[Java] Créons un Minecraft Mod 1.14.4 [Introduction]
Créer Scala Seq à partir de Java, faire de Scala Seq une liste Java
[Java] Créons un Minecraft Mod 1.16.1 [Introduction]
Faisons une fonction de recherche avec Rails (ransack)
Créons une bibliothèque d'opérations de stockage de fichiers polyvalente (?) En faisant abstraction du stockage / acquisition de fichiers avec Java
[Java] Créons un Minecraft Mod 1.14.4 [99. Mod output]
J'ai essayé d'exécuter une application d'accès à la base de données sur IKS + Db2 sur IBM Cloud (6. Préparation de l'application d'accès à la base de données (java))
[Java] Créons un Minecraft Mod 1.14.4 [0. Fichier de base]
[Java] Créons un Minecraft Mod 1.14.4 [4. Ajouter des outils]
Créez "Je ne suis pas un robot" en Java EE (Jakarta EE)
[Java] Créons un Minecraft Mod 1.14.4 [5. Ajouter une armure]
[Java] Créons un Minecraft Mod 1.14.4 [édition supplémentaire]
Faisons un pseudo modèle en utilisant active_hash ~ Prefectural data ~
[Java] Créons un Minecraft Mod 1.14.4 [6. Ajouter une recette]
Faisons un Bot LINE avec Ruby + Sinatra - Partie 2
[Java] Créons un Minecraft Mod 1.16.1 [Ajouter un élément]
[Java] Créons un Minecraft Mod 1.16.1 [Fichier de base]
[Mémo personnel] Créez une copie complète simple avec Java
[Java] Créons un Minecraft Mod 1.14.4 [1. Ajouter un élément]
Awesome Java: excellent logiciel de bibliothèque de framework Java
J'ai essayé de créer une fonction de connexion avec Java
Faisons un Bot LINE avec Ruby + Sinatra - Partie 1
[Java] Créons un Minecraft Mod 1.14.4 [2. Ajouter un bloc]
[Introduction au développement d'applications Android] Faisons un compteur
[Java] Créons un Minecraft Mod 1.16.1 [Ajouter un bloc]
Une bibliothèque qui réalise des chaînes multilignes en chaîne multiligne Java
Bibliothèque de mesures de couverture Java
Faites un blackjack avec Java
Méthode de connexion JAVA DB
Bibliothèque de mappage d'objets JAVA
[Java] Créer un filtre
java construire un triangle
[Java] Migration de bases de données (Flyway)
Faisons ressembler à des rails (vue)
Accès à la base de données avec Exposed
Accédez à API.AI depuis Java