运行程序时,我在Eclipse控制台中得到了这个信息:
Type a number then press enter.
1. Add a customer
2. Add an order
3. Remove an order
4. Ship an order
5. Print pending orders with customer information
6. Restock parts
7. Exit
1
Loading driver...
Driver loaded!
Connecting database...
Database connected!
Enter 5 letters or less to identify the customer as.
Exception in thread "main" java.util.NoSuchElementException: No line found
at java.util.Scanner.nextLine(Scanner.java:1540)
我尝试仅使用一个扫描仪而不关闭它,但这没有用。有人可以帮我弄清楚为什么我在显示为tempCustID = keyboard1.nextLine();
的行上收到此消息吗?奇怪的是,在上一行int seed = keyboard.nextInt();
上没有错误发生。
这是我的Menu.java类的代码:
import java.sql.Connection;
import java.sql.SQLException;
public class Menu {
public static void main(String[] args) throws SQLException {
// TODO Auto-generated method stub
DatabaseModifier session = new DatabaseModifier();
int seed = session.options();
Connection mycon = session.connectDB();
while(seed != 7) {
if(seed == 1) {
session.addCust(mycon);
}else if(seed == 2) {
//session.addOrder(mycon);
}else if(seed == 3) {
}else if(seed == 4) {
}else if(seed == 5) {
}else if(seed == 6) {
}else {
System.out.println("Invalid option.");
}
seed = session.options();
}
System.out.println("Good-bye.");
}
}
这是我的DatabaseModifier.java类的代码:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class DatabaseModifier {
public int options() {
System.out.println("Type a number then press enter.");
System.out.println("1. Add a customer");
System.out.println("2. Add an order");
System.out.println("3. Remove an order");
System.out.println("4. Ship an order");
System.out.println("5. Print pending orders with customer information");
System.out.println("6. Restock parts");
System.out.println("7. Exit");
Scanner keyboard = new Scanner(System.in);
int seed = keyboard.nextInt();
keyboard.close();
return seed;
}
public Connection connectDB() {
String url = "jdbc:mysql://localhost:3306/northwind?useSSL=false&serverTimezone=EST";
String username = "root";
String password = "password";
System.out.println("Loading driver...");
try {
Class.forName("com.mysql.cj.jdbc.Driver");
System.out.println("Driver loaded!");
}catch (ClassNotFoundException e) {
throw new IllegalStateException("Cannot find the driver in the classpath!", e);
}
System.out.println("Connecting database...");
try {
Connection mycon = DriverManager.getConnection(url, username, password);
System.out.println("Database connected!");
return mycon;
} catch (SQLException e) {
throw new IllegalStateException("Cannot connect the database!", e);
}
}
public void addCust(Connection mycon) throws SQLException {
String tempCustID, custID, comp, contName, contTitle, addr, city, reg, postCode, country, phone, fax;
Scanner keyboard1 = new Scanner(System.in);
int correctInput = 0;
do {
PreparedStatement stat = mycon.prepareStatement("SELECT CustomerID FROM customers");
ResultSet cust = stat.executeQuery();
System.out.println("Enter 5 letters or less to identify the customer as.");
tempCustID = keyboard1.nextLine();
custID = tempCustID.toUpperCase();
while (cust.next()) {
String customerID = cust.getString("CustomerID");
if (custID.equals(customerID) || "".equals(custID) || "NULL".equals(custID) || "null".equals(custID) || custID.length() > 5) {
System.out.println(
"Customer ID already exists or you entered incorrect input. Please enter a different sequence of 5 letters or less to identify the customer as.");
}else
correctInput = 1;
}
}while(correctInput == 0);
correctInput = 0;
do {
PreparedStatement stat1 = mycon.prepareStatement("SELECT CompanyName FROM customers");
ResultSet comp1 = stat1.executeQuery();
System.out.println("Enter 40 letters or less to identify the company name.");
comp = keyboard1.nextLine();
while (comp1.next()) {
String compName = comp1.getString("CompanyName");
if (compName.equals(comp) || "".equals(comp) || "NULL".equals(comp) || "null".equals(comp) || comp.length() > 40) {
System.out.println(
"Company name already exists or you entered incorrect input. Please enter a different sequence of 40 letters or less to identify the company as.");
}else
correctInput = 1;
}
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 30 letters or less to identify the contact's first and last name.");
contName = keyboard1.nextLine();
if ("".equals(contName) || "NULL".equals(contName) || "null".equals(contName) || contName.length() > 30) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 30 letters or less to identify the contact's job title.");
contTitle = keyboard1.nextLine();
if ("".equals(contTitle) || "NULL".equals(contTitle) || "null".equals(contTitle) || contTitle.length() > 30) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 60 letters or less to identify the company's address.");
addr = keyboard1.nextLine();
if ("".equals(addr) || "NULL".equals(addr) || "null".equals(addr) || addr.length() > 60) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 15 letters or less to identify the company's city.");
city = keyboard1.nextLine();
if ("".equals(city) || "NULL".equals(city) || "null".equals(city) || city.length() > 15) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 15 letters or less to identify the company's region.");
reg = keyboard1.nextLine();
if ("".equals(reg) || "NULL".equals(reg) || "null".equals(reg) || reg.length() > 15) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 10 letters or less to identify the company's postal code.");
postCode = keyboard1.nextLine();
if ("".equals(postCode) || "NULL".equals(postCode) || "null".equals(postCode) || postCode.length() > 10) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 15 letters or less to identify the company's country.");
country = keyboard1.nextLine();
if ("".equals(country) || "NULL".equals(country) || "null".equals(country) || country.length() > 15) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 24 letters or less to identify the company's phone number.");
phone = keyboard1.nextLine();
if ("".equals(phone) || "NULL".equals(phone) || "null".equals(phone) || phone.length() > 24) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
correctInput = 0;
do {
System.out.println("Enter 24 letters or less to identify the company's fax.");
fax = keyboard1.nextLine();
if ("".equals(fax) || "NULL".equals(fax) || "null".equals(fax) || fax.length() > 24) {
System.out.println("Incorrect input.");
}else
correctInput = 1;
}while(correctInput == 0);
keyboard1.close();
PreparedStatement newCust = mycon.prepareStatement(
"INSERT INTO customers" + "(CustomerID, CompanyName, ContactName, ContactTitle, Address, "
+ "City, Region, PostalCode, Country, Phone, Fax)" + "VALUES(?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
newCust.setString(1, custID);
newCust.setString(2, comp);
newCust.setString(3, contName);
newCust.setString(4, contTitle);
newCust.setString(5, addr);
newCust.setString(6, city);
newCust.setString(7, reg);
newCust.setString(8, postCode);
newCust.setString(9, country);
newCust.setString(10, phone);
newCust.setString(11, fax);
newCust.executeUpdate();
}
答案 0 :(得分:1)
扩展并弄清user3170251的注释,关闭Scanner
也会关闭基础数据源,如果该数据源实际上是Closeable
:
如果此扫描仪尚未关闭,则其基础 可读性还实现了Closeable接口,然后可读性的 close方法将被调用。如果此扫描仪已经关闭,则 调用此方法无效。
作为InputStream
,您的输入源System.in
实际上是Closeable
。一旦关闭,它就关闭了-即使将其包装在新的Scanner
中,也无法再读取任何内容。这就是为什么您第二次及其后调用DataBaseModifier.options()
引发的原因。
解决方案是避免关闭System.in
。此外,重用单个Scanner
而不是创建新的Scanner
是最安全的,因为有可能将数据缓冲在Scanner
内并在关闭时丢失。有几种方法可以解决该问题,但是一种非常简单的方法是使您的@CrossOrigin
成为实例变量而不是局部变量。在实例化类时初始化它,并使其永远打开。