美文网首页
JDBC进阶4——对数据库和数据库表进行动态增删改查

JDBC进阶4——对数据库和数据库表进行动态增删改查

作者: 从0到1的小姐姐 | 来源:发表于2018-05-17 08:42 被阅读0次

不知道各位是否观察到,截止到现在的增删改查都建立在,在MYSQL数据库中建立好相应的数据库和数据表,写入相应的字段之后才开始使用JAVA对数据库的进行操作!我google了一下,没有发现在java中对数据库进行增删改查操作的,经由教程:https://www.yiibai.com/jdbc/jdbc_quick_guide.html
启发,对数据库的操作分开了,但是重复代码很多,能不能像进阶2中一样结合在一起呢?

image.png
我自己动手调,写出了简单的框架,但是从外部传参到操作数据库之间自己也没有调出来,一个大佬耐心的帮我调了半天,终于把代码跑通,在此感谢大佬耐心的援助!
功能:在Java中实现,下述功能
image.png
其中3 创建表中嵌套了进阶2中对表的操作
image.png
插入后
image.png
查询
eclipse中
image.png
MYSQL中
image.png
可以看到对应的MYSQL中使用java对数据库和数据表的操作都已经更新在数据库中

完整代码:
文件调用关系为:
Syn.java调用TestConnection.java和Test.java
Test.java调用Handle.java
Handle.java调用TestConnection.java
主文件


//此代码在JAVA中,连接数据库,对数据库进行操作,嵌套对表的操作
package database_20;

import java.sql.*;
import java.util.Scanner;

                                                                                    //步骤1:导入需要的包,java.sql是JDBC 4.0的主要包。它提供了与数据源进行交互的主要类。
public class Syn {
    
    static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";                      //JDBC驱动名
    static final String DB_URL = "jdbc:mysql://localhost/test?useSSL=false";        //数据库URL,test是在SQL中创建好的数据库,后面一句SSL要加上
    static final String USER = "root";                                              //用户
    static final String PASS ="12345678";                                           //密码
    static String ch;
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Connection conn =null;                                                      //Connection 接口用于联系数据库
        Statement stmt = null;                                                      //Statement:使用从此接口创建的对象将SQL语句提交到数据库。
        
        int flag = 0;   
        try{
            Class.forName(JDBC_DRIVER);                                             //步骤2 :注册JDBC驱动
            System.out.println("Connecting to database...");                        //步骤3:打开一个连接
            conn = DriverManager.getConnection(DB_URL, USER, PASS);                     //DriverManager:此类管理数据库驱动程序列表。 使用通信子协议将来自java应用程序的连接请求与适当的数据库驱动程序进行匹配。在JDBC下识别某个子协议的第一个驱动程序将用于建立数据库连接。
        
            System.out.println("Creating statement...");                            //步骤4:执行一个查询
            stmt = conn.createStatement();
            System.out.println("欢迎光临!");
            do{     
                System.out.println("请输入您要进行的操作:0 显示数据库 1.建立数据库  2 选择数据库   3 创建表   4 删除表  5 删除数据库   6  关闭数据库:");
                Scanner sc = new Scanner(System.in);
                String str = sc.next(); 
                int f=Integer.parseInt(str);                                        //类型str转为int
            switch (f){
            case 0:
                Statement stmte = conn.createStatement();
                ResultSet resultSet = stmte.executeQuery("select * from information_schema.schemata");      //查询数据库名
                while(resultSet.next()){
                System.out.println(resultSet.getString(2));                                                 //循环输出也可以写成getString("schema_name")
                
                }   
                break;
            case 1:
                System.out.println("请输入建立的数据库名称:");
                String na = sc.next();                                              //!!!只建立一个scanner也可以持续监听,注意next()  nextline()的区别!!!
                String sql ="CREATE DATABASE "+na;                                  //获取外部输入的数据库na,是个变量
                System.out.println(sql);
                stmt.executeUpdate(sql);
                System.out.println("数据库建立完成");
                flag = f;
                break;
            case 2:
                System.out.println("请输入选择的数据库名称:");
                ch = sc.next();                                         //ch是外部输入选择使用的数据库名
                String sql2 ="USE "+ch;                                 
                System.out.println(sql2);
                stmt.executeUpdate(sql2);
                System.out.println("数据库选择完成");
                flag = f;
                break;
            
            case 3:
                System.out.println("请输入需要建立的表的名字:");
                String ta = sc.next();                                  //ta是外部输入得到的在ch库下面的表名
                 String sql3 = "CREATE TABLE "+ta+                      //这里表名动态化了,但是字段类型还是在此固定了,以后是否可以进一步改进呢???
                           "(id INTEGER not NULL, " +
                           " name VARCHAR(255), " + 
                           " salary INTEGER, " + 
                           " dpId INTEGER, " + 
                           " email VARCHAR(255), " + 
                           " PRIMARY KEY ( id ))"; 
              stmt.executeUpdate(sql3);
              System.out.println("需要对表进行进一步操作么?1:是   2:否");
              int j = sc.nextInt();
                if(j==1){
                    TestConnection tc=new TestConnection(ch);                       //*****调用TestConnection并且将ch传递给数据库连接这个函数
                    Test.test(sc,tc,ta);                                            //*****调用Test,并且将参数传递给test
                }else
                    flag = f;
                    break;
            case 4:
                System.out.println("请输入需要删除的表名称:");
                String deta = sc.next();
                String sql4 ="DROP TABLE "+deta;                                    
                System.out.println(sql4);
                stmt.executeUpdate(sql4);
                System.out.println("表删除完成");
                flag = f;
                break;
            case 5:
                System.out.println("请输入需要删除的数据库名称:");
                String de = sc.next();
                String sql5 ="DROP DATABASE "+de;                                   
                System.out.println(sql5);
                stmt.executeUpdate(sql5);
                System.out.println("数据库删除完成");
                flag = f;
                break;
            case 6:
                 System.out.println("程序退出!");
                 System.exit(0);
                 break;
            }
            }while(flag!=6);
                                                                                            //步骤6:清理环境
            stmt.close();
            conn.close();
        }catch(SQLException se){                                                        //SQLException:此类处理数据库应用程序中发生的任何错误。
            se.printStackTrace();
        }catch(Exception e){                                                        
            e.printStackTrace();
        }                                                               
        System.out.println("Goodbye");
    }
}//end main                                                     

Test.java

//此程序将被Syn调用,然后它调用handle
package database_20;

import java.util.Scanner;
/**
 * 测试类
 * @author Administrator
 *
 */
public class Test {
    private static Scanner sc;

    public static void test(Scanner sc,TestConnection tc,String ta) {
        int index = 0;
        System.out.println("表操作:");
    //输出选项
      do{
      System.out.println("1:查询    2:更新     3:插入   4:删除   5:退出");
      System.out.println("你想干什么?   请选择:");
      sc = new Scanner(System.in);
      //实例化数据操作类Handle
      Handle hd = new Handle(sc, tc,ta);                //注意,这里在传递参数
 
      int type = sc.nextInt();
      /**
       * 判断用户选择操作的项
       */
      switch(type){
      case 1:
          //调用Handle查询方法
          hd.query();
      System.out.println("查询完成!");
          index = type;
          break;
      case 2:
          //更新
          hd.update();
          System.out.println("更新完成!");
          index = type;
          break;
      case 3:
          //插入
          hd.insert();
          System.out.println("插入完成!");
          index = type;
          break;
      case 4:
          //删除
          hd.delete();
          System.out.println("删除完成!");
          index = type;
          break;
      case 5:
          //退出
          System.out.println("程序退出!");
          System.exit(0);
          break;
      }
 
    }while(index != 5);
    }
}

Handle.java

//test调用handle,handle调用testconnection

package database_20;

import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
/**
 * 数据库操作类
 * @author Administrator
 *
 */
public class Handle {
   public String ta;
    public Scanner sc;
    public TestConnection tc;
    
    public Handle(Scanner sc,TestConnection tc,String ta) {
         this.sc=sc;
         this.tc=tc;
         this.ta=ta;
        // TODO Auto-generated constructor stub
    }
    /**
     * 查询方法
     */
    public void query() {
        System.out.println("1:查询全部");
        System.out.println("2:根据ID查询");
        System.out.print("选择你要执行选项:");
        // Scanner sc2 = new Scanner(System.in);
        int type2 = sc.nextInt();
        switch (type2) {
 
        case 1:
            String Sql1 = "select ID,Name,Salary,dpId,email from "+ta+" where 1=?";         //表名在这里,这里顺序要和数据库表一致
            Object[] array1 = { 1 };
            List list = tc.getData(Sql1, array1);
            /**
             * 取键值 并打印 即为输出的列名 排列
             */
            Map map2 = (Map) list.get(0);
            // 存键值
            Set set2 = map2.keySet();
            Iterator it2 = set2.iterator();
            while (it2.hasNext()) {
                System.out.print("\t" + it2.next());
            }
 
            System.out.println();
            //循环取出 每个行的数据
 
            for (Object object : list) {
                // list里面是map对象
                Map map = (Map) object;
                // 存键值
                Set set = map.keySet();
                Iterator it = set.iterator();
 
                while (it.hasNext()) {
                    // 取键值
 
                    Object key = it.next();
 
                    // 输出 map里的数据
 
                    System.out.print("\t " + map.get(key));
 
                }
                System.out.println();
            }
 
            break;
        case 2:
            /**
             * 根据用户输入的员工id进行查询
             */
            System.out.println("输入ID:");
            Object object = sc.nextInt();
            Object[] array = { object };
            String Sql2 = "select id,name,salary,dpId,email from "+ta+" where ID =? ";          //表名
 
            List list2 = tc.getData(Sql2, array);
           //输出列名
            Map map3 = (Map) list2.get(0);
            // 存键值
            Set set3 = map3.keySet();
            Iterator it3 = set3.iterator();
 
            while (it3.hasNext()) {
                System.out.print("\t" + it3.next());
            }
 
            System.out.println();
            //循环输出数据
            for (Object object2 : list2) {
                // list里面是map对象
                Map map4 = (Map) object2;
                // 存键值
                Set set4 = map4.keySet();
                Iterator it4 = set4.iterator();
 
                while (it4.hasNext()) {
                    // 取键值
 
                    Object key = it4.next();
 
                    // 输出 map里的数据
 
                    System.out.print("\t " + map4.get(key));
                    // System.out.print("\\t"+ map.get(key));
 
                }
                System.out.println();
            }
 
            break;
        }
    }
 
    /**
     * 更新方法
     */
    public void update(){
        System.out.print("请输入ID:");
        Object id = sc.next();
        System.out.print("请输入想更新的薪水值:");
        Object salary = sc.next();
        //根据用户输入的员工号来修改薪水值并判断是否执行成功
        String sql = "update" +ta+ "set Salary = ? where  ID = ? " ;                //表名
        Object [] array =  { salary, id  };
        //使用TestConnection的update方法
        int line =  tc.update(sql, array);
        if(line>0){
            System.out.println("信息更新成功!");
        }
 
    }
    /**
     * 插入方法
     */
    public void insert(){
        System.out.print("请输入ID:");
        int id = sc.nextInt();
        System.out.print("请输入Name:");
        String name = sc.next();
        System.out.print("请输入email:");
        String email = sc.next();
        System.out.print("请输入Salary:");
        int salary = sc.nextInt();
        System.out.print("请输入dapartmentId:");
        int dpId = sc.nextInt();
        Object[] array = {id,name,salary,dpId,email};
        //插入用户输入的数据 并判断是否执行成功
        String sql = "insert into "+ta+" values(?,?,?,?,?)";                        //表名
        int line = tc.update(sql, array);
        if(line>0){
            System.out.println("插入成功!");
        }
    }
 
    /**
     * 删除方法
     */
    public void delete(){
        System.out.print("请输入想删除的员工号:");
        Object id = sc.next();
        Object [] array = {id};
        //删除用户输入 的员工号的数据并判断是否执行成功
        String sql = "delete from "+ta+" where ID = ? ";                            //表名
        int line =  tc.update(sql, array);
            if(line>0){
                System.out.println("删除成功!");
            }
    }
 
}

TestConnection.java

package database_20;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
 
public class TestConnection {
 
    /**
     * 定义链接需要的字符串
     */
    private String ch;
    private static final String str1 = "com.mysql.jdbc.Driver";
    private static final String user = "root";
    private static final String password = "12345678";
    Connection conn;
    PreparedStatement st;
    ResultSet rs;
 
    /**
     * 加载驱动类
     */
    static {
 
        try {
            Class.forName(str1);
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 
    public TestConnection(String ch) {
        this.ch=ch;
        // TODO Auto-generated constructor stub
    }

    /**
     * 建立链接的方法
     *
     * @return
     */
    private Connection getConnection() {
 
        try {
            String url = "jdbc:mysql://localhost/"+ch+"?useSSL=false";                  //这里是数据库名
            conn = DriverManager.getConnection(url, user, password);
 
        } catch (Exception e) {
            // TODO: handle exception
        }
        return conn;
 
    }
 
    /**
     * 使用prepareStatement来预编译查询语句 然后传参数的值来作为条件查询数据库 返回list
     *
     * @param id
     * @return
     */
    public List getData(String sql, Object[] array) {
        // SQL语句
        List list = new ArrayList();
        conn = this.getConnection();
        try {
            // 预编译
            st = conn.prepareStatement(sql);
            // 利用方法传入参数
            for (int i = 0; i < array.length; i++) {
                st.setObject(i + 1, array[i]);
            }
            // 执行查询
            rs = st.executeQuery();
            while (rs.next()) {
                Map map = new HashMap();
 
                ResultSetMetaData rsmd = rs.getMetaData();
                // 以列名为键 存储每一行数据进map
                for (int i = 1; i <= rsmd.getColumnCount(); i++) {
 
                    map.put(rsmd.getColumnName(i), rs.getObject(i));
 
                }
                // 将每一个map加入list 这样list的到就是每一行
                list.add(map);
 
            }
 
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
            // 关闭连接
            this.close();
        }
        return list;
 
    }
 
    /**
     * 更新数据的方法
     *
     * @param sql
     * @param array
     * @return
     */
    public int update(String sql, Object[] array) {
        conn = this.getConnection();
        int line = 0;
        try {
 
            st = conn.prepareStatement(sql);
            // 传参数
            for (int i = 0; i < array.length; i++) {
                st.setObject(i + 1, array[i]);
            }
 
            line = st.executeUpdate();
            // 判断是否修改成功
            if (line > 0) {
                return line;
 
            } else {
 
                System.out.println("更新失败");
            }
 
        } catch (SQLException e) {
 
            e.printStackTrace();
        } finally {
            // 关闭连接
            this.close();
        }
        return 0;
    }
 
    /**
     * 关闭连接
     */
    private void close() {
 
        try {
            if (rs != null) {
                rs.close();
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally {
 
            try {
                if (st != null) {
                    st.close();
                }
            } catch (SQLException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
 
                try {
                    if (conn != null) {
                        conn.close();
                    }
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        }
    }
}

上述代码调通之后还是能完成比较完整的数据库和数据库标的操作,但是还有几点需要优化
1.大佬说我程序写的太乱,这个,我可能写的太少,还不知道怎样写出清晰明了的代码,确实有点冗余
2.主文件中那个字段是自己定的,就像之前MYSQL里面要预先写好数据库和表一样,这个需要改进
3.不知道大佬们看到这里有没有发现没有显示表的操作,导致每次都要重新新建一个表,这个也需要改进

相关文章

网友评论

      本文标题:JDBC进阶4——对数据库和数据库表进行动态增删改查

      本文链接:https://www.haomeiwen.com/subject/cejmdftx.html