Advertisement
Guest User

Untitled

a guest
May 11th, 2018
106
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 22.65 KB | None | 0 0
  1. import java.io.InputStreamReader;
  2. import java.sql.*;
  3. import java.util.ArrayList;
  4. import java.util.LinkedList;
  5. import java.io.BufferedReader;
  6. import java.io.FileReader;
  7. import java.util.Scanner;
  8.  
  9. public class Diagnostico {
  10.  
  11.     private final String DATAFILE = "data/disease_data.data";
  12.     private Connection connection = null;
  13.  
  14.     private void showMenu() {
  15.  
  16.         int option = -1;
  17.         do {
  18.             System.out.println("Bienvenido a sistema de diagnóstico\n");
  19.             System.out.println("Selecciona una opción:\n");
  20.             System.out.println("\t1. Creación de base de datos y carga de datos.");
  21.             System.out.println("\t2. Realizar diagnóstico.");
  22.             System.out.println("\t3. Listar síntomas de una enfermedad.");
  23.             System.out.println("\t4. Listar enfermedades y sus códigos asociados.");
  24.             System.out.println("\t5. Listar síntomas existentes en la BD y su tipo semántico.");
  25.             System.out.println("\t6. Mostrar estadísticas de la base de datos.");
  26.             System.out.println("\t7. Salir.");
  27.             try {
  28.                 option = readInt();
  29.                 switch (option) {
  30.                     case 1:
  31.                         crearBD();
  32.                         break;
  33.                     case 2:
  34.                         realizarDiagnostico();
  35.                         break;
  36.                     case 3:
  37.                         listarSintomasEnfermedad();
  38.                         break;
  39.                     case 4:
  40.                         listarEnfermedadesYCodigosAsociados();
  41.                         break;
  42.                     case 5:
  43.                         listarSintomasYTiposSemanticos();
  44.                         break;
  45.                     case 6:
  46.                         mostrarEstadisticasBD();
  47.                         break;
  48.                     case 7:
  49.                         exit();
  50.                         break;
  51.                 }
  52.             } catch (Exception e) {
  53.                 System.err.println("Opción introducida no válida!");
  54.                 e.printStackTrace();
  55.             }
  56.         } while (option != 7);
  57.         exit();
  58.     }
  59.  
  60.     private void exit() {
  61.         try {
  62.             connection.close();
  63.             System.out.println("Saliendo... ¡hasta otra!");
  64.         } catch (SQLException e) {
  65.             e.printStackTrace();
  66.         }
  67.         System.exit(0);
  68.     }
  69.  
  70.     /**
  71.      * Método para establecer conexión con la base de datos.
  72.      *
  73.      * @throws Exception Puede lanzar excepción.
  74.      */
  75.     private void conectar(String database) throws Exception {
  76.         if (connection == null) {
  77.             try {
  78.                 Class.forName("com.mysql.jdbc.Driver");
  79.                 connection = DriverManager.getConnection(
  80.                         "jdbc:mysql://localhost:3306/" + database,
  81.                         "root",
  82.                         "");
  83.             } catch (Exception e) {
  84.                 System.out.println("Error al conectarse a la base de datos: ");
  85.                 e.printStackTrace();
  86.             }
  87.         }
  88.     }
  89.  
  90.     /**
  91.      * Método para comprobar si la base de datos "diagnostico" existe.
  92.      *
  93.      * @throws Exception Puede lanzar excepción.
  94.      */
  95.     private boolean existeDB() throws Exception {
  96.         boolean ret = false;
  97.         ResultSet r = connection.getMetaData().getCatalogs();
  98.         while (r.next()) {
  99.             if (r.getString(1).equalsIgnoreCase("diagnostico")) {
  100.                 ret = true;
  101.             }
  102.         }
  103.         return ret;
  104.     }
  105.  
  106.     /**
  107.      * Método para crear la base de datos, tablas e importar datos.
  108.      *
  109.      * @throws Exception Puede lanzar alguna excepción, en cuyo caso,
  110.      *                   hace ROLLBACK y elimina las tablas y base de datos creadas.
  111.      */
  112.     private void crearBD() {
  113.  
  114.         /*
  115.          * Se conecta con JDBC a través del método conectar(). Acto seguido,
  116.          * se procede a crear la base de datos y las tablas para dejar paso
  117.          * a importación de datos posteriormente.
  118.          */
  119.         try {
  120.             conectar("");
  121.             if (!existeDB()) {
  122.                 LinkedList<String> archivo = readData();
  123.                 ArrayList<String> sentenciasSQL = new ArrayList<>();
  124.                 sentenciasSQL.add("CREATE DATABASE diagnostico;");
  125.                 sentenciasSQL.add("USE diagnostico;");
  126.                 sentenciasSQL.add("CREATE TABLE disease (" +
  127.                         "disease_id INT AUTO_INCREMENT, " +
  128.                         "name VARCHAR(255), " +
  129.                         "PRIMARY KEY (disease_id)" +
  130.                         ");");
  131.                 sentenciasSQL.add("CREATE TABLE source (" +
  132.                         "source_id INT AUTO_INCREMENT, " +
  133.                         "name VARCHAR(255) UNIQUE, " +
  134.                         "PRIMARY KEY (source_id)" +
  135.                         ");");
  136.                 sentenciasSQL.add("CREATE TABLE symptom (" +
  137.                         "cui VARCHAR(25), " +
  138.                         "name VARCHAR(255), " +
  139.                         "st VARCHAR(45), " +
  140.                         "PRIMARY KEY (cui)" +
  141.                         ");");
  142.                 sentenciasSQL.add("CREATE TABLE disease_symptom (" +
  143.                         "disease_id INT, " +
  144.                         "cui VARCHAR(25), " +
  145.                         "FOREIGN KEY (disease_id) REFERENCES disease(disease_id), " +
  146.                         "FOREIGN KEY (cui) REFERENCES symptom(cui)" +
  147.                         ");");
  148.                 sentenciasSQL.add("CREATE TABLE code (" +
  149.                         "code VARCHAR(255) UNIQUE, " +
  150.                         "source_id INT, " +
  151.                         "PRIMARY KEY (code), " +
  152.                         "FOREIGN KEY (source_id) REFERENCES source(source_id)" +
  153.                         ");");
  154.                 sentenciasSQL.add("CREATE TABLE disease_has_code (" +
  155.                         "disease_id INT, " +
  156.                         "code VARCHAR(255), " +
  157.                         "source_id INT, " +
  158.                         "FOREIGN KEY (disease_id) REFERENCES disease(disease_id), " +
  159.                         "FOREIGN KEY (code) REFERENCES code(code), " +
  160.                         "FOREIGN KEY (source_id) REFERENCES `source`(source_id)" +
  161.                         ");");
  162.  
  163.                 /*
  164.                  * Dado que las sentencias CREATE implican un COMMIT automático, comenzaremos la
  165.                  * transacción antes de las sentencias INSERT. Ahora se interpretan y segmentan los
  166.                  * datos de disease_data.data y se crean las sentencias de importación.
  167.                  */
  168.                 sentenciasSQL.add("START TRANSACTION;");
  169.                 for (String linea : archivo) {
  170.                     String[] d1 = linea.split("=");
  171.                     String[] e1 = d1[0].split(":");
  172.                     String nombreEnfermedad = e1[0];
  173.                     sentenciasSQL.add("INSERT INTO disease (name) VALUES ('" + nombreEnfermedad.replaceAll("'", "''") + "');");
  174.                     String[] datosEnfermedad = e1[1].split(";");
  175.                     for (String dato : datosEnfermedad) {
  176.                         String[] e2 = dato.split("@");
  177.                         String codigoE = e2[0];
  178.                         String sourceE = e2[1];
  179.                         sentenciasSQL.add("INSERT IGNORE INTO source (name) VALUES ('" + sourceE + "');");
  180.                         sentenciasSQL.add("INSERT IGNORE INTO code VALUES ('" + codigoE.replaceAll("'", "''") + "', " +
  181.                                 "(SELECT source_id FROM source WHERE `name`='" + sourceE + "'));");
  182.                         sentenciasSQL.add("INSERT INTO disease_has_code VALUES (" +
  183.                                 "(SELECT disease_id FROM disease WHERE `name`='" + nombreEnfermedad.replaceAll("'", "''") + "'), " +
  184.                                 "'" + codigoE.replaceAll("'", "''") + "', " +
  185.                                 "(SELECT source_id FROM code WHERE `code`='" + codigoE.replaceAll("'", "''") + "')" +
  186.                                 ");");
  187.                     }
  188.                     String[] s1 = d1[1].split(";");
  189.                     for (String dato : s1) {
  190.                         String[] datosSintoma = dato.split(":");
  191.                         String nombreSintoma = datosSintoma[0];
  192.                         String codigoSintoma = datosSintoma[1];
  193.                         String semanticaSintoma = datosSintoma[2];
  194.                         sentenciasSQL.add("INSERT IGNORE INTO symptom VALUES (" +
  195.                                 "'" + codigoSintoma.replaceAll("'", "''") + "', " +
  196.                                 "'" + nombreSintoma.replaceAll("'", "''") + "', " +
  197.                                 "'" + semanticaSintoma + "'" +
  198.                                 ");");
  199.                         sentenciasSQL.add("INSERT INTO disease_symptom VALUES (" +
  200.                                 "(SELECT disease_id FROM disease WHERE `name` = '" + nombreEnfermedad.replaceAll("'", "''") + "'), " +
  201.                                 "'" + codigoSintoma.replaceAll("'", "''") + "')" +
  202.                                 ";");
  203.                     }
  204.                 }
  205.  
  206.                 /*
  207.                  * Una vez termino el proceso de segmentar e interpretar los datos de disease_data.data, y
  208.                  * colectar todas las sentencias de importación correspondientes, se añade al final de esta
  209.                  * colección la sentencia COMMIT. Finalmente se procede a ejecutar en orden las sentencias.
  210.                  */
  211.                 sentenciasSQL.add("COMMIT;");
  212.                 for (String sentencia : sentenciasSQL) {
  213.                     PreparedStatement ps = connection.prepareStatement(sentencia);
  214.                     ps.execute();
  215.                 }
  216.                 System.out.println("¡Proceso terminado con éxito!\n");
  217.             } else {
  218.                 System.out.println("¡La base de datos diagnóstico ya existe!\n");
  219.             }
  220.             connection.setCatalog("diagnostico");
  221.         } catch (Exception e) {
  222.             e.printStackTrace();
  223.  
  224.             /*
  225.              * En caso de un error en el proceso anterior, se parará el progreso y se optará por eliminar totalmente
  226.              * la base de datos, deshaciendo así todos los cambios. Esto ocurre porque se presume que siempre que se
  227.              * ejecute el método crearDB(), no existe la base de datos.
  228.              */
  229.             try {
  230.                 PreparedStatement ps = connection.prepareStatement("DROP DATABASE IF EXISTS diagnostico;");
  231.                 ps.execute();
  232.             } catch (SQLException ex) {
  233.                 System.out.println("No pudo borrarse la base de datos.");
  234.             }
  235.         }
  236.     }
  237.  
  238.     /**
  239.      * Método para diagnosticar una enfermedad seleccionando una serie de síntomas.
  240.      *
  241.      * @throws Exception Puede lanzar alguna excepción.
  242.      */
  243.     private void realizarDiagnostico() {
  244.         /*
  245.          * Se conecta a la base de datos e imprime el código de los síntomas.
  246.          */
  247.         try {
  248.             conectar("diagnostico");
  249.             PreparedStatement ps = connection.prepareStatement("SELECT cui,name FROM symptom ORDER BY cui ");
  250.             ResultSet lista = ps.executeQuery();
  251.             while (lista.next()) {
  252.                 System.out.println(lista.getString("cui") + "  |  " + lista.getString("name"));
  253.             }
  254.  
  255.             /*
  256.              * Se limpia de espacios y se hace split de los códigos introducidos. Posteriormente,
  257.              * se consulta en la base de datos qué enfermedades tienen los síntomas introducidos,
  258.              * y se imprime.
  259.              */
  260.             System.out.println("Introduzca el código de los síntomas separados por comas:");
  261.             String conjuntoEspacios = readString().replaceAll("\\s+", "");
  262.             String[] conjunto = conjuntoEspacios.split(",");
  263.  
  264.             for (int i = 0; i < conjunto.length; i++) {
  265.                 conjunto[i] = "cui= '" + conjunto[i] + "'";
  266.             }
  267.             String query = "SELECT disease_symptom.disease_id,name FROM disease_symptom " +
  268.                     "INNER JOIN disease ON (disease_symptom.disease_id=disease.disease_id) " +
  269.                     "WHERE " + String.join(" OR ", conjunto) +
  270.                     " GROUP BY disease_id HAVING count(*)=" + Integer.toString(conjunto.length) + ";";
  271.  
  272.             ps = connection.prepareStatement(query);
  273.             ResultSet result = ps.executeQuery(query);
  274.             if (!result.next()) {
  275.                 System.out.println("No hay enfermendades asociadas.");
  276.             } else {
  277.                 result.beforeFirst();
  278.                 System.out.println("Enfermedades para los códigos solicitados: (" + conjuntoEspacios + ")");
  279.                 while (result.next())
  280.                     System.out.println("- " + result.getString("name"));
  281.             }
  282.             System.out.println();
  283.         } catch (Exception e) {
  284.             System.out.println("Ha ocurrido un error:");
  285.             e.printStackTrace();
  286.         }
  287.     }
  288.  
  289.  
  290.     /**
  291.      * Método para crear imprimir la lista de síntomas de una enfermedad y sus datos.
  292.      *
  293.      * @throws Exception Puede lanzar excepción si el proceso de consulta en
  294.      *                   SQL ha fallado o la ID de enfermedad introducida es inválida.
  295.      */
  296.     private void listarSintomasEnfermedad() {
  297.         System.out.println("Escoge una de las siguientes enfermedades introduciendo su ID:");
  298.  
  299.         /*
  300.          * Se consulta a la base de datos las enfermedades almacenadas y sus IDs correspondientes.
  301.          */
  302.         try {
  303.             conectar("diagnostico");
  304.             PreparedStatement ps = connection.prepareStatement("SELECT disease_id,name FROM disease;");
  305.             ResultSet listadoEnfermedades = ps.executeQuery();
  306.             while (listadoEnfermedades.next()) {
  307.                 System.out.println(listadoEnfermedades.getInt("disease_id") + "  |  " +
  308.                         listadoEnfermedades.getString("name"));
  309.             }
  310.  
  311.             /*
  312.              * A través de un Scanner, se pide al usuario que introduzca una
  313.              * ID. Acto seguido, se consulta y lista los síntomas de la enfermedad correspondiente.
  314.              */
  315.             Scanner sc = new Scanner(System.in);
  316.             int ID = sc.nextInt();
  317.             PreparedStatement ps2 = connection.prepareStatement(
  318.                     "SELECT cui FROM disease_symptom WHERE `disease_id`='" + ID + "';");
  319.             ResultSet codigosSintomas = ps2.executeQuery();
  320.  
  321.             while (codigosSintomas.next()) {
  322.                 PreparedStatement ps3 = connection.prepareStatement(
  323.                         "SELECT name FROM symptom WHERE `cui`='" + codigosSintomas.getString("cui") + "'");
  324.                 ResultSet sintomas = ps3.executeQuery();
  325.                 sintomas.next();
  326.                 System.out.println("* " + sintomas.getString("name"));
  327.             }
  328.             System.out.println();
  329.         } catch (Exception e) {
  330.             System.out.println("Error al ejecutar la opción 4.");
  331.             e.printStackTrace();
  332.         }
  333.     }
  334.  
  335.     /**
  336.      * Método para crear imprimir las enfermedades con sus códigos y vocabularios.
  337.      *
  338.      * @throws Exception Puede lanzar excepción si el proceso de consulta en SQL ha fallado.
  339.      */
  340.     private void listarEnfermedadesYCodigosAsociados() {
  341.         System.out.println("Las enfermedades guardadas en la base de datos y sus códigos asociados son:\n");
  342.  
  343.         /*
  344.          * Se realiza una consulta a través de la cual se diseña un ResultSet cuya primera columna posee
  345.          * el nombre de la enfermedad, segunda columna el código y tercera columna el vocabulario del código.
  346.          */
  347.         try {
  348.             PreparedStatement ps = connection.prepareStatement(
  349.                     "SELECT disease.name,disease_has_code.code,source.name FROM disease_has_code " +
  350.                             "INNER JOIN disease ON disease_has_code.disease_id=disease.disease_id " +
  351.                             "INNER JOIN source ON disease_has_code.source_id=source.source_id;");
  352.             ResultSet resultados = ps.executeQuery();
  353.             while (resultados.next()) {
  354.                 System.out.println(resultados.getString(1) +
  355.                         " | " + resultados.getString(2) +
  356.                         " - " + resultados.getString(3));
  357.             }
  358.             System.out.println();
  359.         } catch (Exception e) {
  360.             System.out.println("Ha ocurrido un error al listar las enfermedades y sus códigos.");
  361.             e.printStackTrace();
  362.         }
  363.     }
  364.  
  365.     /**
  366.      * Método para crear imprimir los síntomas y sus tipos semánticos.
  367.      *
  368.      * @throws Exception Puede lanzar excepción si el proceso de consulta en SQL ha fallado.
  369.      */
  370.     private void listarSintomasYTiposSemanticos() {
  371.         System.out.println("Los síntomas guardados en la base de datos y sus tipos semanticos son:");
  372.  
  373.         /*
  374.          * Se realiza una consulta para obtener todos los síntomas y sus tipos semánticos.
  375.          */
  376.         try {
  377.             PreparedStatement ps = connection.prepareStatement("SELECT name,st FROM symptom;");
  378.             ResultSet resultados = ps.executeQuery();
  379.             while (resultados.next()) {
  380.                 System.out.println(resultados.getString("name") +
  381.                         " - " + resultados.getString("st"));
  382.             }
  383.             System.out.println();
  384.         } catch (SQLException e) {
  385.             System.out.println("Ha ocurrido un error al listar los síntomas y sus tipos semánticos.");
  386.             e.printStackTrace();
  387.         }
  388.     }
  389.  
  390.     /**
  391.      * Método para crear imprimir estadísticas.
  392.      *
  393.      * @throws Exception Puede lanzar excepción si el proceso de consulta en SQL ha fallado.
  394.      */
  395.     private void mostrarEstadisticasBD() {
  396.  
  397.         /*
  398.          * Se diseñan las consultas específicas para cada datos solicitado en el
  399.          * enunciado. Se ejecutan, y se imprimen los datos pertinentes.
  400.          */
  401.         try {
  402.             conectar("diagnostico");
  403.             PreparedStatement a = connection.prepareStatement("SELECT COUNT(name) FROM disease;");
  404.             PreparedStatement b = connection.prepareStatement("SELECT COUNT(name) FROM symptom;");
  405.             PreparedStatement c1 = connection.prepareStatement("SELECT tabla.enfermedad FROM " +
  406.                     "(SELECT disease.name AS enfermedad, symptom.name AS sintoma FROM disease_symptom " +
  407.                     "INNER JOIN symptom ON disease_symptom.cui = symptom.cui " +
  408.                     "INNER JOIN disease ON disease_symptom.disease_id = disease.disease_id) " +
  409.                     "AS tabla GROUP BY tabla.enfermedad ORDER BY COUNT(tabla.enfermedad) ASC LIMIT 1;");
  410.             PreparedStatement c2 = connection.prepareStatement("SELECT tabla.enfermedad FROM " +
  411.                     "(SELECT disease.name AS enfermedad, symptom.name AS sintoma FROM disease_symptom " +
  412.                     "INNER JOIN symptom ON disease_symptom.cui = symptom.cui " +
  413.                     "INNER JOIN disease ON disease_symptom.disease_id = disease.disease_id) " +
  414.                     "AS tabla GROUP BY tabla.enfermedad ORDER BY COUNT(tabla.enfermedad) DESC LIMIT 1;");
  415.             PreparedStatement c3 = connection.prepareStatement("SELECT AVG(final.sintomas) FROM " +
  416.                     "(SELECT tabla.enfermedad, COUNT(tabla.sintoma) AS sintomas FROM " +
  417.                     "(SELECT disease.name AS enfermedad, symptom.name AS sintoma FROM disease_symptom " +
  418.                     "INNER JOIN symptom ON disease_symptom.cui = symptom.cui " +
  419.                     "INNER JOIN disease ON disease_symptom.disease_id = disease.disease_id) AS tabla " +
  420.                     "GROUP BY tabla.enfermedad) AS final;");
  421.             PreparedStatement d = connection.prepareStatement("SELECT st,COUNT(name) AS numero " +
  422.                     "FROM symptom GROUP BY st ORDER BY numero DESC;");
  423.             ResultSet res1 = a.executeQuery();
  424.             res1.next();
  425.             ResultSet res2 = b.executeQuery();
  426.             res2.next();
  427.             ResultSet res3 = c2.executeQuery();
  428.             res3.next();
  429.             ResultSet res4 = c1.executeQuery();
  430.             res4.next();
  431.             ResultSet res5 = c3.executeQuery();
  432.             res5.next();
  433.             ResultSet res6 = d.executeQuery();
  434.             System.out.println("- Número enfermedades: " + res1.getString(1));
  435.             System.out.println("- Número de síntomas: " + res2.getString(1));
  436.             System.out.println("- Enfermedad con más síntomas: " + res3.getString(1) +
  437.                     "\n- Enfermedad con menos síntomas: " + res4.getString(1) +
  438.                     "\n- Número medio de síntomas: " + res5.getString(1));
  439.             System.out.println("- Tipos semánticos de síntomas y cantidades: ");
  440.             while (res6.next()) {
  441.                 System.out.println(res6.getString(1) + " · " + res6.getString(2));
  442.             }
  443.             System.out.println("\n");
  444.         } catch (Exception e) {
  445.             System.out.println("Ha ocurrido un error al mostrar las estadísticas.");
  446.             e.printStackTrace();
  447.         }
  448.     }
  449.  
  450.     /**
  451.      * Método para leer números enteros de teclado.
  452.      *
  453.      * @return Devuelve el número leído.
  454.      * @throws Exception Puede lanzar excepción.
  455.      */
  456.     private int readInt() throws Exception {
  457.         try {
  458.             System.out.print("> ");
  459.             return Integer.parseInt(new BufferedReader(new InputStreamReader(System.in)).readLine());
  460.         } catch (Exception e) {
  461.             throw new Exception("No es un número.");
  462.         }
  463.     }
  464.  
  465.     /**
  466.      * Método para leer cadenas de teclado.
  467.      *
  468.      * @return Devuelve la cadena leída.
  469.      * @throws Exception Puede lanzar excepción.
  470.      */
  471.     private String readString() throws Exception {
  472.         try {
  473.             System.out.print("> ");
  474.             return new BufferedReader(new InputStreamReader(System.in)).readLine();
  475.         } catch (Exception e) {
  476.             throw new Exception("Error leyendo línea.");
  477.         }
  478.     }
  479.  
  480.     /**
  481.      * Método para leer el fichero que contiene los datos.
  482.      *
  483.      * @return Devuelve una lista de String con el contenido.
  484.      * @throws Exception Puede lanzar excepción.
  485.      */
  486.     private LinkedList<String> readData() throws Exception {
  487.         LinkedList<String> data = new LinkedList<String>();
  488.         BufferedReader bL = new BufferedReader(new FileReader(DATAFILE));
  489.         while (bL.ready()) {
  490.             data.add(bL.readLine());
  491.         }
  492.         bL.close();
  493.         return data;
  494.     }
  495.  
  496.     public static void main(String args[]) {
  497.         new Diagnostico().showMenu();
  498.     }
  499. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement