• Java中JDBC连接数据库(MySQL)


    •  JDBC连接数据库步骤。
    • 一个简单详细的查询数据的例子。
    • 封装连接数据库,释放数据库连接方法。
    • 实现查询,插入,删除,更新等十一个处理数据库信息的功能。(包括事务处理,批量更新等)
    • 把十一个功能都放在一起。
    • 安装下载的数据库驱动程序jar包,不同的数据库需要不同的驱动程序(这本该是第一步,但是由于属于安装类,所以我们放在最后)

     一.JDBC连接数据库(编辑)步骤(主要有六个步骤)。

           1.注册驱动: Class.forName("com.mysql.jdbc.Driver");显示的加载到JVM中

           2.获取连接:(1) param1:  要连接数据库的url-----》 String url="jdbc:mysql://localhost:3306/test?"+ "useUnicode=true&characterEncoding=UTF8";//防止乱码

                                param2:要连接数据库的用户名--》 String user="h4"; 

                                param3:要连接数据库的密码----》 String pass="111"; 

                                Connection conn=DriverManager.getConnection(url,user,pass);//DriverManager下的方法:getConnection(String url,String username,String password)

                           (2)接下来我们分析下url:"jdbc(这是协议以jdbc开头):mysql(这是子协议,数据库管理系统名称)://localhost(数据库来源地址):3306(目标端口)/test(要查询的表)?"

                                                       "useUnicode=true&characterEncoding=UTF8";添加这个是为了防止乱码,指定使用Unicode字符集 ,且使用UTF-8来编辑。

           3.创建一个Statement语句对象(主要三种方法): Statement stmt=conn.createStatement();//Connection接口下的方法:Statement createStatement()

                                                                                   PreparedStatement pstmt = conn.PreparedStatement() ;

                                                                      CallableStatement cstmt =  conn.prepareCall("{CALL demoSp(? , ?)}") ;

                                         下面我们来分析下他们:(1) Statement与 PreparedStatement对象的区别,后者可以动态设置查询参数

                                                      (2)设置参数的方法 PreparedStatement.setXXXX(parameterIndex,value),如果数据库参数类型是varchar 则用setString,如果参数类型是Integer 则用setInt

                                                                                                        (3)CallableStatement.setXXXX(parameterIndex,value)   //按照参数的顺序设置value

                                                                                                              CallableStatement.setXXXX(parameterName,value)  //按照参数的名字来设置value,这个名字是在定义存储过程的时候的形式参数的名字

                                                                                    (4)CallableStatement.registerOutParameter方法用于声明一个存储过程输出类型的参数,用以接收存储过程的输出值

            4.执行SQL语句: ResultSet rs=stmt.executeQuery(Sql);除了查询语句是executeQuery();其他全部是executeUpdate();

                               Statement接口下的方法:

                                                                          boolean     execute(String sql):执行SQL语句,如果返回值是结果集则为true,否则为false

                                                                           ResultSet  executeQuery(String sql):执行SQL语句,返回值为ResultSet

                                                                           int            executeUpdate(String sql):执行SQL语句,返回值为所影响的行数

            5.处理结果集:ResultSet对象的getXxxx方法,取决于数据库中表的字段的类型,例如:varchar2  对应方法是getString ,如果是 integer 对应方法是getInt/getLong

                                   While(rs.next()){

                                         rs.getInt(columnIndex);  //通过列的序号来获取字段的值

                                                rs.getString(columnName);//通过列的名字来获取字段的值

                  ResultSet接口下常见的方法:beforeFirst();将游标移动到ResultSet中第一条记录(的前面)

                                              afterLast();将游标移动到ResultSet中最后一条记录(的后面)

                                              absolute(intcolumn):将游标移动到相对于第一行的指定行,负数则为相对于最后一条记录

                                              previous():将游标上移一行

                                              next():将游标下移一行

                                                                       ResultSet.TYPE_SCROLL_SENSITIVE          结果集可以滚动

                                                                       ResultSet.CONCUR_READ_ONLY   结果集只读,不能修改

               6.关闭资源: 操作完以后要关闭jdbc来释放jdbc资源。但是顺序要和你定义对象的时候相反,就像关门一样,从里面先关,一直往外关。

                           如下示例:

                                         if(rs !=null){//1.关闭结果集
                                                 try{
                                                        rs.close();
                                                    } catch (SQLException e){
                                                         e.printStackTrace();
                                                   }
                                               }
                                       if(stmt !=null){//2.关闭声明的对象
                                                try{
                                                      stmt.close();
                                                  }catch(SQLException e){
                                                        e.printStackTrace();
                                                      }
                                               }
                                       if(conn !=null){//3.关闭连接 (记住一定要先关闭前面的1.2.然后在关闭连接)
                                               try{
                                                     conn.close();
                                               }catch(Exception e){
                                                  e.printStackTrace();
                                                 }
                                            }
           


                                 
    二.下面是一个简单的(详细的)查询数据的例子。

    复制代码
     1 package javacore1;//这是你建的一个包名。
     2 
     3 import java.sql.CallableStatement;
     4 import java.sql.Connection;
     5 import java.sql.DriverManager;
     6 import java.sql.PreparedStatement;
     7 import java.sql.ResultSet;         //左边这五个是你在写程序时要导入的包名,记住是要在java.sql下的包。
     8 import java.sql.SQLException;
     9 import java.sql.Statement;
    10 public class jdbc { //定义一个类
    11    public static void main(String[] args){ //主方法
    12       try{
    13           String driver="com.mysql.jdbc.Driver";              //1.定义驱动程序名为driver内容为com.mysql.jdbc.Driver
    14           String url="jdbc:mysql://localhost:3306/test?"      //2.定义url;jdbc是协议;mysql是子协议:表示数据库系统管理名称;localhost:3306是你数据库来源的地址和目标端口;test是我本人建的表位置所在处,你以你的为标准。
    15                   + "useUnicode=true&characterEncoding=UTF8"; //防止乱码;useUnicode=true表示使用Unicode字符集;characterEncoding=UTF8表示使用UTF-8来编辑的。
    16           String user="h4";                                   //3.定义用户名,写你想要连接到的用户。
    17           String pass="111";                                  //4.用户密码。
    18           String querySql="select * from employees";          //5.你想要查找的表名。
    19           Class.forName(driver);                              //6.注册驱动程序,用java.lang包下面的class类里面的Class.froName();方法 此处的driver就是1里面定义的driver,也可以  Class.forName("com.mysql.jdbc.Driver");
    21           Connection conn=DriverManager.getConnection(url,user,pass);//7.获取数据库连接,使用java.sql里面的DriverManager的getConnectin(String url , String username ,String password )来完成
    22                                                                              //括号里面的url,user,pass便是前面定义的2,3,4步骤内容;
    23           Statement stmt=conn.createStatement();   //8.构造一个statement对象来执行sql语句:主要有Statement,PreparedStatement,CallableStatement三种实例来实现
    24                                                    //    三种实现方法分别为:Statement stmt = con.createStatement() ;  
    25                                                      //                   PreparedStatement pstmt = conn.prepareStatement(sql) ;   
    26                                                      //                   CallableStatement cstmt =  conn.prepareCall("{CALL demoSp(? , ?)}") ;
    27           ResultSet rs=stmt.executeQuery(querySql);//9.执行sql并返还结束 ;ResultSet executeQuery(String sqlString):用于返还一个结果集(ResultSet)对象。
    28      while(rs.next()){    //10.遍历结果集 
    29           System.out.println("人员编号:"+rs.getString("employee_id")+"工资:"+rs.getString("salary")+"姓名:"+rs.getString("last_name"));//使用getString()方法获取你表里的资料名
    30            }
    31      if(rs !=null){//11.关闭记录集
    32           try{
    33               rs.close();
    34           } catch (SQLException e){
    35             e.printStackTrace();
    36            }
    37          }
    38      if(stmt !=null){//12.关闭声明的对象
    39           try{
    40               stmt.close();
    41           }catch(SQLException e){
    42            e.printStackTrace();
    43            }
    44          }
    45      if(conn !=null){//13.关闭连接 (记住一定要先关闭前面的11.12.然后在关闭连接,就像关门一样,先关里面的,最后关最外面的)
    46           try{
    47               conn.close();
    48           }catch(SQLException e){
    49             e.printStackTrace();
    50           }
    51         }
    52           }catch(Exception e){
    53            e.printStackTrace();
    54           }
    55         }
    56     }
    复制代码

     三.为了更加直观,我们把获取数据库连接和释放连接封装在方法里,以便于后面更好的操作。

    复制代码
     1 package javacore1;
     2 
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 
     6 public class jdbc{
     7     public static void main(String[] args){
     8           
     9     Connection conn= getConnection("h4", "111"); //获取数据库连接
    10 
    11     /*,,,,此处为方法名来获取连接,例如 query(conn),,,,,*/
    12     
    13         releaseConnection(conn); // 释放数据库连接
    14    }
    15      
    16     /*,,,,,,,,,,此处构建一个你想要的功能的方法,,,,,,,,,,,,*/
    17 
    18 
    19 //数据库连接
    20 public static Connection getConnection(String user, String pass) {
    21              
    22               Connection conn = null;//声明连接对象
    23               String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    24               String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    25                          + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    26        try {
    27             Class.forName(driver);// 注册(加载)驱动程序
    28             conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    29            } catch (Exception e) {
    30              e.printStackTrace();
    31           }
    32             return conn;
    33          }
    34 // 释放数据库连接
    35 public static void releaseConnection(Connection conn) {
    36          try {
    37               if (conn != null)
    38                    conn.close();
    39              } catch (Exception e) {
    40                e.printStackTrace();
    41              }
    42          }
    43      }
    复制代码

    四.实现查询、插入、删除、更新等十一个处理数据库信息的功能。

    1.查询数据

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.ResultSet;
     5 import java.sql.SQLException;
     6 import java.sql.Statement;
     7 public class Query {
     8     public static void main(String[] args) {
     9         Connection conn = getConnection("h4", "111");// 获取数据库连接
    10             query(conn);     //方法名调用数据库连接
    11         releaseConnection(conn);//释放数据库连接
    12   }
    13 //查询数据,定义的query方法
    14 public static void query(Connection conn){
    15         String Sql="select * from employees";
    16         try{
    17             Statement stmt=conn.createStatement(); //也可以使用PreparedStatement来做
    18             ResultSet rs=stmt.executeQuery(Sql);//执行sql语句并返还结束
    19                                                                        
    20        while(rs.next()){//遍历结果集 ,向下一行                              
    21             System.out.println("人员编号:"+rs.getString("employee_id")+"工资:"+rs.getString("salary"));
    22             }
    23           if(rs !=null){
    24             try{
    25                 rs.close();
    26             } catch (SQLException e){
    27             e.printStackTrace();
    28            }
    29         }
    30         if(stmt !=null){
    31             try{
    32                stmt.close();
    33             }catch(SQLException e){
    34              e.printStackTrace();
    35           }
    36         }
    37         if(conn !=null){
    38             try{
    39                 conn.close();
    40                }catch(SQLException e){
    41                 e.printStackTrace();
    42             }
    43         }
    44      }catch(Exception e){
    45        e.printStackTrace();
    46      }
    47  }
    48 //数据库连接
    49   public static Connection getConnection(String user, String pass) {
    50             Connection conn = null;//声明连接对象
    51             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    52             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    53                        + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    54      try {
    55           Class.forName(driver);// 注册(加载)驱动程序
    56           conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    57          } catch (Exception e) {
    58            e.printStackTrace();
    59         }
    60           return conn;
    61        }
    62 //释放数据库连接
    63   public static void releaseConnection(Connection conn) {
    64        try {
    65             if (conn != null)
    66                  conn.close();
    67            } catch (Exception e) {
    68              e.printStackTrace();
    69            }
    70        }
    71    }
    复制代码
    复制代码
    //查询数据,结果倒着显示,倒序
    package javacore1;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    public class Query {
        public static void main(String[] args) {
            Connection conn = getConnection("h4", "111");// 获取数据库连接
                query(conn);     //方法名调用数据库连接
            releaseConnection(conn);//释放数据库连接
      }
    //查询数据,定义的query方法
    public static void query(Connection conn){
            String Sql="select * from employees";
            try{
                Statement stmt=conn.createStatement(); //也可以使用PreparedStatement来做
                ResultSet rs=stmt.executeQuery(Sql);//执行sql语句并返还结束
                rs.afterLast();     //先跳到最后一行                                  
           while(rs.previous()){//遍历结果集 ,向上一行                              
                System.out.println("人员编号:"+rs.getString("employee_id")+"工资:"+rs.getString("salary"));
                }
              if(rs !=null){
                try{
                    rs.close();
                } catch (SQLException e){
                e.printStackTrace();
               }
            }
            if(stmt !=null){
                try{
                   stmt.close();
                }catch(SQLException e){
                 e.printStackTrace();
              }
            }
            if(conn !=null){
                try{
                    conn.close();
                   }catch(SQLException e){
                    e.printStackTrace();
                }
            }
         }catch(Exception e){
           e.printStackTrace();
         }
     }
    //数据库连接
      public static Connection getConnection(String user, String pass) {
                Connection conn = null;//声明连接对象
                String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
                String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
                           + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
         try {
              Class.forName(driver);// 注册(加载)驱动程序
              conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
             } catch (Exception e) {
               e.printStackTrace();
            }
              return conn;
           }
    //释放数据库连接
      public static void releaseConnection(Connection conn) {
           try {
                if (conn != null)
                     conn.close();
               } catch (Exception e) {
                 e.printStackTrace();
               }
           }
       }
    复制代码

     2.插入数据

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.SQLException;
     5 import java.sql.Statement;
     6 public class Insert {
     7     public static void main(String[] args) {
     8         Connection conn = getConnection("h3", "111111");    // 获取数据库连接
     9             insert(conn);    //方法名调用数据库连接
    10         releaseConnection(conn);// 释放数据库连接
    11       }
    12 //插入数据    
    13      public static void insert(Connection conn) {  
    14             try {  
    15                   String sql = "insert into employees(employee_id,last_name,salary,department_id,userid)"  
    16                         + " values ('100010', 'xiaogou', '7000','004','9')"; // 插入数据的sql语句  
    17                   Statement stmt1 =conn.createStatement();    // 创建用于执行静态sql语句的Statement对象  
    18                   int count = stmt1.executeUpdate(sql);  // 执行插入操作的sql语句,并返回插入数据的个数       
    19                System.out.println("向biao中插入了 " + count + " 条数据"); //输出插入操作的处理结果  
    20                conn.close();   //关闭数据库连接  
    21                 } catch (SQLException e) {  
    22                   e.printStackTrace(); 
    23              }  
    24         }      
    25 //数据库连接
    26     public static Connection getConnection(String user, String pass) {
    27             Connection conn = null;//声明连接对象
    28             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    29             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    30                     + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    31             try {
    32                 Class.forName(driver);// 注册(加载)驱动程序
    33                 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    34             } catch (Exception e) {
    35                 e.printStackTrace();
    36             }
    37              return conn;
    38         }
    39 //释放数据库连接
    40     public static void releaseConnection(Connection conn) {
    41             try {
    42                 if (conn != null)
    43                     conn.close();
    44             } catch (Exception e) {
    45                 e.printStackTrace();
    46             }
    47        }
    48 }
    复制代码

    3.删除数据

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.SQLException;
     5 import java.sql.Statement;
     6 public class Delete {
     7     public static void main(String[] args) {
     8         Connection conn = getConnection("h3", "111111");    // 获取数据库连接
     9              delete(conn);    //方法名调用数据库连接;
    10         releaseConnection(conn);// 释放数据库连接
    11 }
    12 //删除数据
    13     public static void delete(Connection conn){
    14         String Sql = "delete  from employees  where employee_id=100009";
    15     try {
    16          Statement stmt = conn.createStatement();// 或者用PreparedStatement方法
    17          stmt.executeUpdate(Sql);//执行sql语句
    18     if (stmt != null) {
    19     try {
    20          stmt.close();
    21          } catch (SQLException e) {
    22          e.printStackTrace();
    23          }
    24        }
    25     } catch (SQLException e) {
    26          e.printStackTrace();
    27        }
    28         
    29     }
    30 //数据库连接
    31     public static Connection getConnection(String user, String pass) {
    32         Connection conn = null;//声明连接对象
    33         String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    34         String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    35                 + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    36         try {
    37             Class.forName(driver);// 注册(加载)驱动程序
    38             conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    39         } catch (Exception e) {
    40             e.printStackTrace();
    41         }
    42         return conn;
    43     }
    44 // 释放数据库连接
    45     public static void releaseConnection(Connection conn) {
    46         try {
    47             if (conn != null)
    48                 conn.close();
    49         } catch (Exception e) {
    50             e.printStackTrace();
    51         }
    52     }
    53 }
    复制代码

    4.更新数据

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.SQLException;
     5 import java.sql.Statement;
     6 public class Update {
     7     public static void main(String[] args) {
     8          Connection conn = getConnection("h3", "111111");    // 获取数据库连接
     9              update(conn);     //方法名调用数据库连接
    10          releaseConnection(conn);// 释放数据库连接
    11      }
    12 //更新数据  
    13   public static void update(Connection conn){
    14           String Sql = "update  employees set salary=8000 where employee_id=100005";
    15     try {
    16          Statement stmt1 = conn.createStatement();//或者用PreparedStatement方法
    17          stmt1.executeUpdate(Sql);//执行sql语句
    18     if (stmt1 != null) {
    19          try {
    20             stmt1.close();
    21          } catch (SQLException e) {
    22             e.printStackTrace();
    23          }
    24      }
    25         } catch (SQLException e) {
    26            e.printStackTrace();
    27          }
    28       }
    29 //数据库连接
    30     public static Connection getConnection(String user, String pass) {
    31         Connection conn = null;//声明连接对象
    32         String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    33         String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    34                 + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    35         try {
    36             Class.forName(driver);// 注册(加载)驱动程序
    37             conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    38         } catch (Exception e) {
    39             e.printStackTrace();
    40         }
    41          return conn;
    42     }
    43 // 释放数据库连接
    44     public static void releaseConnection(Connection conn) {
    45         try {
    46             if (conn != null)
    47                 conn.close();
    48         } catch (Exception e) {
    49             e.printStackTrace();
    50         }
    51     }
    52 }
    复制代码

    5.转账(事物处理)

    JDBC处理事务通过关闭连接的自动提交实现的:

        Connection.setAutoCommit(false);
    提交事务:
        Connection.commit();
    回滚事务
        回滚部分:
           Connection.rollback(Savepoint);
       全部回滚:
          Connection.rollback();

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.Statement;
     5 public class TransCash {
     6     public static void main(String[] args) {
     7         Connection conn = getConnection("h3", "111111");// 获取数据库连接
     8             transCash(conn);   //方法名调用数据库连接
     9         releaseConnection(conn);// 释放数据库连接
    10   }
    11 //转账(数据调换)(原来数据为100和500,实现这个功能后变成500和100,其实说白了就是更新数据,改数据)
    12   public static void transCash(Connection conn){
    13         Statement stmt = null;
    14     try{
    15           conn.setAutoCommit(false);//关闭自动提交
    16             String sql = "update employees set salary=500 where employee_id=100001";
    17             stmt = conn.createStatement();
    18             stmt.executeUpdate(sql);            
    19                   sql = "update employees set salary=100 where employee_id=100002";
    20             stmt.executeUpdate(sql);//执行sql语句,上面的两个工资将会调换

    //int i=1/0;如果这样,那么将不可以完成任务,因为这是一个完整的事物,有一点失败,将全部失败 21 conn.commit();//提交事务 22 }catch(Exception e){ 23 e.printStackTrace(); 24 }finally{ 25 try{ 26 if(stmt != null){ stmt.close(); 27 }catch(Exception e){ 28 e.printStackTrace(); 29 } 30 } 31 } 32 //数据库连接 33 public static Connection getConnection(String user, String pass) { 34 Connection conn = null;//声明连接对象 35 String driver = "com.mysql.jdbc.Driver";// 驱动程序类名 36 String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL 37 + "useUnicode=true&characterEncoding=UTF8";// 防止乱码 38 try { 39 Class.forName(driver);// 注册(加载)驱动程序 40 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接 41 } catch (Exception e) { 42 e.printStackTrace(); 43 } 44 return conn; 45 } 46 //释放数据库连接 47 public static void releaseConnection(Connection conn) { 48 try { 49 if (conn != null) 50 conn.close(); 51 } catch (Exception e) { 52 e.printStackTrace(); 53 } 54 } 55 }
    复制代码

    6.查找存储过程无参数的

    复制代码
     1 package javacore1;
     2 import java.sql.CallableStatement;
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 import java.sql.SQLException;
     6 public class ExecProc {
     7     public static void main(String[] args) {
     8         Connection conn = getConnection("h3", "111111");    // 获取数据库连接
     9            execProc(conn);//方法名调用数据库连接
    10         releaseConnection(conn);// 释放数据库连接
    11     }
    12 //调用无参存储过程;
    13       public static void execProc(Connection conn){
    14                String sql = "{call raisesalary}";
    15           try {
    16               CallableStatement cstmt = conn.prepareCall(sql);
    17               cstmt.executeUpdate();
    18           } catch (SQLException e) {
    19             e.printStackTrace();
    20           }
    21        }
    22 //数据库连接
    23         public static Connection getConnection(String user, String pass) {
    24                 Connection conn = null;//声明连接对象
    25                 String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    26                 String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    27                         + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    28                 try {
    29                     Class.forName(driver);// 注册(加载)驱动程序
    30                     conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    31                 } catch (Exception e) {
    32                     e.printStackTrace();
    33                 }
    34                  return conn;
    35             }
    36 // 释放数据库连接
    37         public static void releaseConnection(Connection conn) {
    38                 try {
    39                     if (conn != null)
    40                         conn.close();
    41                 } catch (Exception e) {
    42                     e.printStackTrace();
    43                 }
    44            }
    45     }
    复制代码

    7.查找存储过程有参数的  

    复制代码
     1 package javacore1;
     2 import java.sql.CallableStatement;
     3 import java.sql.Connection;
     4 import java.sql.DriverManager;
     5 import java.sql.Types;
     6 public class GetMulti {
     7     public static void main(String[] args) {
     8          Connection conn = getConnection("h3", "111111");    // 获取数据库连接
     9             int cnt = getMulti(conn);            //查找存储过程;   
    10             System.out.println("人员编号:" + cnt); 
    11          releaseConnection(conn);// 释放数据库连接
    12     }
    13 //查找存储过程有参
    14     public static int getMulti(Connection conn) {
    15            int dept_id = 100001;
    16            int cnt = 0;
    17            String sql = "{call calc_emp_count(?,?)}";
    18         try {
    19               CallableStatement cstmt = conn.prepareCall(sql);//初始化Statement对象
    20               cstmt.setInt(1, dept_id);//CallableStatement.setxxx(参数,值)或者(数字,值),而PreparedStatement.setxxx(数字,值)只能这样
    21               cstmt.setInt(2, cnt);    //
    22               cstmt.registerOutParameter(2, Types.INTEGER);//声明输出参数
    23               cstmt.executeUpdate();//执行sql语句
    24               cnt = cstmt.getInt(2);//获取结果
    25           if (cstmt != null) {
    26                 cstmt.close();// 释放Statement对象
    27               }
    28             } catch (Exception e) {
    29               e.printStackTrace();
    30           }
    31            return cnt;
    32       }
    33 //数据库连接
    34     public static Connection getConnection(String user, String pass) {
    35             Connection conn = null;//声明连接对象
    36             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    37             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    38                     + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    39             try {
    40                 Class.forName(driver);// 注册(加载)驱动程序
    41                 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    42             } catch (Exception e) {
    43                 e.printStackTrace();
    44             }
    45              return conn;
    46         }
    47 //释放数据库连接
    48     public static void releaseConnection(Connection conn) {
    49             try {
    50                 if (conn != null)
    51                     conn.close();
    52             } catch (Exception e) {
    53                 e.printStackTrace();
    54             }
    55        }
    56 }
    复制代码

    8.普通处理

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.Date;
     4 import java.sql.DriverManager;
     5 import java.sql.PreparedStatement;
     6 import java.sql.SQLException;
     7 public class PlanInsert {
     8     public static void main(String[] args) {
     9         Connection conn = getConnection("h3", "111111");    // 获取数据库连接
    10            planInsert(conn);    //方法名调用数据库连接
    11         releaseConnection(conn);// 释放数据库连接
    12       }
    13 //普通处理
    14      public static void planInsert(Connection conn) {  
    15          try {  
    16                String sql = "insert into test_user1(userid,username,loadingtime)"  
    17                      + " values (?,?,?)"; // 插入数据的sql语句  
    18                PreparedStatement pstmt=conn.prepareStatement(sql);
    19                long startTime=System.currentTimeMillis();
    20              for(int i=0;i<1000;i++){
    21                  pstmt.setLong(1, i);
    22                  pstmt.setString(2, "user"+i);
    23                  pstmt.setDate(3, new Date(System.currentTimeMillis()));
    24                  pstmt.executeUpdate();
    25              }
    26          System.out.println("总共耗时:"+(System.currentTimeMillis() - startTime));
    27                pstmt.close();   //关闭数据库连接  
    28            } catch (SQLException e) {  
    29              e.printStackTrace(); 
    30          } 
    31      }    
    32 //数据库连接
    33     public static Connection getConnection(String user, String pass) {
    34             Connection conn = null;//声明连接对象
    35             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    36             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    37                     + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    38             try {
    39                 Class.forName(driver);// 注册(加载)驱动程序
    40                 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    41             } catch (Exception e) {
    42                 e.printStackTrace();
    43             }
    44              return conn;
    45         }
    46 //释放数据库连接
    47     public static void releaseConnection(Connection conn) {
    48             try {
    49                 if (conn != null)
    50                     conn.close();
    51             } catch (Exception e) {
    52                 e.printStackTrace();
    53             }
    54        }
    55 }
    复制代码

    9.批量处理

    获得原来JDBC事务的模式:

    boolean currentTransactionModle = con.getAutoCommit();

    设置成事务模式(关闭自动提交):
    con.setAutoCommit(false);
    Statement stm = con.createStatement();
    三个异构的sql语句:
    String sql1 = "delete from user where id = 8";
    String sql2 = "update user set name='java' where id = 7";
    String sql3 = "insert into user(name,password) values('jdbc','jdbc')";
    添加到Statement的批量处理缓冲区中:
    stm.addBatch(sql1);
    stm.addBatch(sql2);
    stm.addBatch(sql3);
    执行批量更新:
    stm.executeBatch();
    提交本次批量更新的事务:
    con.commit();
    回复原来的事务模式:
    con.setAutoCommit(currentTransactionModle);

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.Date;
     4 import java.sql.DriverManager;
     5 import java.sql.PreparedStatement;
     6 import java.sql.SQLException;
     7 public class BatchInsert {
     8     public static void main(String[] args) {
     9         Connection conn = getConnection("h3", "111111");    // 获取数据库连接
    10            batchInsert(conn);    //方法名调用数据库连接
    11         releaseConnection(conn);// 释放数据库连接
    12       }
    13 //批量插入的速度要比普通处理的速度快
    14      public static void batchInsert(Connection conn) {  
    15          try {  
    16                String sql = "insert into test_user1(userid,username,loadingtime)"  
    17                      + " values (?,?,?)"; // 插入数据的sql语句  
    18                PreparedStatement pstmt=conn.prepareStatement(sql);
    19                long startTime=System.currentTimeMillis();
    20              for(int i=0;i<1000;i++){
    21                  pstmt.setLong(1, i);
    22                  pstmt.setString(2, "user"+i);
    23                  pstmt.setDate(3, new Date(System.currentTimeMillis()));
    24                  pstmt.addBatch();//添加到批量处理
    25              }
    26              int[] result=pstmt.executeBatch();
    27           System.out.println("总共耗时:"+(System.currentTimeMillis() - startTime));
    28              pstmt.close();   //关闭数据库连接  
    29           } catch (SQLException e) {  
    30              e.printStackTrace(); 
    31          } 
    32      }    
    33 //数据库连接
    34     public static Connection getConnection(String user, String pass) {
    35             Connection conn = null;//声明连接对象
    36             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    37             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    38                     + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    39             try {
    40                 Class.forName(driver);// 注册(加载)驱动程序
    41                 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    42             } catch (Exception e) {
    43                 e.printStackTrace();
    44             }
    45              return conn;
    46         }
    47 //释放数据库连接
    48     public static void releaseConnection(Connection conn) {
    49             try {
    50                 if (conn != null)
    51                     conn.close();
    52             } catch (Exception e) {
    53                 e.printStackTrace();
    54             }
    55        }
    56 }
    复制代码

    10.分页显示

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.PreparedStatement;
     5 import java.sql.ResultSet;
     6 import java.sql.SQLException;
     7 public class Paging {
     8     public static void main(String[] args) {
     9         Connection conn = getConnection("h3", "111111");    // 获取数据库连接
    10             paging(conn,1,3);//方法名调用数据库连接,且定义显示第几行到第几行
    11         releaseConnection(conn);// 释放数据库连接
    12    }
    13 //分页查询
    14     public static void paging(Connection conn,int startIndex,int total){
    15         try{
    16             String sql="select * from employees limit ?,?";
    17             PreparedStatement pstmt=conn.prepareStatement(sql);
    18             pstmt.setInt(1, startIndex);
    19             pstmt.setInt(2, total);
    20             ResultSet rs=pstmt.executeQuery();
    21         while(rs.next()){
    22                 System.out.print("工号:"+rs.getInt(1));
    23                System.out.println("部门编号:"+rs.getInt("department_id"));
    24             }rs.close();
    25             pstmt.close();
    26           }catch(SQLException e){
    27             e.printStackTrace();
    28         }
    29     }
    30 //数据库连接
    31     public static Connection getConnection(String user, String pass) {
    32             Connection conn = null;//声明连接对象
    33             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    34             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    35                     + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    36             try {
    37                 Class.forName(driver);// 注册(加载)驱动程序
    38                 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    39             } catch (Exception e) {
    40                 e.printStackTrace();
    41             }
    42              return conn;
    43         }
    44 // 释放数据库连接
    45     public static void releaseConnection(Connection conn) {
    46             try {
    47                 if (conn != null)
    48                     conn.close();
    49             } catch (Exception e) {
    50                 e.printStackTrace();
    51             }
    52        }
    53 }
    复制代码

    11.结果集可以滚动

    复制代码
     1 package javacore1;
     2 import java.sql.Connection;
     3 import java.sql.DriverManager;
     4 import java.sql.PreparedStatement;
     5 import java.sql.ResultSet;
     6 import java.sql.SQLException;
     7 public class ScrpllResult {
     8     public static void main(String[] args) {
     9           Connection conn = getConnection("h3", "111111");    // 获取数据库连接
    10              scrpllResult(conn);//方法名调用数据库连接
    11           releaseConnection(conn);// 释放数据库连接
    12       }
    13 //结果集滚动显示
    14     public static void scrpllResult(Connection conn){
    15         try{
    16             String sql="select * from employees";                         //结果集可以滚动      //并发性,结果集只读,不可以修改
    17             PreparedStatement pstmt=conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    18             ResultSet rs=pstmt.executeQuery();
    19         while(rs.next()){  //向下一行遍历
    20                 System.out.print("工号:"+rs.getLong(1));
    21                 System.out.println("名字"+rs.getString("last_name"));
    22            }while(rs.previous()){//向上一行遍历
    23                 System.out.print("工号:"+rs.getLong(1));
    24                 System.out.println("工资"+rs.getInt("salary"));
    25              }
    26                rs.absolute(6);//表示直接跳到第几行
    27             if(rs.next()){
    28                 System.out.print("工号:"+rs.getLong(1));
    29                 System.out.println("..........部门编号:"+rs.getString("department_id"));
    30               }
    31                 rs.close();
    32                 pstmt.close();
    33             }catch(SQLException e){
    34                 e.printStackTrace();
    35             }
    36         }    
    37 //数据库连接
    38     public static Connection getConnection(String user, String pass) {
    39             Connection conn = null;//声明连接对象
    40             String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    41             String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    42                     + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    43             try {
    44                 Class.forName(driver);// 注册(加载)驱动程序
    45                 conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    46             } catch (Exception e) {
    47                 e.printStackTrace();
    48             }
    49              return conn;
    50         }
    51 // 释放数据库连接
    52     public static void releaseConnection(Connection conn) {
    53             try {
    54                 if (conn != null)
    55                     conn.close();
    56             } catch (Exception e) {
    57                 e.printStackTrace();
    58             }
    59        }
    60 }
    复制代码

    五.把上面十一个放在一起当然最方便省事。(需要用谁,只需把前面的注释打开便行)

    复制代码
      1 package javacore1;
      2 import java.sql.CallableStatement;
      3 import java.sql.Connection;
      4 import java.sql.Date;
      5 import java.sql.DriverManager;
      6 import java.sql.PreparedStatement;
      7 import java.sql.ResultSet;
      8 import java.sql.SQLException;
      9 import java.sql.Statement;
     10 import java.sql.Types;
     11 public class jdbcMySql {
     12 public static void main(String[] args) {
     13     Connection conn = getConnection("h3", "111111");    // 获取数据库连接
     14            //query(conn); //1.查询数据
     15            //insert(conn);//2.插入数据
     16            //delete(conn);//3.删除数据
     17            //update(conn);//4.更新数据
     18            //transCash(conn);//5.转账
     19            //execProc(conn);//6.查找存储过程无参数的
     20            //int cnt = getMulti(conn);//7.查找存储过程有参数的   
     21            //System.out.println("人员编号:" + cnt);//查找存储过程有参数的
     22            //planInsert(conn);//8.普通处理
     23            //batchInsert(conn);//9.批量处理
     24            // paging(conn,1,3);//10.分页显示
     25            //scrpllResult(conn);//11.结果集可以滚动
     26         releaseConnection(conn);// 释放数据库连接
     27      }
     28 //1.查询数据,定义的query方法
     29 public static void query(Connection conn){
     30         String Sql="select * from employees";
     31         try{
     32             Statement stmt=conn.createStatement(); //也可以使用PreparedStatement来做
     33           ResultSet rs=stmt.executeQuery(Sql);//执行sql语句并返还结束
     34                                                    
     35      while(rs.next()){//遍历结果集                               
     36             System.out.println("人员编号:"+rs.getString("employee_id")+"工资:"+rs.getString("salary"));
     37             }
     38           if(rs !=null){
     39             try{
     40                 rs.close();
     41             } catch (SQLException e){
     42             e.printStackTrace();
     43            }
     44         }
     45         if(stmt !=null){
     46             try{
     47                stmt.close();
     48             }catch(SQLException e){
     49              e.printStackTrace();
     50           }
     51         }
     52         if(conn !=null){
     53             try{
     54                 conn.close();
     55                }catch(SQLException e){
     56                 e.printStackTrace();
     57             }
     58         }
     59      }catch(Exception e){
     60        e.printStackTrace();
     61      }
     62 }
     63 //2.插入数据    
     64      public static void insert(Connection conn) {  
     65             try {  
     66                   String sql = "insert into employees(employee_id,last_name,salary,department_id,userid)"  
     67                         + " values ('100010', 'xiaogou', '7000','004','9')"; // 插入数据的sql语句  
     68                   Statement stmt1 =conn.createStatement();    // 创建用于执行静态sql语句的Statement对象  
     69                   int count = stmt1.executeUpdate(sql);  // 执行插入操作的sql语句,并返回插入数据的个数       
     70                System.out.println("向biao中插入了 " + count + " 条数据"); //输出插入操作的处理结果  
     71                conn.close();   //关闭数据库连接  
     72                 } catch (SQLException e) {  
     73                   e.printStackTrace(); 
     74              }  
     75         }
     76 //3.删除数据
     77     public static void delete(Connection conn){
     78             String Sql = "delete  from employees  where employee_id=100009";
     79         try {
     80              Statement stmt = conn.createStatement();// 或者用PreparedStatement方法
     81              stmt.executeUpdate(Sql);//执行sql语句
     82         if (stmt != null) {
     83         try {
     84              stmt.close();
     85              } catch (SQLException e) {
     86              e.printStackTrace();
     87              }
     88            }
     89         } catch (SQLException e) {
     90              e.printStackTrace();
     91            }
     92             
     93         }
     94 //4.更新数据  
     95     public static void update(Connection conn){
     96               String Sql = "update  employees set salary=8000 where employee_id=100005";
     97         try {
     98              Statement stmt1 = conn.createStatement();//或者用PreparedStatement方法
     99              stmt1.executeUpdate(Sql);//执行sql语句
    100         if (stmt1 != null) {
    101              try {
    102                 stmt1.close();
    103              } catch (SQLException e) {
    104                 e.printStackTrace();
    105              }
    106          }
    107             } catch (SQLException e) {
    108                e.printStackTrace();
    109              }
    110           }    
    111 //5.转账(数据调换)(原来数据为100和500,实现这个功能后变成500和100,其实说白了就是更新数据,改数据)
    112   public static void transCash(Connection conn){
    113             Statement stmt = null;
    114         try{
    115               conn.setAutoCommit(false);//关闭自动提交
    116                 String sql = "update employees set salary=500 where employee_id=100001";
    117                 stmt = conn.createStatement();
    118                 stmt.executeUpdate(sql);            
    119                       sql = "update employees set salary=100 where employee_id=100002";
    120                 stmt.executeUpdate(sql);//执行sql语句,上面的两个工资将会调换
    121               conn.commit();//提交事务
    122            }catch(Exception e){
    123              e.printStackTrace();
    124            }finally{
    125         try{
    126              if(stmt != null)stmt.close();
    127                 }catch(Exception e){
    128                   e.printStackTrace();
    129                 }
    130               }
    131             }
    132 //6.调用无参存储过程;
    133   public static void execProc(Connection conn){
    134            String sql = "{call raisesalary}";
    135       try {
    136           CallableStatement cstmt = conn.prepareCall(sql);
    137           cstmt.executeUpdate();
    138       } catch (SQLException e) {
    139         e.printStackTrace();
    140       }
    141    } 
    142 //7.查找存储过程有参
    143   public static int getMulti(Connection conn) {
    144            int dept_id = 100001;
    145            int cnt = 0;
    146            String sql = "{call calc_emp_count(?,?)}";
    147         try {
    148               CallableStatement cstmt = conn.prepareCall(sql);//初始化Statement对象
    149               cstmt.setInt(1, dept_id);//CallableStatement.setxxx(参数,值)或者(数字,值),而PreparedStatement.setxxx(数字,值)只能这样
    150               cstmt.setInt(2, cnt);    //
    151               cstmt.registerOutParameter(2, Types.INTEGER);//声明输出参数
    152               cstmt.executeUpdate();//执行sql语句
    153               cnt = cstmt.getInt(2);//获取结果
    154           if (cstmt != null) {
    155                 cstmt.close();// 释放Statement对象
    156               }
    157             } catch (Exception e) {
    158               e.printStackTrace();
    159           }
    160            return cnt;
    161       }
    162 //8.普通处理
    163      public static void planInsert(Connection conn) {  
    164          try {  
    165                String sql = "insert into test_user1(userid,username,loadingtime)"  
    166                      + " values (?,?,?)"; // 插入数据的sql语句  
    167                PreparedStatement pstmt=conn.prepareStatement(sql);
    168                long startTime=System.currentTimeMillis();
    169              for(int i=0;i<1000;i++){
    170                  pstmt.setLong(1, i);
    171                  pstmt.setString(2, "user"+i);
    172                  pstmt.setDate(3, new Date(System.currentTimeMillis()));
    173                  pstmt.executeUpdate();
    174              }
    175          System.out.println("总共耗时:"+(System.currentTimeMillis() - startTime));
    176                pstmt.close();   //关闭数据库连接  
    177            } catch (SQLException e) {  
    178              e.printStackTrace(); 
    179          } 
    180      } 
    181 //9.批量插入的速度要比普通处理的速度快
    182     public static void batchInsert(Connection conn) {  
    183              try {  
    184                    String sql = "insert into test_user1(userid,username,loadingtime)"  
    185                          + " values (?,?,?)"; // 插入数据的sql语句  
    186                    PreparedStatement pstmt=conn.prepareStatement(sql);
    187                    long startTime=System.currentTimeMillis();
    188                  for(int i=0;i<1000;i++){
    189                      pstmt.setLong(1, i);
    190                      pstmt.setString(2, "user"+i);
    191                      pstmt.setDate(3, new Date(System.currentTimeMillis()));
    192                      pstmt.addBatch();//添加到批量处理
    193                  }
    194                  int[] result=pstmt.executeBatch();
    195               System.out.println("总共耗时:"+(System.currentTimeMillis() - startTime));
    196                  pstmt.close();   //关闭数据库连接  
    197               } catch (SQLException e) {  
    198                  e.printStackTrace(); 
    199              } 
    200          }
    201 //10.分页查询
    202    public static void paging(Connection conn,int startIndex,int total){
    203             try{
    204                 String sql="select * from employees limit ?,?";
    205                 PreparedStatement pstmt=conn.prepareStatement(sql);
    206                 pstmt.setInt(1, startIndex);
    207                 pstmt.setInt(2, total);
    208                 ResultSet rs=pstmt.executeQuery();
    209             while(rs.next()){
    210                     System.out.print("工号:"+rs.getInt(1));
    211                    System.out.println("部门编号:"+rs.getInt("department_id"));
    212                 }rs.close();
    213                 pstmt.close();
    214               }catch(SQLException e){
    215                 e.printStackTrace();
    216             }
    217         }
    218 //11.结果集滚动显示
    219      public static void scrpllResult(Connection conn){
    220          try{
    221              String sql="select * from employees";                         //结果集可以滚动                                               //并发性,结果集只读,不可以修改
    222              PreparedStatement pstmt=conn.prepareStatement(sql, ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_READ_ONLY);
    223              ResultSet rs=pstmt.executeQuery();
    224          while(rs.next()){  //向下一行遍历
    225                  System.out.print("工号:"+rs.getLong(1));
    226                  System.out.println("名字"+rs.getString("last_name"));
    227             }while(rs.previous()){//向上一行遍历
    228                  System.out.print("工号:"+rs.getLong(1));
    229                  System.out.println("工资"+rs.getInt("salary"));
    230               }
    231                 rs.absolute(6);//表示直接跳到第几行
    232              if(rs.next()){
    233                  System.out.print("工号:"+rs.getLong(1));
    234                  System.out.println("..........部门编号:"+rs.getString("department_id"));
    235                }
    236                  rs.close();
    237                  pstmt.close();
    238              }catch(SQLException e){
    239                  e.printStackTrace();
    240              }
    241          } 
    242 //数据库连接
    243 public static Connection getConnection(String user, String pass) {
    244           Connection conn = null;//声明连接对象
    245           String driver = "com.mysql.jdbc.Driver";// 驱动程序类名
    246           String url = "jdbc:mysql://localhost:3306/test?" // 数据库URL
    247                      + "useUnicode=true&characterEncoding=UTF8";// 防止乱码
    248    try {
    249         Class.forName(driver);// 注册(加载)驱动程序
    250         conn = DriverManager.getConnection(url, user, pass);// 获取数据库连接
    251        } catch (Exception e) {
    252          e.printStackTrace();
    253       }
    254         return conn;
    255      }
    256 //释放数据库连接
    257 public static void releaseConnection(Connection conn) {
    258      try {
    259           if (conn != null)
    260                conn.close();
    261          } catch (Exception e) {
    262            e.printStackTrace();
    263          }
    264      }
    265  }
    复制代码

     六.安装下载的数据库驱动程序jar包,不同的数据库需要不同的驱动程序(但是安装方法都是一样的)

    在使用JDBC编程时需要连接数据库,导入JAR包是必须的,导入其它的jar包方法同样如此,导入的方法是 

    打开eclipse
    1.右击要导入jar包的项目,点properties 

    2.左边选择java build path,右边选择libraries 

    3.选择add External jars 

    4.选择jar包的按照路径下的
    确定后就行了。

    Java连接MySQL的最新驱动包下载地址 

    http://www.mysql.com/downloads/connector/j

    1.鼠标放在你建的根目录上面。右击,然后选择最下面的properties。

    2.然后左边选择java build path,右边选择libraries ,在选择右边的add External jars ,选择jar包的路径,点击确定就可以了

    3.装好后,图如下出现你要添加的包。

    转自:http://www.cnblogs.com/wuziyue/p/4827295.html

  • 相关阅读:
    Max Sum Plus Plus HDU
    Monkey and Banana HDU
    Ignatius and the Princess IV HDU
    Extended Traffic LightOJ
    Tram POJ
    Common Subsequence HDU
    最大连续子序列 HDU
    Max Sum HDU
    畅通工程再续
    River Hopscotch POJ
  • 原文地址:https://www.cnblogs.com/marveler/p/5621949.html
Copyright © 2020-2023  润新知