JDBC查询+ Scanner.next()给出了InputMismatchException

时间:2011-01-23 23:16:29

标签: java jdbc java.util.scanner

我使用Java的JDBC编写了最简单的DBMS实现。在我的应用程序中,我有权在一些简单的mysql数据库上执行CRUD操作。一切都在控制台完成。问题是,当用户从菜单中选择操作(当前硬编码的查询)然后提供查询时,会抛出java.util.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();行。此外,当我为查询添加另一个扫描程序实例时,选择操作类型会将用户返回到菜单而不需要查询。

2 个答案:

答案 0 :(得分:0)

以下是InputMismatchException的定义:

  

扫描仪抛出指示   检索到的令牌与   预期类型的​​模式,或者   令牌超出范围   期望的类型。

我扫描了您的代码,似乎menuChoice = sc.nextInt();可能是抛出该异常的那个。有可能你的while loop循环次数过多而你的扫描仪没有下一个要读取的int值,这就是你得到这个异常的原因。

nextInt()是您使用的唯一抛出此特定异常的Scanner 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()){
   ...
}

这可以解决您的问题。

答案 1 :(得分:0)

您的Scanner在空白处打破了令牌。 Scanner.next()仅返回一个标记(例如“SELECT”)。您输入的其余查询可用于扫描nextInt()来电,但查询中的下一个标记(例如“*”)不是整数。

而不是next()您可能需要nextLine()