How to retrieve the password from a java.sql.Connection object - java

I'm looking for a way to get the password from a java.sql.Connection object. I know there's a getUserName() method in the DatabaseMetaData object, but unfortunately no corresponding getPassword() method. Using the debugger in Netbeans I can see a field for the password, so there must be a way to get this information using reflection, but thus far I've been unable to figure out how.

As I commented, the only way must be looking into the code. For instance, for MySQL using the latest driver (5.1.15). You can get the password like this:
public static void main(String[] args) throws Exception{
ConnectionImpl con = (ConnectionImpl) DriverManager.getConnection("jdbc:mysql://localhost:3908/mydb?user=edalorzo&password=mandrake");
System.out.println(con.getProperties().get("password"));
con.close();
}
But for this, you would need to know the class hierarchy and its implementation details.
Other databases most probably will be different. If your database is open source, like MySQL you can know the details of the inner construction and find ways to retrieve the password.

It is up to the implementer of the JDBC to provide that since the user and password are being passed in as a Map to the Driver.
One way to know what the Password is, is to extend the driver and include that.
class CustomDriver extends ImplementerDriver {
#Override
public Connection connect(String url, Properties info) throws SQLException {
super.connect(url, info);
// Extract password from info.
}
public String getPassword() {
....
}
}

You can parse the sever XML configuration file for the Connection Pool parameters, and get the password from there. sophisticated solution but it works.

Related

Java - properties as a static fields directly on class

I was trying to find out any info about that on google, but without any result.
Can someone please explain me, if there is any reason why we should load properties via config.properties, then declaring "Properties prop", then readinng it… instead of directly defining static fields as properties on some class (simpler and quicker i guess).
Public ConfigClass{
public static string SERVERNAME = "some hostname";
public static string USERNAME = "some username"
}
And then, just calling it inside code if we need that, e.g.
ConfigClass.SERVERNAME
I'm talking about simple scenarios, where i want to use simple properties like, servername, username, etc…
One advantage would be that you can change the values without having to recompile and re-deploy your code. Also, this might work for private projects but imagine you're a company with several customers where the values might be different for each customer.

EBeans alternative to find() in JPA

I was following the Play! Framework tutorial on creating a blog. They use JPA instead of EBeans and they use the find() function that extend from play.db.Jpa.Model . I am using EBeans and have extended with play.db.ebean.Model . However, when I use the find() function, it says that no such method exists. I have done some research and have looked here: http://www.playframework.com/documentation/2.0/api/java/play/db/ebean/Model.html
and here: http://www.playframework.com/documentation/2.0/api/java/play/db/ebean/Model.Finder.html
but there is no mention of a simple find() method (there are others such as findId() but I don't see how they can help). Is there an alternative I could use in the Model class? If not, are there any other classes that I could use easily?
EDIT:
The specific part I need to create is a connect() method in the User class. In the tutorial, this is described as:
In the User.java source, add the connect() method:
public static User connect(String email, String password) {
return find("byEmailAndPassword", email, password).first();
}
What other options do I have for this if I can't use find(). Will ebean.find() work?
I am aware of two methods of using find() method of the play.db.ebean.Model.
The first one goes like this:
User user = Ebean.find(User.class, id);
The second method would be something like this:
//define a Model.finder class in the User model class
//The first parameter would be the datatype of the id used, which is String in my case
public static Model.Finder<String,User> find = new Model.Finder<String,User>(String.class, User.class);
User user = User.find.byId(id);
Since your query fetches data based on two values, your code should look something like this:
User.find.where()
.eq("email", email).eq("password",password)
.findUnique();

Is there any way to use OrmLite with Postgres hstores?

We're currently using a PostgreSQL database and OrmLite. We now have a use case for using an Postgres hstore, but can't find any way of accessing that table through OrmLite. I'd prefer to avoid opening a separate database connection just to select and insert to that one table, but I'm not seeing any other options.
At the very least I'd like a handle to the existing connection OrmLite is using so I can reuse it to build a prepared statement, but I haven't found a way to get a java.sql.Connection starting from an OrmLite ConnectionSource.
I see that OrmLite has a JdbcCompiledStatement, but that's just a wrapper around a PreparedStatement and requires the PreparedStatement to be passed in to the constructor. (Not sure what the use case for that is.)
I've tried to use DatabaseConnection.compileStatement(...), but that requires knowledge of the field types being used and OrmLite doesn't seem to know what an hstore is.
I've tried to use updateRaw(), but that function only exists on an OrmLite dao that I don't have because the table I would link the dao to has a field type OrmLite doesn't recognize. Is there some way to get a generic dao to issue raw queries?
I get that hstores are database specific and probably won't be supported by OrmLite, but I'd really like to find a way to transfer data to and from the database using unsupported fields instead of just unsupported queries.
It sounds like ConnectionSource may actually be implemented by JdbcConnectionSource, and will likely return a JdbcDatabaseConnection. That object has a getInternalConnection method that looks like what you are looking for.
#Gray I submitted an ORMLite patch on SourceForge that can enables the "Other" data type. The patch ID is 3566779. With this patch, it's possible to support hstores.
Users will need to add the PGHStore class to their projects. The code for this class is here.
Users will also need to add a persister class as shown here:
package com.mydomain.db.persister;
import com.mydomain.db.PGHStore;
import com.j256.ormlite.field.FieldType;
import com.j256.ormlite.field.SqlType;
import com.j256.ormlite.field.types.BaseDataType;
import com.j256.ormlite.support.DatabaseResults;
import java.sql.SQLException;
public class PGHStorePersister extends BaseDataType {
private static final PGHStorePersister singleton = new PGHStorePersister();
public static PGHStorePersister getSingleton() {
return singleton;
}
protected PGHStorePersister() {
super(SqlType.OTHER, new Class<?>[] { PGHStore.class });
}
protected PGHStorePersister(SqlType sqlType, Class<?>[] classes) {
super(sqlType, classes);
}
#Override
public Object parseDefaultString(FieldType ft, String string) throws SQLException {
return new PGHStore(string);
}
#Override
public Object resultToSqlArg(FieldType fieldType, DatabaseResults results, int columnPos) throws SQLException {
return results.getString(columnPos);
}
#Override
public Object sqlArgToJava(FieldType fieldType, Object sqlArg, int columnPos) throws SQLException {
return new PGHStore((String) sqlArg);
}
#Override
public boolean isAppropriateId() {
return false;
}
}
Lastly, users will need to annotate their data to use the persister.
#DatabaseField(columnName = "myData", persisterClass=PGHStorePersister.class)
At the very least I'd like a handle to the existing connection OrmLite is using so I can reuse it to build a prepared statement...
Ok, that's pretty easy. As #jsight mentioned, the ORMLite ConnectionSource for JDBC is JdbcConnectionSource. When you get a connection from that class using connectionSource.getReadOnlyConnection(), you will get a DatabaseConnection that is really a JdbcDatabaseConnection and can be cast to it. There is a JdbcDatabaseConnection.getInternalConnection() method which returns the associated java.sql.Connection.
I've tried to use updateRaw(), but that function only exists on an OrmLite dao that I don't have ...
You really can use any DAO class to perform a raw function on any table. It is convenient to think of it as being an unstructured update to an DAO object's table. But if you have any DAO, you can perform a raw update on any other table.
find a way to transfer data to and from the database using unsupported fields instead of just unsupported queries
If you are using unsupported fields, then you are going to have to do it as a raw statement -- either SELECT or UPDATE. If you edit your post to show the raw statement you've tried, I can help more specifically.

Java: connecting to db to fetch data

I have a question regarding Java when fetching data from, lets say MySQL database. As of now I need to write quite a lot of redundant code when fetching data. And I wonder if there is a better way to do that.
E.g. I have an method which fetch data from a table A. The method for that will look something like this then
public void readDataBase() throws Exception {
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=sqluser&password=sqluserpw");
statement = connect.createStatement();
resultSet = statement
.executeQuery("select * from FEEDBACK.COMMENTS");
writeResultSet(resultSet);
} catch (Exception e) {
throw e;
} finally {
close();
}
}
I wonder if there's a better way to write a method such as this one. Because it gets quite ugly when you have to write code such as this, namely that you have to write those line to getConnection all the time in every method that fetch data from the database.
Use Spring, with MyBatis or spring-jdbc for data access instead of raw JDBC.
spring-jdbc is a library wrapping basic JDBC code where you can provide callbacks to specify how you want resultsets mapped to objects and such. Mybatis is a little higher-level, you specify your queries in an xml file.
With Spring the big win is you get declarative transactions so you have no code starting and committing transactions, you also get templates for data access objects, and setting up a connection pool is easy. And there are plenty of examples for how to put the pieces together.
At some point you're better off writing your own DAO which handles all the plumbing for you.
I would do different things depending on whether I am in a single threaded batch job or inside a container.
For single threaded batch job:
create just one connection and reuse it
create just one prepared statement and reuse it
optimize commit calls
For J2EE
use the container managed data source pool
Most of the times when you write a program working with a database you do not open a connection every time you want to do something with it. Instead you open a connection at the beggining of the program and then use it every time when accessing a database.
Take a look at this example (pseudocode!):
class Database {
private Connection conn;
public Database() {
connect();
}
private void connect() {
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(dbUrl);
}
public void close() {
conn.close();
}
private ResultSet readSth() {
statement = conn.createStatement();
return statement.executeQuery("select * from FEEDBACK.COMMENTS");
}
private void doSth() {
// do sth else with conn
}
}
You can create a class having static method there, that returns you an instance of connection like below:
import java.sql.*;
import java.util.Properties;
public class Getconnection{
private static final String dbClassName = "com.mysql.jdbc.Driver";
private static final String CONNECTION ="jdbc:mysql://127.0.0.1/dbUserData";
private static Properties p = new Properties();
public static Connection getConnection(){
p.put("user","root");
p.put("password","library");
try{
Class.forName(dbClassName);
Connection con=DriverManager.getConnection(CONNECTION,p);
return con;
}
catch(Exception ie){
ie.printStackTrace();
return null;
}
}
}
So that you do not need to create different instances of connection, and change only at one place if you want to...
I think you are suffering from basic code organization. For example, you should only create the connection once and then pass it around to whatever methods need it. Typically, people use connection pools so that only a certain number of connections ever exist to the db (because they are expensive) and a connection pool manager will loan them out as needed and keep track of their states. There are a few connection pool libraries in Java (Apache has one) but I have had good luck using: http://sourceforge.net/projects/c3p0/
I dont really like heavy ORMs such as Hibernate but I do I like MyBatis. It lets me wright SQL and doesnt inject itself all over my domain models: http://www.mybatis.org/java.html I think you would benefit greatly by having a Data Access Object layer (DAO). This layer abstracts out communication with your data so the layers above can just fetch collections of data without worrying about the underlying SQL it took to generate that list.
I've moved away from direct JDBC access since I started using ORM (eg. Hibernate).
Or why dont you have some publicly available static method to read from the db:
public ResultSet readDataBase(String query) throws Exception {
try {
Class.forName("com.mysql.jdbc.Driver");
connect = DriverManager
.getConnection("jdbc:mysql://localhost/feedback?"
+ "user=sqluser&password=sqluserpw");
statement = connect.createStatement();
return statement.executeQuery(query);
} catch (Exception e) {
throw e;
} finally {
close();
}
}
and you can have similar methods when you do update/delete, etc

fetching values from class

I am new to java. My problem is
I have created a class for all the database connections.Now i want to access that class methods in another class.So i have created an object of that class.
But when i am using that object to access the methods of database class it is showing the error that
"dbcon(object) cannot be resolved to a type"
I can't understand what is the issue.
Please help.
Make a valid reference.
The error you are getting is because your code which uses the class is not able to reference the class. If these classes are in different packages, you will need to add an import line to the top of the class you're working in to import the dbcon class.
You should also be aware that case matters. dbcon is not the same as DBCon. In Java, it is a standard that all class names should begin with uppercase letters and all variables with lowercase letters. So, the class dbcon is at the very least named improperly. This standard helps to identify and resolve problems like the one you're having before they ever happen.
Finally, I would highly suggest that you work with some sort of IDE like Eclipse. This software can make your development process much easier by helping you solve common problems like these through suggested steps.
Heres a working reference example. Look at your code if it is close or similiar (apart from class and methodnames):
package com.example.util;
// imports if required
public class MyConnection {
// attribute storing the real connection
Connection conn = null;
// constructor to create a connection
public MyConnection() {
this.conn = magicMethodToCreateConnection(); // to be implemented
}
// getter method for that connection
public Connection getConnection() {
return conn;
}
}
package com.example.application;
import com.example.util.*;
// more imports if required
public class ConenctionUser {
public static useConnection() {
MyConnection myConn = new MyConnection();
Connection conn = myConn.getConnecion();
// now we can use conn
}
}

Categories

Resources