Dynamic access to MySQL database in Java - java

I am looking for some way how to access MySQL database more dynamically.
For example, I want to insert some text to my table.
I have some method called insert() which is called approximately every half of the second and does the insert stuff.
The code looks like this:
public void insert(String string) {
Class.forName("com.mysql.jdbc.Driver").newInstance();
java.sql.Connection conn = java.sql.DriverManager.getConnection(...);
java.sql.Statement stat = conn.createStatement();
stat.executeUpdate("INSERT INTO mytable (mytext) VALUES ('"+ string +"')");
conn.close();
}
But I really think this could cause many problems because it is opening and closing connections too often.
So isn't there any way to open some "MySQLStream" to the database and print the data to it without opening and closing the connection again and again?
Thanks for your replies.

Create a Connection object at the beginning of the program, and use it for every query. Close it only at the end of the program.
Oftentimes one Connection is good, so you may declare it as static.
public static java.sql.Connection conn;
public static void buildConnection()
{
Class.forName("com.mysql.jdbc.Driver").newInstance();
conn = java.sql.DriverManager.getConnection(...);
}
public void insert(String string)
{
java.sql.Statement stat = conn.createStatement();
stat.executeUpdate("INSERT INTO mytable (mytext) VALUES ('"+ string +"')");
}
In the program, you may do the following:
buildConnection();
...
insert("....");
insert("....");
...
conn.close();

Related

How to use PreparedStatement with JDBC

I'm new to JDBC and Java.
I'm coming from Javascript and Typescript background. I decided to learn JDBC with Oracle by creating a small basic project.
I'm using JDK 8. I'm following this study material: TutorialsPoint-PreparedStatement. I figured out that problem is with my DataService.
Here's my DataService class:
import java.sql.*;
import java.util.logging.Level;
import java.util.logging.Logger;
public class DataService {
Connection con;
PreparedStatement pstmt;
static String branch_name="";
static LocalDate branch_created_on;
static String branch_pulled_from="";
DataService() {
try {
Class.forName("oracle.jdbc.driver.OracleDriver");
con=DriverManager.getConnection("jdbc:oracle:thin:#localhost:1521:xe","system","scott");
}
catch(Exception e){
System.out.println(e);
}
}
public void getValue() {
branch_name=AddNewBranchRecord.branchNameTextField.getText();
branch_created_on=AddNewBranchRecord.datePicker1.getValue();
branch_pulled_from=(String) AddNewBranchRecord.combo_box_1.getValue();
}
public void putValue() {
System.out.println("Branch name: "+branch_name);
System.out.println("Branch created on: "+branch_created_on);
System.out.println("Branch pulled from: "+branch_pulled_from);
}
public void insertRecord() {
System.out.println("Adding a record...");
getValue();
try {
String sql;
sql = "insert into mybranches values (branch_name, branch_created_on, branch_pulled_from);";
pstmt = con.prepareStatement(sql);
} catch (SQLException ex) {
Logger.getLogger(DataService.class.getName()).log(Level.SEVERE, null, ex);
}
pstmt .close();
}
}
I'm sure there's something that I missed out.
I'm not getting any error or exception but no row is inserted in the database.
I cross checked with select * from mybranches.
However, the same code works perfectly if I use the normal Statement.
You create the PreparedStatement but you don't use it.
A prepared statement is there to e.g. insert different values into a table multiple times.
You create the PreparedStatement once like you would execute a normal Statement and include ? instead of the values that differ.
If you want to execute it, you have to set the values (the ?s will be replaced with them) by using the setXXX(int,Type) methods and then execute it with .execute().
As pointed out in the comments of the question, the SQL code is not valid. The sql code prepared statement is just like the sql code of a regular statement but the values that change all the time are replaced by ?.
The SQL code of the prepared statement would be something like that:
INSERT INTO mybranches VALUES (?,?,?)
If you want to use the PreparedStatement, you could set the values like that:
pstmt.setString(1,branch_name);
pstmt.setObject(2,branch_created_from);
pstmt.setString(3,branch_pulled_from);
Finally, execute it with
pstmt.execute();
Note that (as I already said) you should create the PreparedStatement once and not every time you execute the insertRecord() method and in that method, you should just call the setXXX methods and the execute() method.
The PreparedStatement (and the Connection object) should be closed when you don't need it anymore.
Also, as #TT. suggests in the comments, you should specify the columns in an INSERT statement. It would be something like
INSERT INTO mybranches (name,createdFrom,pulledFrom) VALUES (?,?,?)

MySQL not pushing insert into database with netbeans

Recently I'm just learning some HTML, JSP and servlets for a university project, the thing is that I made a database into MySQL Workbench with id primary key, auto increment , then some fields like username, password, firstname, lastname, and so on.
The goal is to make a login page and register page, for some reason if I push data with MySQL Workbench into the database it will let me retrieve it with my login form and my select statment, but for some reason I'm doing the same thing with register but in this case with the query INSERT.
So, after research, I did preparestatment and changed the executeQuery to executeUpdate and everything, but my log says a nullPointerException somewhere, I know it may be a simple and silly error that I'm not seeing, but I'm new at this. This is what U have made so far to insert data into my database:
public static UserBean registarUsuario(UserBean bean){
//preparing some objects for connection
Statement stmt = null;
ResultSet rs = null;
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException ex) {
System.out.println("Error al cargar el driver");
System.out.println(ex.getMessage());
}
String firstname = bean.getFirstName();
String lastname = bean.getLastName();
String username = bean.getUsername();
String password = bean.getPassword();
boolean admin = bean.isAdmin();
int tipo = bean.getType();
String insertQuery =
"insert into idusuario (firstname,lastname,username,password,admin,tipo) values ('"+firstname+"','"+lastname+"','"+username+"','"+password+"','"+admin+"','"+tipo+"')";
System.out.println("Firstname is " + firstname);
System.out.println("Surname is " + lastname);
System.out.println("Query: "+insertQuery);
try
{
//connect to DB
currentCon = DriverManager.getConnection("jdbc:mysql://localhost:3306/usuarios", "root", "admin");
rs = stmt.executeQuery(insertQuery);
...
My output:
Info: Query: insert into idusuario
(firstname,lastname,username,password,admin,tipo) values
('jhon','marston','jmar','123','true','0') Info: Error :
java.lang.NullPointerException
The thing is that Netbeans doesn't even tell me where the NPE is happening so I'm kind of confused, I don't know if the query is wrong or if something else is, because as I can see in my output, the query seems ok.
I leave you here my database structure
You are assigining the stmt as null and never initializing it.
Statement stmt = null;
ResultSet rs = null;
Then you are trying to use it:
rs = stmt.executeQuery(insertQuery);
You will need to do something like this before you use it:
PreparedStatement stmt=currentCon.prepareStatement(yourQuery);
So, after research, i did preparestatment and changed the executeQuery
to executeUpdate and everything, but my log says a
nullPointerException somewhere, i know it may be a simple and silly
error that im not seeing, but understand that im new at this. this is
what i have made so far to insert data into my database
When we use insert,update or delete we need to use executeUpdate.
When we use select we need to use executeQuery.
In your example you are doing executeQuery for an insert. This is wrong. You need to use this:
rs = stmt.executeUpdate(insertQuery);
You're getting a NPE because you are trying to retrieve the results where there are none.
Here is a nice thing to do to help you reduce boilerplate code... (so you don't have to keep repeating yourself with db initialization values)
Create a class for your database connection:
public class DBConnection {
private static String url = null;
private static Connection conn = null;
public static Connection getConnection(){
try{
Class.forName("com.mysql.jdbc.Driver");
url = "jdbc:mysql://localhost:3306/usuarios";
conn = DriverManager.getConnection(url,"root","admin");
} catch (Exception e) {
System.out.println(e);
}
return conn;
}
}
Now you can use this in all your other classes like this:
public static UserBean registarUsuario(UserBean bean){
try(Connection conn= DBConnection.getConnection()){
PreparedStatement pst = conn.prepareStatement("insert into idusuario (firstname,lastname,username,password,admin,tipo) values (?,?,?,?,?,?);");
pst.setString(1, bean.getFirstName());
pst.setString(2, bean.getLastName());
pst.setString(3, bean.getUserName());
pst.setString(4, bean.getPassword());
pst.setBoolean(5, bean.isAdmin());
pst.setInt(6, bean.getType());
pst.executeUpdate();
}catch (SQLException e) {
e.printStackTrace();
}
}

invalid column index error in java while fetching data from oracle 10g database. Cant figure out whats wrong

Code snippet:
On a button click, actionevent will be called
public void actionPerformed(ActionEvent e)
{
Function f = new Function();
Function is a nested class which i have used to establish the connection with the database.
The code snippet for function class is also provided in the end.
ResultSet rs = null;
String Cid ="cust_id";
String Pno="cust_phone";
String cat="cust_cat";
String start_date="st_date";
String Adv_amt="adv";
String Adv_end="end_date";
String Address="addr";
t2 is the Textfield name which i have used to get entry of customer name. I want to use this customer name as a PK to fetch all the other data about that customer from DB.
rs=f.find(t2.getText());
try{
if(rs.next())
{
t1.setText(rs.getString("cust_id"));
t3.setText(rs.getString("cust_phone"));
t4.setText(rs.getString("cust_cat"));
t5.setText(rs.getString("st_date"));
t6.setText(rs.getString("adv"));
t7.setText(rs.getString("end_date"));
t8.setText(rs.getString("addr"));
}
else
JOptionPane.showMessageDialog(null,"No data for this name");
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null,ex.getMessage());
}
}
Here is the code snippet for nested class Function which is inside the main class:
class Function{
Connection con=null;
ResultSet rs= null;
PreparedStatement ps = null;
public ResultSet find(String s)
{
try
{
DriverManager.registerDriver(new oracle.jdbc.driver.OracleDriver());
con = DriverManager.getConnection("jdbc:oracle:thin:#Localhost:1521:xe","system","qwerty");
ps= con.prepareStatement("Select * from gkkdb where cust_name='?'");
ps.setString(1,s);
rs= ps.executeQuery();
}
catch(Exception ex)
{
JOptionPane.showMessageDialog(null, ex.getMessage());
}
return rs;
}
}
Please help figure out the problem.
Don't put the parameter placeholder ? in single quotes.
This:
ps = con.prepareStatement("Select * from gkkdb where cust_name='?'");
should be
ps = con.prepareStatement("Select * from gkkdb where cust_name = ?");
The ? is not recognized as a placeholder if you enclose it in single quotes.
Sorting out the bind variable will fix your immediate issue.
You should explicitly specify what columns you want selected and that way you'll only get what you need (someone might add a BLOB column later) and you'll get them in the right order (someone might change the table create script before running on another DB instance, although you are looking up the columns by name, a different order would only impact if you were using positional indexes).
Ditto on the other answer re: bind variables (i.e. no quotes)
Plus, "select * from" is never a good idea, ask your DBA.
Obviously your code is for example, but you should make sure you free up any resources (Connection, Statement, ResultSet) as soon as they are done with. Use Java 7 try-with-resources.

Oracle JDBC Driver ResultSet PreparedStatement Throws ORA-009900 invalid SQL statement Exception

I am using Oracle JDBC Driver ojdbc6.jar. When executing a PreparedStatement the ResultSet is returned. However when trying to get details back of what has been saved, I am unable to get this and it throws an Exception.
Below is the code:
public Processor {
private Connection connection;
public Processor() throws Exception {
connection = DriverManager.getConnection(url, username, password);
}
public int saveData(String name) throws Exception {
PreparedStatement preparedStatement = connection.prepareStatement(name);
preparedStatement.setString(1, name);
ResultSet resultSet = preparedStatement.executeQuery();
resultSet.next();
String row = resultSet.getString("NAME");
return resultSet.getRow();
}
public static void main(String[] args) throws Exception {
Processor processor = new Processor();
int row = processor.saveData(new String("INSERT INTO NAMES (name) VALUES (nameTable)"));
}
}
The url, username and password are setup but not shown in the code. I can connect to the Oracle database and persist the data. However, the problem arises when calling resultSet.getString("NAME"). The following Exception is shown:
ORA-009900: invalid SQL statement
java.sql.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
When executing the following code:
ResultSet resultSet = connection.createStatement().executeQuery("SELECT NAME FROM NAMES"));
resultSet.next();
String name = resultSet.getString("NAME");
This works. I have also executed in the SQL describe NAMES and the name attribute is displayed as NAME.
The issue is something to do with the PreparedStatement object returning the ResultSet data.
Any ideas?
EDIT:
ORA-00900: invalid SQL statement
java.sql.SQLSyntaxErrorException
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:447)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:389)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:382)
at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:675)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:513)
at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:227)
at oracle.jdbc.driver.T4C8Odscrarr.doODNY(T48COdscrarr.java:98)
at oracle.jdbc.driver.T4CPreparedStatement.doDescribe(T4CPreparedStatement.java:818)
at oracle.jdbc.driver.OracleStatement.getColumnIndex(OracleResultSetImpl.java:3711)
at oracle.jdbc.driver.OracleResultSetImpl.findColumn(OracleResultSetImpl.java:2799)
at oracle.jdbc.driver.OracleResultSet.getString(OracleResultSet.java:498)
at com.example.ProcessorTest.testExecuteInsert(ProcessorTest.java:14)
Your saveData method is the cause because an INSERT does not produce a ResultSet, so executeQuery will produce an error, as there will be no ResultSet.
Also you should only use connection.prepareCall(String) for executing stored procedures, not for other types of statements. For a prepared statement you should use connection.prepareStatement(String).
Change your code to:
public int saveData(String name) throws Exception {
PreparedStatement preparedStatement = connection.prepareStatement(name);
preparedStatement.setString(1, name);
return preparedStatement.executeUpdate();
}
BTW: I hope you are aware that this method uses the parameter name both for the query and as the parameter for the query (which really does not make a lot of sense).
And finally, the new String(...) you do in your main is totally unnecessary.
First of all this line of code
int row = processor.saveData(new String("INSERT INTO NAMES (name) VALUES (nameTable)"));
As you have specified that the method saveData() takes argument as String so there is no need of any new String(...) here and moreover you are using PreparedStatement so you can use parameterized query something like this
int row = processor.saveData("INSERT INTO NAMES (name) VALUES (?)");
Then you can use this statement in saveData()
preparedStatement.setString(1, "name");
Finally you are updating the table not quering it so change this
preparedStatement.executeQuery();
to
return preparedStatement.executeUpdate();
One more thing you should be very specific about your method name. You should always name a method based on what it is going to do. Like saveData() here must be used only for saving data not querying the data as you were trying to do by using the ResultSet. If you want to retrieve the data then use some other method.

Java IDE 7.1 to MS SQL 2005 Using PreparedStatement...wheres the return?

I have been toiling with this issue all day.
After reading the benefits between Statements(S) and PreparedStatements(PS) I decided to convert all my S's to PS's in Netbeans.
I was astounded to see that there were no errors but...no output from the execution of my code either.
import java.sql.*;
public class ViewingMySQL {
public static void main(String[] args) {
//Declare Variables
Connection con;
ResultSet rs;
Statement stmt;
String sqlappname;
PreparedStatement findAppID_lookup= null;
String findAppID_lookup_stmt="select app.ID as APPID"
+" from IntergraphIN_AppTranslation"
+" inner join app on app.unit=IntergraphIN_AppTranslation.UnitName"
+" where IntergraphIN_AppTranslation.IntergraphUnitName=(?)";
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection("jdbc:odbc:database","username","password");
sqlappname="'XXXY01'";
findAppID_lookup= con.prepareStatement(findAppID_lookup_stmt);
findAppID_lookup.setString(1, sqlappname);
rs = findAppID_lookup.executeQuery();
if(rs.next()){
System.out.println(rs.getInt("APPID"));
}
rs.close();
findAppID_lookup.close();
}
catch(Exception e){
System.err.println(e);
}
}
}`
When the above code executes and builds...without output.
run:
BUILD SUCCESSFUL (total time: 1 second)
What I had originally was:
import java.sql.*;
public class ViewingMySQL {
public static void main(String[] args) {
//Declare Vars
Connection con;
ResultSet rs;
Statement stmt;
String sqlappname;
try{
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
con = DriverManager.getConnection("jdbc:odbc:Database","username","password");
sqlappname="'XXXY01'";
stmt = con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rs = stmt.executeQuery("SELECT ID FROM app where AppName="+sqlappname);
if(!rs.isBeforeFirst()){
rs.close();
rs = stmt.executeQuery("select app.ID from IntergraphIN_AppTranslation"
+" inner join app"
+" on app.unit=IntergraphIN_AppTranslation.UnitName"
+" where IntergraphIN_AppTranslation.IntergraphUnitName="+sqlappname);
}
if(rs.next()){
System.out.println(rs.getInt(1));
}
rs.close();
stmt.close();
con.close();
}catch(Exception e){
System.err.println(e);
}
}
}`
This code outputs:
run:
2020603
BUILD SUCCESSFUL (total time: 1 second)
The Int that you see above is the ID of the column that I'm looking for.
Can someone please help me with understanding what I'm doing...is it the formatting of the variable that I'm passing into the PS?
Thanks,
SCorliss
Change this:
sqlappname="'XXXY01'";
to this:
sqlappname="XXXY01";
UPDATE re comments:
PreparedStatements have multiple benefits. For example:
it can help protect from sql injection: the input is bound to a variable, the input is not used to create the statement
the rdbms can probably make use of statement caching if only the bind variables change (rather than changing the sql statement itself)
the statements can be a lot easier to read: you don't have to mess around with quoting quotes etc
In this case it seems the meaning of the quoting became confused. In the original: sqlappname="'XXXY01'", the double quote was to declare the java String, the single quote the sql string. In the prepared version: sqlappname="XXXY01", we are just saying "this is the String to bind" and we specifiy on the prepared statement that our bind is going to be a String.

Categories

Resources