Java: Check auto-generated ID - java

My Java program adds items into database. I have a code for generating random string that will be used as an item ID. I want to make IDchecker(id) that will check whether the ID already exists into database.
If I have codeIDgenerator() and IDchecker(id) methods, how do I make a loop that will generate new code if the ID already exists, or will exit the loop if the ID is unique and doesn't come up in the database?
Also I'm having trouble with my IDchecker(id) method, I'm using ResultSet to bring back the data from SQL, but I can't find a way to determine how many rows does ResultSet has (if at all). There is no isEmpty() for resultSet?
Here's the code:
public void AddItem() {
boolean checkCode = false;
while (checkCode == false) {
Random r = new Random();
int numbers = 100000 + (int) (r.nextFloat() * 899900);
String ID= Integer.toString(numbers);
try {
if (DatabaseConnection.checkID(ID) == false) {
checkCode = true;
System.out.println("ID is unique");
} else if (DatabaseConnection.checkID(ID) == true) {
System.out.println("ID is NOT unique");
}
} catch (SQLException ex) {
Logger.getLogger(ModelTabeleIntervencija.class.getName()).log(Level.SEVERE, null, ex);
}
}
And here is the ckeckID(ID) method
public boolean CheckID(String ID) throws SQLException {
String query = "SELECT itemId FROM items WHERE itemID= '"+ID+"'";
Statement dbStatement = connection.createStatement();
ResultSet rsItems= dbStatement .executeQuery(query);
if (rsItems.isEmpty( )== true){
return false;
// ID not found - is unique
} else{
return true;
// ID found - is not unique
}
}
Thanks

While generating unique id is best done in your database, I can help you simplify your code. You shouldn't need to check your database twice.
private final Random r = new Random();
public String getUniqueId() {
try {
while (true) {
int n = r.nextInt(1000 * 1000) + 1000 * 1000;
String id = ("" + n).substring(1); // number between 000000 and 999999
if (DatabaseConnection.checkID(id))
return id;
}
} catch (SQLException ex) {
throw new IllegalStateException("Cannot access database", ex);
}
}
However, instead of generating a random id, you could just get the next id.
public String getUniqueId() {
try {
String maxId = DatabaseConnection.selectMaxId();
int n = Integer.parseInt(maxId) + 1;
return ("" + n).substring(1); // number between 000000 and 999999
} catch (SQLException ex) {
throw new IllegalStateException("Cannot access database", ex);
}
}

Related

How to make column updatable in JDBC?

I'm using JDBC to make a banking system with Java. The user should be able to type in a number in a text field, and deposit said amount of money into the bank account. I would like to then update the account balance in the Microsot Access database.
I currently have this:
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C://Users//User//IdeaProjects//Database4.accdb")) {
Statement users = con.createStatement();
ResultSet sr = users.executeQuery("Select * from Registrations");
Boolean duplicate = false;
while (sr.next()) {
if (userID.equals(sr.getString(2))) {
match = sr;
duplicate = true;
System.out.println("Welcome " + match.getString(2));
System.out.println("Your balance is " + match.getString(3));
break;
}
}
}
catch (SQLException ex) {
ex.printStackTrace();
}
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == depositButton) {
String depositString = depositField.getText();
int depositAmount = Integer.parseInt(depositString);
try {
System.out.println(match.getInt(3) + depositAmount);
match.updateInt("AccBalance", match.getInt(3) + depositAmount);
match.updateRow();
}
catch (SQLException ex) {
ex.printStackTrace();
}
When I try to do this, I get the error 'attempt to assign to non-updatable column'.
I'm very new to Java and tried looking online to find fixes for this issue but couldn't find anything useful.
Try the code below
try (Connection con = DriverManager.getConnection("jdbc:ucanaccess://C://Users//mghosh22//IdeaProjects//Database4.accdb")) {
// Query example UPDATE user SET balance = 10000 WHERE user.id = 1;
PreparedStatement updateBalance = conn.prepareStatement("UPDATE <table> SET balance = ? WHERE <wich row update>");
// For each query parameter, set a value to execute the same
// preparedStatement.setParameterType(countEach?StartingWithOne, yourQueryParameter);
updateBalance.setDouble(1, 10,000.00);
// Execute update return the amount of rows your query affected, how we are talking about account balance, the number of rows affected may be ever one
if (updateBalance.executeUpdate() == 1) {
System.out.println("Row updated");
}
}

Why the place of the option always change?

I'm doing a phone book project in Java, using MySql for school.
I wanted to print the methods using the Class.getDeclaredMethods();
adding them to a Vector of type String.
and invoke a menu() method that prints and accepts the option from the user using Scanner
the problem is that it always changes the methods places.
for example it can print
0.addPerson
1.deleteContact
2.searchByChar
and the next time
0.deleteContact
1.addPerson
2.searchByChar.
the problem is that i have a Switch case depend on it.
the menu function:
public static int menu(Vector<?> options){
System.out.println("The Options: ");
for (int i = 0; i < options.size(); i++) {
System.out.println(i + ". " + options.get(i));
}
Scanner scanner = new Scanner(System.in);
System.out.println("Your Choice: ");
String optionString = scanner.nextLine();
int option = 0;
if(isNumber(optionString)){
option = Integer.valueOf(optionString);
}else{
System.out.println("Please Choose Valid Option");
return menu(options);
}
return option;
}
the methods that get my methods:
public static Vector<String> getClassMethods(Class whichClass){
Method[] methods = whichClass.getDeclaredMethods();
Vector<String> stringMethods = new Vector<>();
for (Method method : methods) {
if(Modifier.toString(method.getModifiers()).equals("protected")){
stringMethods.add(method.getName());
}
}
return stringMethods;
}
my class the connects to the data base:
private boolean getData(Person person){
String sql = "SELECT * FROM " + DB_NAME + " WHERE name = '" + person.getName() + "' and phone_number = '" + person.getPhoneNumber() + "'";
try {
ResultSet resultSet = db.prepareStatement(sql).executeQuery();
if (resultSet.next()) {
return true;
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return false;
}
protected void addPerson(){
Person person = MyUtills.createPerson();
if(getData(person)){
System.out.println(person.getName() + ", " + person.getPhoneNumber() + ": Already in Contacts" );
}else{
add(person);
}
}
private void add(Person person) {
String pName = person.getName();
String pPhone = person.getPhoneNumber();
String pAddress = person.getAddress();
String sql = "INSERT INTO " + DB_NAME + " (name,phone_number,address)" +
"VALUES (?,?,?)";
try {
statement = db.prepareStatement(sql);
statement.setString(1,pName);
statement.setString(2,pPhone);
statement.setString(3,pAddress);
statement.execute();
System.out.println("Added Successfully");
} catch (SQLException e) {
e.printStackTrace();
}
}
//delete contact by name
protected void deleteContact(){
System.out.println("Enter Name Please");
String name = MyUtills.readStringFromUser();
Vector<Person> vector = checkMoreThanOne(name);
if(vector.size() > 1){
System.out.println("Choose One To Delete: ");
int option = menu(vector);
delete(vector.get(option));
}
System.out.println("Deleted");
}
private Vector<Person> checkMoreThanOne(String name) {
Vector<Person> vector = new Vector<>();
String sql = "SELECT * FROM " + DB_NAME;
try {
ResultSet resultSet = db.prepareStatement(sql).executeQuery();
while(resultSet.next()){
String pName = resultSet.getString("name");
String pPhone = resultSet.getString("phone_number");
String pAddress = resultSet.getString("address");
if(pName.equals(name)){
vector.add(new Person(pName,pPhone,pAddress));
}
}
return vector;
} catch (SQLException e) {
e.printStackTrace();
}
return null;
}
//deleting and existing contact;
private void delete(Person person){
String sql = "DELETE FROM " + DB_NAME + " WHERE name = '" + person.getName() + "' and phone_number = '" + person.getPhoneNumber() + "'";
try {
statement = db.prepareStatement(sql);
statement.execute();
System.out.println("Deleted Successfully");
} catch (SQLException e) {
e.printStackTrace();
}
}
//creating a new table for empty data base!
private void createTable() {
try {
statement = db.prepareStatement(SQL_TABLE_STRING);
statement.execute();
} catch (SQLException e) {
e.printStackTrace();
}
}
protected void searchByFirstChar(Character character){
Vector<Person> personVector = new Vector<>();
String sql = "SELECT * FROM newphonebook";
try {
ResultSet resultSet = db.prepareStatement(sql).executeQuery();
while(resultSet.next()){
String name = resultSet.getString("name");
String phoneNum = resultSet.getString("phone_number");
String address = resultSet.getString("address");
if(character.equals(name.charAt(0))){
personVector.add(new Person(name,phoneNum,address));
}
}
System.out.println(personVector);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
public void getOptions(){
Vector<String> options = MyUtills.getClassMethods(DBWriterReader.class);
int option = MyUtills.menu(options);
switch (option){
case 0:
addPerson();
break;
case 1:
deleteContact();
break;
case 2:
// searchByFirstChar();
break;
}
}
}
I know it's not best written but I'm working on it to make it better
The Writing and Reading from the data base works fine, its the way it prints my methods that makes the problem..
If you need to guarantee the order of elements in a data structure, you don't use Vector -- it's not 1999 anymore. Look at the documentation for Vector. You get elements in the order determined by an iterator, not as they are stored.
Change your data structure to an ArrayList, which guarantees order. ArrayLists are also more performant in a single threaded application like yours, because unlike Vector, an ArrayList skips the overhead associated with being synchronized. Using the index of the ArrayList elements may also simplify the way you construct your switch statement.

Strings can not be converted to DAO Receiver

I am trying to perform batch insertion operation with a list object but while inserting I am getting String cannot be converted to DAO.The receiver in the iterator loop.
I have tried to list the list object, at that time it is printing values from the list. but, when I use generics are normal list it is showing error and I don't find any solution to insert
From this method I am reading the excel file and storing into list
public List collect(Receiver rec)
{
//ReadFromExcel rd = new ReadFromExcel();
List<String> up = new ArrayList<String>();
//List<String> details = rd.reader();
//System.out.println(details);
try( InputStream fileToRead = new FileInputStream(new File(rec.getFilePath())))
{
XSSFWorkbook wb = new XSSFWorkbook(fileToRead);
wb.setMissingCellPolicy(Row.MissingCellPolicy.RETURN_BLANK_AS_NULL);
XSSFSheet sheet = wb.getSheetAt(0);
DataFormatter fmt = new DataFormatter();
String data ="";
for(int sn = 0;sn<wb.getNumberOfSheets()-2;sn++)
{
sheet = wb.getSheetAt(sn);
for(int rn =sheet.getFirstRowNum();rn<=sheet.getLastRowNum();rn++)
{
Row row = sheet.getRow(rn);
if(row == null)
{
System.out.println("no data in row ");
}
else
{
for(int cn=0;cn<row.getLastCellNum();cn++)
{
Cell cell = row.getCell(cn);
if(cell == null)
{
// System.out.println("no data in cell ");
// data = data + " " + "|";
}
else
{
String cellStr = fmt.formatCellValue(cell);
data = data + cellStr + "|";
}
}
}
}
}
up = Arrays.asList(data.split("\\|"));
// System.out.println(details);
}
catch (FileNotFoundException ex)
{
Logger.getLogger(BImplementation.class.getName()).log(Level.SEVERE, null, ex);
}
catch (IOException ex)
{
Logger.getLogger(BImplementation.class.getName()).log(Level.SEVERE, null, ex);
}
Iterator iter = up.iterator();
while(iter.hasNext())
{
System.out.println(iter.next());
}
String row="";
Receiver info = null;
String cid = "";
String cname = "";
String address = "";
String mid = "";
boolean b = false;
List<Receiver> res = new ArrayList<Receiver>();
int c = 0;
try
{
String str = Arrays.toString(up.toArray());
//System.out.println(str);
String s = "";
s = s + str.substring(1,str.length());
// System.out.println("S:"+s);
StringTokenizer sttoken = new StringTokenizer(s,"|");
int count = sttoken.countTokens();
while(sttoken.hasMoreTokens())
{
if(sttoken.nextToken() != null)
{
// System.out.print(sttoken.nextToken());
cid = sttoken.nextToken();
cname = sttoken.nextToken();
address = sttoken.nextToken();
mid = sttoken.nextToken();
info = new Receiver(cid,cname,address,mid);
res.add(info);
System.out.println("cid :"+cid+ " cname : "+cname +" address : "+address+" mid : "+mid);
c = res.size();
// System.out.println(c);
}
else
{
break;
}
}
System.out.println(count);
// System.out.println("s");
}
catch(NoSuchElementException ex)
{
System.out.println("No Such Element Found Exception" +ex);
}
return up;
}
with this method I'm trying to insert into database
public boolean insert(List res)
{
String sqlQuery = "insert into records(c_id) values (?)";
DBConnection connector = new DBConnection();
boolean flag = false;
// Iterator itr=res.iterator();
// while(it.hasNext())
// {
// System.out.println(it.next());
// }
try( Connection con = connector.getConnection();)
{
con.setAutoCommit(false);
PreparedStatement pstmt = con.prepareStatement(sqlQuery);
Iterator it = res.iterator();
while(it.hasNext())
{
Receiver rs =(Receiver) it.next();
pstmt.setString(1,rs.getcID());
pstmt.setString(2,rs.getcName());
pstmt.setString(3,rs.getAddress());
pstmt.setString(4,rs.getMailID());
pstmt.addBatch();
}
int [] numUpdates=pstmt.executeBatch();
for (int i=0; i < numUpdates.length; i++)
{
if (numUpdates[i] == -2)
{
System.out.println("Execution " + i +": unknown number of rows updated");
flag=false;
}
else
{
System.out.println("Execution " + i + "successful: " + numUpdates[i] + " rows updated");
flag=true;
}
}
con.commit();
} catch(BatchUpdateException b)
{
System.out.println(b);
flag=false;
}
catch (SQLException ex)
{
Logger.getLogger(BImplementation.class.getName()).log(Level.SEVERE, null, ex);
System.out.println(ex);
flag=false;
}
return flag;
}
I want to insert list object using JDBC batch insertion to the database.
Your method collect(Receiver rec) returns the List of strings called up.
return up;
However (if you are really using the method collect to pass the List into insert(List res) method), you are expecting this list to contain Receiver objects. Which is incorrect, since it collect(..) returns the list of Strings.
And that causes an error when you try to cast Receiver rs =(Receiver) it.next();
You need to review and fix your code, so you will pass the list of Receiver objects instead of strings.
And I really recommend you to start using Generics wherever you use List class. In this case compiler will show you all data-type errors immediately.

jdbc consume too much memory

I wrote program in that I need to update 10000. The query is:
for (Ticket ticket : existInBoth) {
if (!ticket.isUpdatable() && !ticket.isDeleted()) continue;
String query = String.format("update tickets SET vehicle_id = %d , price = %d , free = %d,time = '%s',date='%s',url='%s',deleted_at=NULL WHERE unique_key = '%s'",
ticket.getVehicle().getId(), ticket.getPrice(), ticket.getFree(), ticket.getTime(), ticket.getDate(), ticket.getUrl(), ticket.getUniqueKey());
if (db.update(query) > 0)
updatedDates.add(ticket.getDate());
}
and db.update
#Override
public int update(String sql) {
synchronized (Main.THREAD_GUARD) {
int result = -1;
Connection connection = open();
try {
Statement statement = connection.createStatement();
result = statement.executeUpdate(sql);
statement.close();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(connection);
}
return result;
}
}
It seems realy easy. But when I ran it I see this updating take about 300MB of memory.
I carefully close all statements and connections.

How to do a select all using GreenDAO?

Does anyone know how to do a simple select * from table in greenDAO and place it into an entity? I have done some research on this and I am unable to get any simple example. This is what I have so far:
public void storeAppTimeUsageData(AppTimeUsage stats) {
List<AppTimeUsage> items = new ArrayList<>();
//appTimeUsageDao = DeviceInsightApp.getSession(this, true).getAppTimeUsageDao();
try {
// master
appTimeUsageDao.insertOrReplace(stats);
//} catch (IOException e) {
} catch (Exception e) {
Log.e("Error", "Some exception occurred", e);
Log.e("APP_TAG", "STACKTRACE");
Log.e("APP_TAG", Log.getStackTraceString(e));
}
String sql = "SELECT * FROM APP_TIME_USAGE ";
Cursor c = appTimeUsageDao.getDatabase().rawQuery(sql, null);
int offset = 0;
int d ;
int cd ;
String e = "";
while (c.moveToNext()) {
AppTimeUsage atu AppTimeUsage(
c.getLong(0);
//long b = c.getInt(0);
d = c.getInt(2);
e = c.getString(3);
break;
);
items.add(atu);
}
}
GreenDAO already comes with a built-in method for achieve this task. In your case:
List<AppTimeUsage> items = appTimeUsageDao.loadAll();
This will select all records from APP_TIME_USAGE and return a List<AppTimeUsage> containing the entities.

Categories