The traditional approach is to have a DAO (Data Access Object) for each data class.
I.e. if you have a data class "Person" you also have a class "PersonDAO" that implements methods like findById(), findAll(), save(Person) etc. Basically the DAO class handles all the DB interaction.
The constructor of the DAO class could simply accept a Connection object and thus externalize the problem of creating connections or it could invoke a factory method somewhere that doled out a Connection object.
In either case you'll likely want to have such a factory method.
public class Database{
public static Connection getConnection(){
// Create a new connection or use some connection pooling library
}
}
As someone pointed out java.sql.Connection is not thread safe so you should not hand out the same connection each time unless you are sure that multiple threads will not be accessing the method.
Of course if you need to create a new connection for each call you'll also need to close the connections once you're done with them. The simple approach is to add a close() method to the DAOs and have them take care of it. This does impose a burden on the code using the DAO.
Even if you use connection pooling it is still necessary to close the connections (return to the pool) once you are done with them.
Some one suggested using Thread local to have a per thread connection. This works in some instances, but wouldn't be useful for a web application where each request is a new thread (that is never reused, might as well not store a reference).
You could however take advantage of this in a webapp if you've configured it so that after handling each request a call is made to Database.closeConnection() which then takes care of closing a Tread local connection if one exist.