2011-01-23 68 views
0

我已經使用Java的JDBC編寫了最簡單的DBMS實現。在我的應用程序中,我可以讓用戶在一些簡單的mysql數據庫上執行CRUD操作。一切都在控制檯完成。問題在於,當用戶從菜單中選擇操作(當前硬編碼的查詢),然後提供查詢時,拋出異常(java.util.InputMismatchException)。任何想法,爲什麼這可能會發生?下面的代碼:JDBC查詢+ Scanner.next()給出InputMismatchException

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

public class Main { 

    public static void main(String[] args) { 
     Base base = new Base(); 
     boolean result = false; 

     try{ 
      base.connect(); 
     }catch(SQLException se){ 
      se.printStackTrace(); 
     }catch(Exception e){ 
      e.printStackTrace(); 
     } 

     Scanner sc = new Scanner(System.in); 
     int menuChoice = -1; 
     String query = ""; 

     while(menuChoice != 0){ 
      showMenu(); 
      menuChoice = sc.nextInt(); 
      System.out.println("Please provide your query : "); 

      switch(menuChoice){ 
       case 1: 
         query = sc.next(); 
         result = base.insert(query); 
         break; 
       case 2: 
         query = sc.next(); 
         result = base.update(query); 
         break; 
       case 3: 
         query = sc.next(); 
         result = base.retrieve(query); 
         break; 
       case 4: 
         query = sc.next(); 
         result = base.delete(query); 
         break; 
       case 0: 
        System.out.println("Bye bye"); 
        base.connection = null; 
        System.exit(0); 
      } 
     } 
    } 

    public static void showMenu(){ 
     System.out.println("Welcome to simple JDBC example application./n"); 
     System.out.println("Choose desired operation:\n\n"); 
     System.out.println("1. Insert new instance"); 
     System.out.println("2. Update existing instance"); 
     System.out.println("3. Lookup"); 
     System.out.println("4. Delete instance"); 
     System.out.println("0. Exit"); 
     System.out.print("\n\n Select: "); 
    } 
} 

class Base { 
    private String username = ""; 
    private String password = ""; 
    private String dbname = ""; 
    private String servername = ""; 
    private Statement stmt = null; 
    Connection connection = null; 

    public Base(){ 
    } 

    public boolean create(){ 
     return true; 
    } 

    public void connect() throws Exception{ 
     String driverName = "com.mysql.jdbc.Driver"; 
     Class.forName(driverName); 
     String url = "jdbc:mysql://" + servername + "/" + dbname; 
     connection = DriverManager.getConnection(url, username, password); 
     stmt = connection.createStatement(); 
    } 

    public boolean insert(String statement){ 
     try{ 
      int i=stmt.executeUpdate(statement); 
      System.out.println("Successfully inserted."); 
      return true; 
     }catch(SQLException se){ 
      System.out.println("Inserting data failed."); 
      return false; 
     } 
    } 

    public boolean update(String statement){ 
     try{ 
      int i=stmt.executeUpdate(statement); 
      System.out.println("Successfully updated."); 
      return true; 
     }catch(SQLException se){ 
      System.out.println("Updating data failed."); 
      return false; 
     } 
    } 

    public boolean retrieve(String query){ 
     try{ 
      ResultSet rs = stmt.executeQuery(query); 
      System.out.println("Successfully retrieved :"); 
      while (rs.next()){ 
       System.out.println(rs.getRow()+". "+rs.toString()); 
      } 
      return true; 
     }catch(SQLException se){ 
      System.out.println("Updating data failed."); 
      return false; 
     } 
    } 

    public boolean delete(String statement){ 
     try{ 
      int i=stmt.executeUpdate(statement); 
      System.out.println("Successfully deleted."); 
      return true; 
     }catch(SQLException se){ 
      System.out.println("Deleting data failed."); 
      return false; 
     } 
    } 

} 

/* 

CREATE TABLE users (
user_login varchar(10) PRIMARY KEY NOT NULL, 
user_password varchar(20) NOT NULL 
); 

CREATE TABLE groups (
group_id varchar(10) PRIMARY KEY NOT NULL, 
group_name varchar(50), 
group_description varchar(200) 
); 

CREATE TABLE groups_users (
user_login varchar(10), 
group_id varchar(10), 
FOREIGN KEY (user_login) REFERENCES users(user_login), 
FOREIGN KEY (group_id) REFERENCES groups(group_id)); 


*/ 

編輯:回溯

Select: 1 
Please provide your query : 
SELECT * FROM users 
Inserting data failed. 
Welcome to simple JDBC example application./n 
Choose desired operation: 
Exception in thread "main" java.util.InputMismatchException 


1. Insert new instance 
     at java.util.Scanner.throwFor(Scanner.java:840) 
2. Update existing instance 
     at java.util.Scanner.next(Scanner.java:1461) 
3. Lookup 
     at java.util.Scanner.nextInt(Scanner.java:2091) 
4. Delete instance 
0. Exit 
     at java.util.Scanner.nextInt(Scanner.java:2050) 


     at task.Main.main(Main.java:26) 
Select: Java Result: 1 

所以錯誤來自行menuChoice = sc.nextInt();。而且,當我爲查詢添加另一個掃描器實例時,拾取操作類型將用戶返回到菜單而不詢問查詢。

+0

請爲錯誤添加StackTrace。 – jzd 2011-01-23 23:34:45

回答

0

這裏的的InputMismatchException定義:由Scanner拋出

以指示 檢索到的令牌不匹配所期望的類型的 圖案,或者 令牌超出範圍爲 預期類型。

我掃描了你的代碼,好像menuChoice = sc.nextInt();可能是拋出異常的那個。機會是你的while loop循環太多次,你的掃描器沒有下一個int值來讀取,這就是你得到這個異常的原因。

nextInt()是您使用的唯一一個引發此特定異常的掃描程序API。下面是nextInt()文檔: -

public int nextInt(int radix) 

Scans the next token of the input as an int. This method will throw InputMismatchException if the next token cannot be translated into a valid int value as described below. If the translation is successful, the scanner advances past the input that matched. 

If the next token matches the Integer regular expression defined above then the token is converted into an int value as if by removing all locale specific prefixes, group separators, and locale specific suffixes, then mapping non-ASCII digits into ASCII digits via Character.digit, prepending a negative sign (-) if the locale specific negative prefixes and suffixes were present, and passing the resulting string to Integer.parseInt with the specified radix. 

Parameters: 
    radix - the radix used to interpret the token as an int value 
Returns: 
    the int scanned from the input 
Throws: 
    InputMismatchException - if the next token does not match the Integer regular expression, or is out of range 
    NoSuchElementException - if input is exhausted 
    IllegalStateException - if this scanner is closed 

編輯:

試着改變你的while循環如下所示: -

while(menuChoice != 0 && sc.hasNext()){ 
    ... 
} 

這應該可以解決您的問題。

0

您的Scanner會在白色空間中破壞令牌。 Scanner.next()只返回一個標記(例如「SELECT」)。您輸入的其餘查詢可用於掃描您的nextInt()調用,但查詢中的下一個標記(例如「*」)不是整數。

而不是next()你可能想要nextLine()