Incorrect data getting fetched from select query - java

Can someone review my code
This query is fetching two values address_id and postcode from table1. Here
AddressID class has two variable postcode(string) and address_id(integer) :
#Select("SELECT address_id,postcode FROM table1 WHERE custom_field_1 = #{caseid}")
public List<AddressID> getAddressIdPostCodeList(String caseid);
Here is how AddressID looks AddressID.java
private int addressId;
private String postcode;
//getters and setters of Pstcode and addressId
#Override
public String toString() {
return "PostCode : " + this.postcode;
}
while executing this query I get value of address_id as 0 and required postcode. Although DB has values of address_id which is not zero. Where my code is failing?
This is where in my main method I am calling
List<AddressID> addresses = new ArrayList<>();
addresses = mainClassObject.getAddressIdPostCodeList(address.getcaseId());
Ideally addresses object should have both address_id and postcode. I am getting both values but address_id I am getting 0 and correct values for postcode.

Since I cant comment because I dont have 50 reputation, I had to write it here, its hard to tell from the code you posted, to give you an answer I need more detail on what getAddressIdPostCodeList() does, since you said the data in the DB has no ceros the error must be in the method getAddressIdPostCodeList() and/or in how you are handling the resultset of the Query
EDIT: Solution using Oracle JDBC Driver
Since I dont know how to use Mybatis, heres a solution using JDBC.
to connect using JDBC to your Oracle DB here's a simple tutorial:
1. First you need to download de JDBC driver from Oracle depending your DB version (11g,12c,10g), the driver Its called ojdbcX.jar where X is a number of the version of the driver
2. After you have downloaded the driver you need to add the .jar to your project, if you are using Netbeans IDE you can add it like this:
if you are using Eclipse you can use the following Link to see how to add the .JAR file: How to import a jar in Eclipse
3. After adding the .JAR its pretty simple, you just need to connect to the DB using your credentials, here is an example on how to do it:
Connection connection = null;
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:xe", "system", "password"); } catch (Exception ex) {
ex.printStackTrace();
}
for more deatiled information on how to connect, you can check the oracle.jdbc
Class OracleDriver Documentation
4. After the connection has been made its pretty simple, Heres a short code example to get the result you want, you need to modify it with your connection details and as you see fit because im making a couple of assumptions, this code is just an example:
Main.Java
public class Main {
public static void main(String[] argv) {
List<AddressID> addresses;
SQLConnect conex= new SQLConnect();
String caseid="the id you want";
addresses=conex.getAddressIdPostCodeList(caseid);
}
AddressID.java
public class AddressID {
private String addressId;
private String postcode;
}
SQLConnect.Java
public class SQLConnect {
public static Connection connection;
public SQLConnect (){
createConnection();
}
public void CreateConnection(){
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
connection = DriverManager.getConnection(
"jdbc:oracle:thin:#localhost:1521:xe", "system", "password")
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void closeConnection(){
if(connection!=null){
try {
connection.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
}
public ResultSet ExecuteQuery(String queryTXT) throws SQLException{
Statement query = connection.createStatement();
ResultSet table=query.executeQuery(queryTXT);
return table;
}
public List<AddressID> getAddressIdPostCodeList(String caseid) throws SQLException{
List<AddressID> addresses = new ArrayList <> ();
ResultSet table=ExecuteQuery("SELECT address_id,postcode FROM table1 WHERE custom_field_1 ='"+caseid+"';");
while (table.next()) {
AddressID aux;
aux.addressId=table.getString(1);
aux.postcode=table.getString(2);
addresses.add(aux);
}
return addresses;
}
}

I did forgot to wtite my result query which is actually binding data fetched
from select query to the AddressId class..
#Results(id = "result",
value = {
#Result(property = "addressId", column = "address_id"),
#Result(property = "postcode", column = "postcode")
}
)

Related

H2 Database, problems getting data from tables

I'm creating a JavaFX application, I've connected to the database fine. However when i look to get data from the tables i get the error
org.h2.jdbc.JdbcSQLException: Table "LECTURE" not found; SQL
statement: SELECT NAME FROM Lecture [42102-192]
and I'm 100% sure i'm connected to the database and the table is definitely there, any suggestions on why this is?
hear is my connection code and the code i am running just so you can see
public class ConnectionFactory {
//static reference to itself
private static ConnectionFactory instance = new ConnectionFactory();
public static final String URL = "jdbc:h2:file:~/db\\.";
public static final String USER = "notepad";
public static final String PASSWORD = "password";
public static final String DRIVER_CLASS = "org.h2.Driver";
//private constructor
private ConnectionFactory() {
try {
Class.forName(DRIVER_CLASS);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
private Connection createConnection() {
Connection connection = null;
try {
connection = DriverManager.getConnection(URL, USER, PASSWORD);
} catch (SQLException e) {
System.out.println("ERROR: Unable to Connect to Database.");
}
return connection;
}
public static Connection getConnection() {
return instance.createConnection();
}
}
And the query being run
private void onLoadYearSelect() {
try {
Connection con = ConnectionFactory.getConnection();
Statement stat = con.createStatement();
String query = "SELECT NAME FROM Lecture";
ResultSet years = stat.executeQuery(query);
while(years.next()){
yearSelect.setValue(years.getString("NAME"));
System.out.println(years.getString("NAME"));
}
} catch (SQLException e) {
e.printStackTrace();
}
}
public void initialize(){
onLoadYearSelect();
}
If it says the table doesn't exist, then it really doesn't exist.
Most likely, you are not actually connecting to the correct database. In fact, by default, if the connection string points to a non-existent database, it just creates an empty database on the fly, which would explain your error.
It's probably too late now (because there is probably a 2nd database created already somewhere), but to avoid this confusion, it's not a bad idea to include IFEXISTS=TRUE in the connection string so that it fails if the database doesn't exist, rather than creating an empty one that will mask the true problem.
public static final String URL = "jdbc:h2:file:~/db\\.;IFEXISTS=TRUE";
However, one thing you can still try to debug the problem, is to add IFEXISTS=TRUE to the connection string. Then move or rename the database you think it should be connecting to so as to make the connection string invalid. Basically, force it to fail. If the code still connects to the database successfully, then you'll know the connection string is not pointing to the location you think it is.

Derby Embedded create tabel inorder run on any pc

Hi below code form from my Derby embedded example...
when i run on my pc(developed)it run smoothly.
And then i export as jar file and run on another pc .it throws an exception table already exists.
How can i create table only once on any pc
public class Main {
public static void main(String[] args) throws SQLException {
final String driver="org.apache.derby.jdbc.EmbeddedDriver";
final String url="jdbc:derby:db/testdb";
try {
Class.forName(driver);
Connection connection=DriverManager.getConnection(url);
//connection.createStatement().execute("create table channels(channel varchar(20),topic varchar(20))");
// connection.createStatement().execute("insert into channels (channel,topic) values('hbo','action')");
// System.out.println("saved");
PreparedStatement preStmt=connection.prepareStatement("select * from channels");
ResultSet set=null;
set=preStmt.executeQuery();
while(set.next()){
System.out.print(set.getString(1));
System.out.println(set.getString(2));
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
Also how to configure same issue on hibernate.cfg.xml file...!!
You can check to see if the table already exists before you create it.
Use the DatabaseMetadata calls to examine the structure of the database after you connect to it.
See: http://docs.oracle.com/javase/6/docs/api/java/sql/DatabaseMetaData.html
You can check before every creation check it in DB metadata:
Methods looks like following:
ResultSet result = databaseMetaData.getTables(
catalog, schemaPattern, tableNamePattern, types );
Abd you can use it as following:
ResultSet result = databaseMetaData.getTables(
null, null, TABLE_NAME, null );

How can I write string to container to be used after a loop?

I have an aplication which create a number of query (update or insert) and then each query is executed.
The whole code is working fine but I've saw that my server IO latency is too much during this proccess.
The code execute a loop which is taking arround 1 minute.
Then what I wanted to do is write each query in memory instead to execute it, and then, once I have the whole list of query to execute, use "LOAD DATA LOCAL INFILE" from mysql, which will take less time.
My question is: How can I write all my query (String object) in a "File" or "any other container" in java to use it after the loop?.
#user3283548 This is my example code:
Class1:
import java.util.ArrayList;
public class Class1 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
ArrayList<String> Staff=new ArrayList<String>();
Staff.add("tom");
Staff.add("Laura");
Staff.add("Patricia");
for (int x = 0; x < Staff.size(); x++) {
System.out.println(Staff.get(x));
Class2 user = new Class2 (Staff.get(x));
user.checkUser();
}
}
}
Class2:
public class Class2 {
private String user;
public Class2(String user){
this.user=user;
}
public void checkUser() throws Exception{
if (user.equals("tom")){
String queryUser="update UsersT set userStatus='2' where UserName='"+user+"';";
Class3 updateUser = new Class3(queryUser);
updateUser.UpdateQuery();;
}else{
String queryUser="Insert into UsersT (UserName,userStatus)Values('"+user+"','1');";
Class3 updateUser = new Class3(queryUser);
updateUser.InsertQuery();
System.out.println(user+" is not ton doing new insert");
}
}
}
Class3:
public class Class3 {
public String Query;
public Class3(String Query){
this.Query = Query;
}
public void UpdateQuery() throws Exception{
/*// Accessing Driver From Jar File
Class.forName("com.mysql.jdbc.Driver");
//DB Connection
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/default","root","1234567");
String sql =Query;
PreparedStatement pst = con.prepareStatement(sql);*/
System.out.println(Query); //Just to test
//pst.execute();
}
public void InsertQuery() throws Exception{
/*// Accessing Driver From Jar File
Class.forName("com.mysql.jdbc.Driver");
//DB Connection
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/default","root","1234567");
String sql =Query;
PreparedStatement pst = con.prepareStatement(sql);*/
System.out.println(Query); //Just to test
//pst.execute();
}
}
Then, what I wanted to do is create an ArraList in Class1 and use it in Class3 to collect all the queries which has to be executed.
The idea is to execute the list of queries in one time, once the main process is finished, istead to do it for each element within in loop of the Class1. I wanted to do it, because I think it will be take less resource IO from the server HD
Your loop is probably too slow because you're building up Strings using String
I'd hazard a guess you're doing things like
String query = "SELECT * FROM " + variablea + " WHERE + variableb + " = " ...
If you're doing a lot of string concatenation then use StringBuilder as every time you change a string it is actually re-created which is expensive. Simply changing your code to use StringBuilder instead of string will probably cut your loop executed time to a couple of MS. Simply call .toString() method of StringBuilder obj to get the string.
Storing objects
If you want to store anything for later use you should store it in a Collection. If you want a a key-value relationship then use a Map (HashMap would suit you fine). If you just want the values use an List (ArrayList is most popular).
So for example if I wanted to store query strings for later use I would...
Construct the string using StringBuilder.
Put the string (by calling .toString() into a HashMap
Get the query string from the HashMap...
You should never store things on disk if you don't need them to be persistent over application restarts and even then I'd store them in a database not in a file.
Hope this helps.
Thanks
David
EDIT: UPDATE BASED ON YOU POSTING YOUR CODE:
OK this needs some major re-factoring!
I've kept it really simple because I don't have a lot of time to re-write comprehensively.
I've commented where I have made corrections.
Your major issue here is creating objects in loops. You should just create the object once as creating objects is expensive.
I've also corrected other coding issues and replaced the for loop as you shouldn't be writing it like that.I've also renamed the classes to something useful.
I've not tested this so you may need to do some work to get it to work. But this should be a lot faster.
OLD CLASS 1
import java.util.ArrayList;
import java.util.List;
public class StaffChecker {
public static void main(String[] args) throws Exception {
// Creating objects is expensive, you should do this as little as possible
StaffCheckBO staffCheckBO = new StaffCheckBO();
// variables should be Camel Cased and describe what they hold
// Never start with ArrayList start with List you should specific the interface on the left side.
List<String> staffList = new ArrayList<String>();
staffList.add("tom");
staffList.add("Laura");
staffList.add("Patricia");
// use a foreach loop not a (int x = 0 ... ) This is the preffered method.
for (String staffMember : staffList) {
// You now dont need to use .get() you can access the current variable using staffMember
System.out.println(staffMember);
// Do the work
staffCheckBO.checkUser(staffMember);
}
}
}
OLD CLASS 2
/**
* Probably not really any need for this class but I'll assume further business logic may follow.
*/
public class StaffCheckBO {
// Again only create our DAO once...CREATING OBJECTS IS EXPENSIVE.
private StaffDAO staffDAO = new StaffDAO();
public void checkUser(String staffMember) throws Exception{
boolean staffExists = staffDAO.checkStaffExists(staffMember);
if(staffExists) {
System.out.println(staffMember +" is not in database, doing new insert.");
staffDAO.insertStaff(staffMember);
} else {
System.out.println(staffMember +" has been found in the database, updating user.");
staffDAO.updateStaff(staffMember);
}
}
}
OLD CLASS 3
import java.sql.*;
/**
* You will need to do some work to get this class to work fully and this is obviously basic but its to give you an idea.
*/
public class StaffDAO {
public boolean checkStaffExists(String staffName) {
boolean staffExists = false;
try {
String query = "SELECT * FROM STAFF_TABLE WHERE STAFF_NAME = ?";
PreparedStatement preparedStatement = getDBConnection().prepareStatement(query);
// Load your variables into the string in order to be safe against injection attacks.
preparedStatement.setString(1, staffName);
ResultSet resultSet = preparedStatement.executeQuery();
// If a record has been found the staff member is in the database. This obviously doesn't account for multiple staff members
if(resultSet.next()) {
staffExists = true;
}
} catch (SQLException e) {
System.out.println("SQL Exception in getStaff: " + e.getMessage());
}
return staffExists;
}
// Method names should be camel cased
public void updateStaff(String staffName) throws Exception {
try {
String query = "YOUR QUERY";
PreparedStatement preparedStatement = getDBConnection().prepareStatement(query);
// Load your variables into the string in order to be safe against injection attacks.
preparedStatement.setString(1, staffName);
ResultSet resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
System.out.println("SQL Exception in getStaff: " + e.getMessage());
}
}
public void insertStaff(String staffName) throws Exception {
try {
String query = "YOUR QUERY";
PreparedStatement preparedStatement = getDBConnection().prepareStatement(query);
// Load your variables into the string in order to be safe against injection attacks.
preparedStatement.setString(1, staffName);
ResultSet resultSet = preparedStatement.executeQuery();
} catch (SQLException e) {
System.out.println("SQL Exception in getStaff: " + e.getMessage());
}
}
/**
* You need to abstract the connection logic away so you avoid code reuse.
*
* #return
*/
private Connection getDBConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/default", "root", "1234567");
} catch (ClassNotFoundException e) {
System.out.println("Could not find class. DB Connection could not be created: " + e.getMessage());
} catch (SQLException e) {
System.out.println("SQL Exception. " + e.getMessage());
}
return connection;
}
}

Using database mysql in Java

I have started trying out some stuff so that I can use mysql database together with Java. First of all I have some questions about it.
I have used mysql a lot with PHP development but never with Java. Can I use the MySQL that MAMP brings or do I have to install it stand alone or something?
and second.. I have created this code with the help of a tutorial but the only output I get is
com.mysql.jdbc.Driver
The code that I have used for this you can find below:
package Databases;
import java.sql.*;
public class MysqlConnect{
/* These variable values are used to setup
the Connection object */
static final String URL = "jdbc:mysql://localhost:3306/test";
static final String USER = "root";
static final String PASSWORD = "root";
static final String DRIVER = "com.mysql.jdbc.Driver";
public Connection getConnection() throws SQLException {
Connection con = null;
try {
Class.forName(DRIVER);
con = DriverManager.getConnection(URL, USER, PASSWORD);
}
catch(ClassNotFoundException e) {
System.out.println(e.getMessage());
System.exit(-1);
}
return con;
}
public void getEmployees() {
ResultSet rs = null;
try {
Statement s = getConnection().createStatement();
rs = s.executeQuery("SELECT id, name, job_id, location FROM person");
System.out.format("%3s %-15s %-7s %-7s%n",
"ID", "NAME", "JOB ID",
"LOCATION");
System.out.format("%3s %15s %7s %7s%n",
"---", "---------------",
"-------", "--------");
while(rs.next()) {
long id = rs.getLong("id");
String name = rs.getString("name");
long job = rs.getLong("job_id");
String location = rs.getString("location");
System.out.format("%-3d %-15s %7d %5s%n",
id, name, job, location);
}
}
catch(SQLException e) {
System.out.println(e.getMessage());
System.exit(-1);
}
}
}
It's coming from the following block:
catch(ClassNotFoundException e) {
System.out.println(e.getMessage());
System.exit(-1);
}
That's a pretty poor way of handling exceptions. You're just printing the exception message. You have no clue what's going on. Rather just throw it (which will end up with a nice stacktrace), or print a more descriptive message along alone the exception message, e.g.
catch(ClassNotFoundException e) {
System.out.println("JDBC driver class not found in runtime classpath: " + e.getMessage());
System.exit(-1);
}
How to fix the particular exception is in turn actually a second question (with a pretty obvious answer: just put JAR file containing JDBC driver class in runtime classpath), but ala, you may find this mini-tutorial helpful then: Connect Java to a MySQL database.
Unrelated to the concrete problem, I'm not sure which tutorial you're reading there, but I'd take it with a grain of salt. Apart from poor exception handling, it's also leaking DB resources in getEmployees() method by never closing the result set, statement and connection. This is absolutely not a good practice either. How to do it is also already covered in the aforelinked mini-tutorial. See further also: How often should Connection, Statement and ResultSet be closed in JDBC?
Yes, you need to install MySQL server locally or remotely.
The code will be usable if you also downloaded jdbc Driver jar from MySQL download pages. and you configured your MySQL instance with the proper username and password.

Store database connection as separate Class - Java

Is it possible to store a database connection as a separate class, then call the database objects from a main code? ie;
public class main{
public static void main{
try{
Class.forName("com.jdbc.driver");
Database to = new Database(1,"SERVER1","DATABASE");
Database from = new Database(2,"SERVER2","DATABASE");
String QueryStr = String.format("SELECT * FROM TABLE WHERE Id = %i", to.id)
to.results = sql.executeQuery(QueryStr);
while (to.results.next()) {
String QueryStr = String.format("INSERT INTO Table (A,B) VALUES (%s,%s)",to.results.getString(1),to.results.getString(2));
from.sql.executeQuery("QueryStr");
}
to.connection.close()
from.connection.close()
} catch (Exception ex) {
ex.printStackTrace();
{ finally {
if (to.connection != null)
try {
to.connection.close();
} catch (SQLException x) {
}
if (from.connection != null)
try {
from.connection.close();
} catch (SQLException x) {
}
}
}
public static class Database {
public int id;
public String server;
public String database;
public Connection connection;
public ResultSet results;
public Statement sql;
public Database(int _id, String _server, String _database) {
id = _id;
server = _server;
database = _database;
String connectStr = String.format("jdbc:driver://SERVER=%s;port=6322;DATABASE=%s",server,database);
connection = DriverManager.getConnection(connectStr);
sql = connection.createStatement;
}
}
}
I keep getting a "Connection object is closed" error when I call to.results = sql.executeQuery("SELECT * FROM TABLE"); like the connection closes as soon as the Database is done initializing.
The reason I ask is I have multiple databases that are all about the same that I am dumping into a master database. I thought it would be nice to setup a loop to go through each from database and insert into each to database using the same class. Is this not possible? Database will also contain more methods than shown as well. I am pretty new to java, so hopefully this makes sense...
Also, my code is probably riddled with syntax errors as is, so try not to focus on that.
Connection object is closed doesn't mean that the connection is closed, but that the object relative to the connection is closed (it could be a Statement or a ResultSet).
It's difficult to see from your example, since it has been trimmed/re-arranged, but it looks like you may be trying to use a ResultSet after having re-used its corresponding Statement. See the documentation:
By default, only one ResultSet object per Statement object can be open
at the same time. Therefore, if the reading of one ResultSet object is
interleaved with the reading of another, each must have been generated
by different Statement objects. All execution methods in the Statement
interface implicitly close a statment's current ResultSet object if an
open one exists.
In your example, it may be because autoCommit is set to true by default. You can override this on the java.sql.Connection class. Better yet is to use a transaction framework if you're updating multiple tables.

Categories

Resources