Please suggest me the piece of code for deleting a row from a mysql database that contains three columns problemid, problem and solution.
I want to delete it from a browser i.e. it is a web application.
You may consider using JDBC (Java Database Connectivity) API for your problem. I recommend you to take a close look at the following simple tutorials about developing Java Web Applications Using a MySQL Database.
https://blogs.oracle.com/JavaFundamentals/entry/creating_a_simple_web_application
http://www.javaguicodexample.com/javawebmysqljspjstljsf5.html
Here is a sample Servlet.
But please remember this is just to show you how to do it, you SHOULD NOT use this in a productive system!This is more for demonstration, look at it how and learn how to do it.
This servlet should run fine, but there are some things you have to do!
Anyway you should read these documents, if you haven't already done it
http://docs.oracle.com/javaee/5/tutorial/doc/bnadp.html
http://docs.oracle.com/javase/tutorial/jdbc/basics/index.html
Things which i havent taken into account, while i wrote this:
Request Parameters
If one of the request parameters cannot be found, it will throw an Exception. You need a better way of handling with this situation.
Connection Pooling
This example will open a connection to the database on EVERY request. Opening a connection costs time. Therefore everyone use a connection pool. This library/server opens a specified amount of connections to the database. Everytime you need to access the database you fetch it from this pool and if you're finished you return it to the pool.
Security
Someone who knows the address of this servlet, could easily use it to delete any row in your table. This is your job to secure it.
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
import java.sql.*;
/**
* DON'T USE IN PRODUCTION, JUST FOR LEARNING PURPOSES
**/
public class MySqlServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
long problemId;
long problem;
long solution;
Object problemIdAsObject = request.getParameter("problemId");
Object problemAsObject = request.getParameter("problem");
Object solutionAsObject = request.getParameter("solution");
if ( problemIdAsObject == null ){
throw new ServletException("problemId has not been specified!");
}
if ( problemAsObject == null ){
throw new ServletException("problem has not been specified!");
}
if ( solutionAsObject == null ){
throw new ServletException("solution has not been specified!");
}
problemId = Long.valueOf( (String)problemIdAsObject );
problem = Long.valueOf( (String)problemAsObject );
solution = Long.valueOf( (String)solutionAsObject );
PreparedStatement statement = null;
Connection connectionToDatabase = null;
try{
connectionToDatabase = getConnection();
String sql = "DELETE FROM table WHERE problemid = ? and "+
"problem = ? and solution = ?";
statement = connectionToDatabase.prepareStatement(sql);
statement.setLong(1,problemId);
statement.setLong(2,problem);
statement.setLong(3,solution);
statement.execute();
}catch( SQLException sqle ){
throw new ServletException(sqle);
}catch( ClassNotFoundException cnfe ){
throw new ServletException(cnfe);
}finally{
try{
statement.close();
connectionToDatabase.close();
}catch( SQLException sqle ){
throw new ServletException(sqle);
}
}
response.setContentType("text/html");
PrintWriter out = response.getWriter();
out.println("<HTML>");
out.println("<BODY>");
out.println("OK");
out.println("</BODY></HTML>");
}
private Connection getConnection()
throws ClassNotFoundException,SQLException{
String userName = "user";
String password = "password";
String databaseName = "database";
String serverAddress = "localhost";
String connectionString = "jdbc:mysql://"+serverAddress+"/"+databaseName+
"?user="+userName+"&password="+password;
//If this line is not working, use this instead:
//Class.forName("com.mysql.jdbc.Driver").newInstance();
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection(connectionString);
return connection;
}
}
It's so simple buddy, first of all you have to make a link to any servlet from jsp. And with that link you have to pass the deleted record id as parameter & write the code inside servlet for deleting the given row from database. And then return that same page where the previous link you have clicked.
Related
I'm using google app engine JAVA 8 and servlet 3.1 and would like to use HikariCP for pooling.
I'll write my logic in pseudo-code for better understanding.
At this point when user connects to a servlet it creates a new connection to database every time.
so my servlet looks a bit like this
doGet(){
DatabaseObject db = new DatabaseObject()
Connection conn = db.getConnection()
db.createTable(conn)
db.readData(conn)
...
conn.close()
}
Now I've seen many pooling examples like this one
but first I'm not sure this is what I'm trying to achieve also I don't really understand the whole process
Any examples, explanations are welcome as I've tried searching the net and couldn't find some for servlets. So maybe I'm thinking the wrong direction
That example looks like it stores the pool in the app (servlet) context.
I've done it differently. Usually I create a class, call it MyDb. Then I add various methods to it to access data. Within it there is a getConnection() method.
Internally, MyDb has its own connection pool. getConnection() simply returns a connection from the pool. The pool is initialized when the first MyDb is created.
Something like this (this is for app engine so no port is specified):
private static DataSource pool = null;
public MyDb( String dbhost, String dbdsn, String dbuid, String dbpwd )
{
try
{
if( MyDb.pool == null )
{
String dbconn = null;
String dbclassname = null;
HikariConfig config = new HikariConfig();
dbconn = "jdbc:google:mysql://" + dbhost + "/" + dbdsn;
dbclassname = "com.mysql.jdbc.GoogleDriver";
config.setJdbcUrl( dbconn );
config.setUsername( dbuid );
config.setPassword( dbpwd );
MyDb.pool = new HikariDataSource( config );
}
catch( Exception e )
{
logger.error( e.getMessage() );
}
}
protected Connection getConnection() throws Exception
{
return pool.getConnection();
}
}
I use wildfly-8.2.0.Final. There is connection pool (Oracle) on this server.
Look at following code:
public ArrayList<HashMap<String, Object>> fetchSome(String query)
throws OracleQueryProcessorException {
ArrayList<HashMap<String, Object>> result = new ArrayList<HashMap<String, Object>>();
try {
Context initCtx = new InitialContext();
DataSource ds = (DataSource) initCtx.lookup(driver);
try (Connection con = ds.getConnection();
PreparedStatement stmt = con.prepareStatement(query)) {
try (ResultSet rs = stmt.executeQuery()) {
ResultSetMetaData rsmd = rs.getMetaData();
rs.next();
HashMap<String, Object> row = new HashMap<String, Object>();
String name = rsmd.getColumnName(1);
Object value = rs.getObject(1);
if (value instanceof Blob) {
Blob bl = (Blob) value;
if (bl.length() > 0)
value = bl.getBinaryStream();
else
value = null;
}
row.put(name, value);
result.add(row);
}
} catch (SQLException e) {
throw new OracleQueryProcessorException();
}
} catch (NamingException e) {
throw new OracleQueryProcessorException();
}
return result;
}
And this is usage of this function:
InputStream is = (InputStream) fetchSome("SELECT BLOB_FIELD FROM TEST WHERE ID = 1").get(0).get("BLOB_FIELD");
if (is != null) {
byte[] a = new byte[3];
is.read(a);
}
Reading from this stream is working!! How can it work? Connection is closed (cause using try-with-resources clause). Reading from this stream take no connection from pool (All pool's connections are available).
fetchSome() opens a Connection, sends the query, and then reads the data back into the resulting ArrayList. Then fetchSome closes the Connection and returns the ArrayList. The code you are curious about then reads from the ArrayList that was returned, not from the Connection that was, as you correctly noticed, closed.
By the time your method returns, all database communication has finished, and all the data has been copied into the returned list, from which it can then be read as often and as late as you want, without needing a Connection again.
Does it really work for various BLOB sizes? Good thresholds are:
4000B (limit where BLOB might be in lined in the row - not stored aside)
2000B (maximum size for RAW) - BLOB can be casted to RAW somewhere
16KB, 32KB
some huge value bigger than JVM heap size
AFAIK on OCI level(C client library) LOBs might be "pre-allocated" .i.e. some smaller portion of BLOB can be sent to client, although it was not requested yet by the client. This should reduce number of round-trips between database and client.
Also you should try check v$instance view to check whether the connection really was closed. Cooperation between JDBC and Oracle is tricky sometimes.
For example temporary LOBs created via Connection.createBLOB() are treaded differently than any other temporary lobs by the database. I think it is because Oracle database can not talk to JVM GC and it does not know when really the java instance was disposed. So these lobs are kept in the database "forever".
I am trying to learn how you would tackle the task of creating a Java console application, connect to a (in this case) MySQL DB and send or retrieve data, without showing your username and password in the source code of the Java application. I currently have no trouble
creating a connection showing credentials.
// JDBC driver name and database URL
private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private static final String DB_URL = "jdbc:mysql://192.168.1.159:3306/javahelper";
// Database credentials
private static final String USER = "xxxx";
private static final String PASS = "RandomString";
/**
* #return
*/
public Connection openConnection() {
Connection connection = null;
try {
Class.forName(JDBC_DRIVER);
// opening connection
connection = (Connection) DriverManager.getConnection(DB_URL,USER,PASS);
} catch (ClassNotFoundException e) {
System.out.println("This is from openConnection method");
e.printStackTrace();
} catch (SQLException f) {
System.out.println("This is from openConnection method");
f.printStackTrace();
}
return connection;
}
From what information I can gather you always need to show your credentials somewhere in the application. But how do you than achieve "safe" connection between a application and a DB, so others can't misuse your credentials for malicious reasons?
one way of doing it is using a properties file having your credentials or having your data in a xml file.
create a properties file like the one below
// database.properties
DB_URL=jdbc:mysql://localhost:3306/UserDB
DB_USERNAME=user_name
DB_PASSWORD=password
Use this information in your code to get the username and passwords.
Properties properties= new Properties();
FileInputStream input = null;
try{
input = new FileInputStream("database.properties");
props.load(input );
con = DriverManager.getConnection(props.getProperty("DB_URL"),props.getProperty("DB_USERNAME"),props.getProperty("DB_PASSWORD"));
}
you can use encrypt the username and password.The best opensource encryptor(My personal view) is jbcrypt
// Hash a password for the first time
String hashed = BCrypt.hashpw(password, BCrypt.gensalt());
// gensalt's log_rounds parameter determines the complexity
// the work factor is 2**log_rounds, and the default is 10
String hashed = BCrypt.hashpw(password, BCrypt.gensalt(12));
// Check that an unencrypted password matches one that has
// previously been hashed
if (BCrypt.checkpw(candidate, hashed))
System.out.println("It matches");
else
System.out.println("It does not match");
Sharing what i find
Creating and using the propertise file
I created a database.properties file(normal text file) and placed it in the src folder of the Java project.
JDBC_DRIVER=com.mysql.jdbc.Driver
USER=YourUser
PASS=YourPassword
DB_URL=jdbc:mysql://IP:PORT/DB
Afterwards i edited my openConnection() method to use the properties file for loading the credientials of the connection.
public Connection openConnection() {
Properties properties = new Properties();
Connection connection = null;
String path = System.getProperty("user.dir");
path += "/src/database.properties";
try(FileInputStream fin = new FileInputStream(path);) {
properties.load(fin);
try {
Class.forName(properties.getProperty("JDBC_DRIVER"));
// opening connection
connection = (Connection) DriverManager.getConnection(properties.getProperty("DB_URL"),properties.getProperty("USER"),properties.getProperty("PASS"));
} catch (ClassNotFoundException e) {
System.out.println("This is from openConnection method");
e.printStackTrace();
} catch (SQLException f) {
System.out.println("This is from openConnection method");
f.printStackTrace();
}
} catch (IOException io) {
System.out.println("This is from openConnection method");
io.printStackTrace();
}
return connection;
}
Sending username and password, Java application -> MySQL
From what i can read on the web, it dosent matter much if you encrypt or hash the password before you send it towards the sequel service from your Java application. An example i found is that the sequel service dosent have a "receive hash method and authenticate". And even if it did the hash would need to be in the program somewhere. And when the program has access to it, others also have access to it if they really want it. Also if the hash is whats needed to authenticate than your back to where you can just as well use the clear text password.
The discussion than ends on "what is the best approach". Some suggest a keyserver / auth system in between the application and sequel service, using a datastore setup on the server side, using the OS "wallet" (example Windows registry) or creating a database user with minimum permissions to just get the job done / or a read only DB "read_only=1 in my.cnf".
I tried the 3'rd option and created a "DBaccess" user, with only the select permission to retrieve data, no administrative rights and random generated password by MySQL.
I'm using the tutorial at http://www.vogella.com/tutorials/MySQLJava/article.html
to try tp connect to my sql server on my server
When it executes the line:
Connection connect = DriverManager
.getConnection("jdbc:mysql:http://www.findmeontheweb.biz"
+ "user=findmeon_bitcoin&password=PASSWORD");
an exception gets thrown saying "No sutabled driver found for jdbc:mysql:http://www.findmeontheweb.biz
This is what I did
1. Downloaded the "mysql-connecter-java-5.1.33.bin.jar into my lib folder
2. added the jar to my project from preferences.
project code:
public class cStart {
private Connection connect = null;
private Statement statement = null;
private PreparedStatement preparedStatement = null;
private ResultSet resultSet = null;
public static void main (String[] args) {
int g=0;
try {
// this will load the MySQL driver, each DB has its own driver
Class.forName("com.mysql.jdbc.Driver");
// setup the connection with the DB.
// EXCEPTION GOES OF HEAR
Connection connect = DriverManager
.getConnection("jdbc:mysql:http://www.findmeontheweb.biz"
+ "user=findmeon_bitcoin&password=PASSWORD");
} catch (Exception e) {
System.out.println("Exception...." );
}
}
}
The URL format should be look like this
jdbc:mysql://hostname/ databaseName
I think this is a much cleaner way to do it:
String URL = "jdbc:URL_TO_YOUR_DATBASE";
String USER = "username";
String PASS = "password"
Connection conn = DriverManager.getConnection(URL, USER, PASS);
As seen here: http://www.tutorialspoint.com/jdbc/jdbc-db-connections.htm
I say give that link a try with your driver. You also should make sure you have the actual jar for MySQL. It really might be invalid.
I would try the one here: http://www.java2s.com/Code/Jar/c/Downloadcommysqljdbc515jar.htm
And then add that to your project.
The URL to the database might be wrong.
If yes you should specify a correct one with including database name.
Else verify if the jdbc driver jar is added in the build-path, if yes try to put it in the lib folder of your webapp.
I am trying to get a connection to a SQLite database (using Eclipse on Windows 8). Everything workes fine as long as the path name doesn't contain any special characters (like "é"). I tried to convert it to UTF-8 (because I read on http://www.sqlite.org/c3ref/open.html that it should be), but it didn't work. I get an "out of memory" exception (SQLException) what means that no database file was found.
This is the code summary of what I did:
public static String DB_PATH = "jdbc:sqlite:" + System.getProperty("user.home") + "<Rest of the path><databasename>.sqlite";
public static void main(String[] args) throws ClassNotFoundException
{
// load the sqlite-JDBC driver using the current class loader
Class.forName("org.sqlite.JDBC");
Connection connection = null;
try
{
// create a database connection
connection = DriverManager.getConnection(DB_PATH);
Statement statement = connection.createStatement();
statement.setQueryTimeout(30); // set timeout to 30 sec.
// work with the database ...
}
}
catch(SQLException e)
{
// if the error message is "out of memory",
// it probably means no database file is found
System.err.println(e.getMessage());
}
finally
{
// try to disconnect
// ...
}
Thanks for your help!
Use the latest lib from http://www.xerial.org/maven/repository/artifact/org/xerial/sqlite-jdbc/