In JDBC we use the
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver").newInstance();
method to load the object in memory. Then when we use the DriverManager class to get a connection to the Sql Server, the DriverManager automatically uses the appropriate drivers from the set of drivers loaded in memory. Can the DriverManager concept be compared with the Provider design pattern used in .net ? If not, then what exactly do we mean by
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver")
method and why don't we create the object of the sql server driver class using the new keyword ?
Class.forName("XXXDriver") invokes static block of XXXDriver.
Usually the static block invokes DriverManager.registerDriver(new XXXDriver()) to register itself to DriverManager.
Something like:
public class XXXDriver implements Driver{
static{
//Be invoked by Class.forName("XXXDriver")
DriverManager.registerDriver(new XXXDriver())
}
...
}
Unfortunately I don't know about the provider pattern in .Net. But here is what that Class.forName() magic is for.
You don't instantiate the class via newInstance(). forName() is enough. (Ok, I see the reason for instance creation in BalusC's answer.)
The JDBC specification mandates that every JDBC driver registers itself with DriverManager.registerDriver(). This is done via a static block that gets executed when the class is loaded. Class loading is initiated via Class.forName().
Related
Here is some comparison of using DataSource and using DriverManager from https://stackoverflow.com/a/19674833/1224441
With JDBC, we can use an abstracted class, such as
java.sql.DataSource, which defines a database. However,
the MySQL DataSource and a Microsoft SQL DataSource are different
implementations. JDBC doesn't know which one you want to use.
So you use DriverManager to specify to JDBC that you want to use the
MySQL implementation, and you load that driver's class.
Say that later on you switch to Microsoft SQL. Now, all you have to do
is change the DriverManager to load the Microsoft SQL driver's class,
and all of your code that uses the abstract java.sql
classes will still work.
I found some examples of using DataSource and using DriverManager at http://zetcode.com/tutorials/jeetutorials/datasource/
But I don't see how different implementations (e.g. implementations by MySQL, and Microsoft SQL Server) would affect DataSource and DriverManager differently. Or do I misunderstand something?
When you acces you database with JDBC, you will handle java.sql.Connection, java.sql.Resultset... which are interfaces. You will actually use implementations that are specific to your database.
That way most of the code you wrote for one database can be used with another one and you don't have to learn a new API each time you need to access a new DB.
You need to specify first which implementations you need which are provided by the JDBC driver. You can do it with the old school DriverManager or with the now preferred DataSource.
DriverManager
The DriverManager is a concrete class. It isn't specific to any database. In summary it is just the place where you register your driver so you can get later all the specific implementations you need. It isn't specific by itself but it provides all the specific stuff you need.
Here is an excerpt from the example you mentioned with some of my comments.
final String url = "jdbc:mysql://localhost:3306/books";
//This line returns the Class of the Jdbc drive
//It will not be used but doing this will allow
//static initializations where it will register
//the driver to the DriverManager
Class.forName("com.mysql.jdbc.Driver");
//Here you get your connection implmentation
Connection con = DriverManager.getConnection(url, "root", "");
//MySQL specific Statement
Statement stmt = con.createStatement();
//MySQL specific ResultSet
ResultSet result = stmt.executeQuery("SELECT * FROM books");
The "trap" here is that the registration of the driver (to the DriverManager) is done during the static init done when you call the the Class.forName method.
For your information, here is the piece of code in com.mysql.jdbc.Driver doing the the driver registration in the init:
public class Driver extends NonRegisteringDriver implements java.sql.Driver {
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
DataSource
Using DataSource is more suitable for external configuration. DataSource is an interface and the implementation depends directly on the database.
In your example, the Driver implementation is specified in the web.xml file.
First we define the driver to be able to find it with JNDI
<database>
<jndi-name>jdbc/mysql</jndi-name>
<driver>
<type>com.mysql.jdbc.jdbc2.optional.MysqlConnectionPoolDataSource</type>
<url>jdbc:mysql://localhost:3306/books</url>
<user>root</user>
<password></password>
</driver>
<database>
And then we pass the reference to the servlet :
<servlet>
<servlet-name>datasource</servlet-name>
<servlet-class>com.zetcode.DataSourceExample</servlet-class>
<init>
<data-source>${jndi:lookup('jdbc/mysql')}</data-source>
</init>
</servlet>
That way, you had not to write any specific line of code. If you change your database, (in theory) you just have to change your configuration. Not the code.
Important notes
As Kayaman mentioned in the comments calling Class.forName is no longer needed since Java 6. All you need is having the driver in your classpath.
As a reminder using DriverManager is not recommended anymore. See this excerpt from the javadoc
NOTE: The DataSource interface, new in the JDBC 2.0 API, provides another way to connect to a data source. The use of a DataSource object is the preferred means of connecting to a data source.
Im creating a simple DBHelper for my postgre DB using a JDBC driver.
Im wondering what are the best practices?
For example, are methods like initConnection() closeConnection() or any other, should be static one? Like:
void foo{
DBHelper.initConnection();
// do some logic, maybe:
// Data someData = DBHelper.getSomeData();
DBHelper.closeConnection();
}
Or maybe better if i will create a DBHelper object and call method for object. Like:
void foo2{
DBHelper dbhelper = new DBHelper();
dbhelper.initConnection();
// do some logic, maybe:
// Data someData = dbhelper.getSomeData();
dbhelper.closeConnection();
}
Is it matter at all?
Do i need always check if connection is open before i will try to retrive some data? What if it is close? And always try to close it in finally block?
EDIT:
in answer to #Kayaman comment:
So my foo method like this?
void foo3{
Connection conn = DBHelper.getConnection();
// do some logic, maybe:
// Statement statement = conn.createStatement();
// some stmt work
conn.close() //do i need check if stmt is closed before?
}
That will make my DBHelper class usefull only to getting connection. There will be no logic inside? (like GetInterestingRecords() or GetRecordsWithId(30) ?
Have you thought about defining the connection properties in the server config file (if it is a web app) and have the session opened for the whole application lifecycle?
Before implementing DBHelper you should check if some java libraries may satisfy your needs. If you take a look at this there are listed some libraries that seem to fit your problem.
If you decide to go on with your own custom implementation I suggest to make DBHelper a normal class with no static methods for managing the connections; the main reason is that with static methods you cannot manage multiple (i.e. connections to different databases) db connections at the same time. If you are using a java 7 implementation in your onw library you could also implement tha AutoClosable inferface in order to better manage the resource you library is managing.
I have read about DAO from here and I find it really interesting but a few things are still missing me.
I would like to use the Interface to implement for two different data sources - one is a Socket connection, the other a Database connection.
For this I do the following:
public class databasePartDAOImplementation extends Database implements PartDAO {
//implementation
}
and the Database class has a constructor and some methods for managing this connection. How can I set up these classes, so I could instantiate one Database connection and then uses multiple DAOs all using this one connection?
I'm thinking of creating and instance of Database() and casting it into all the DAOs when needed, but I am not sure of any downfalls to this.
The Database class I use looks like this
public class Database
{
protected Connection connection;
public Database() throws ClassNotFoundException
{
Class.forName("org.sqlite.JDBC");
connection = null;
try
{
connection = DriverManager.getConnection("jdbc:sqlite:database.s3db");
}
catch(SQLException e)
{
System.err.println(e.getMessage());
}
}
public Connection getConnection() {
return connection;
}
}
tl;dr Would using this be a good idea of accessing the db?
Database db = new Database();
databasePartDAOImplementation dao = (databasePartDAOImplementation) db;
dao.getAllRecords();
You are partially correct regarding the point that the DAO should manage the connection with its data source to obtain and store data. But, as you have asked, how can we have all DAOs share the same connection? Let me shed some light by considering of the following strategies and then things will fall into place:
Automatically generating DAO code: Normally, there exists a relationship between your business objects, their DAOs and their underlying DB tables. Automatic code generation can take place using that relationship. In complex cases, you may use third party tools for code generation. May not be what you are looking for, but I just wanted to put it out there.
DAO Factory:
In a scenario where you are not dealing with different data sources (apparently this is not your scenario), you would create a single DAO factory class and use the Factory Method pattern to create the different DAOs used by your application. The DAO factory would be the class to manage the connection to the data source in this case.
In the scenario where you are dealing with different data sources (this is most likely your scenario), you would create an abstract DAO factory (this is the Abstract Factory pattern). Then, again, using the Factory Method pattern, your abstract DAO factory creates the concrete DAO factories for each of your specific data sources. Each concrete DAO factory would be responsible of two main tasks:
Creating a DAO for each kind of data access
Implementing a static method (e.g. createConnection) that takes care of creating a connection with its specific data source. You should consider connection pooling implementation and usage for that matter.
All the DAOs that are created by a concrete DAO factory would then be able to call that static method (createConnection) to obtain a connection to the specific data source. This connection would essentially be the same connection across all DAOs of the concrete DAO factory.
Ideas presented in this answer are based on the detailed article Core J2EE Patterns - Data Access Object.
I have having this problem with Java JMS when I am sending a queue to other systems and also planning to access the database to store some pictures.
I am facing this error with the compiler:
reference to connection is ambiguous,both interface
java.sql.Connection in java.sql and interface and interface javax.jms
Connection in javax.jms match Connection connection = null;
It should be quite a simple tweak to the code but I am not sure how. Any ideas?
You have to user the fully qualified class name, that is, java.sql.Connection or javax.jms.Connection. Otherwise the compiler doesn't know which connection interface you are referring to.
Since Connection and Statements are interfaces, interface methods will be abstract by default. How can we create Connection and Statement interfaces in our Java program while connecting to the database?
Actually the implementation is provided by JDBC drivers. And the API give you a way to use the thing. Look at this example.
The implementations are provided by the JDBC driver for your database. e.g. for MySql you download the JDBC Driver for MySQL (Connector/J) and place the jar file on the classpath for your application.
Then you make a call to DriverManager (e.g.) this gives you a instance of a class which implements the Connection interface.
Connection c = DriverManager.getConnection("jdbc:mysql://[yourhost]/[nameofyourdb]?user=[username]&password=[password]");
Now you can get an instance of a class which implements the Statement interface from the Connection instance.
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM [yourtablename]");
....
For more examples just google around a bit (JDBC, java, [nameofyourdb])
For Connector/J there is a nice documentation herer
MySQL Connector/J
Connector/J Examples
Actually, the interfaces are given by Sun and as everyone know interfaces are set of rules that will be used for a specific nature of programming and for a consistent structure. So the database vendors take that interface and will result the API which doesn't ruin the prototype. As a result every vendors implemented with same names as that interface has, irrespective of its logic.
So developers need not to worry about its implementation and must know only about the interface names.
I have worked on an abstraction for databases at work. Here is some example code
Database database = new Database(new SQL("host", "port","database", "username","password"));
List<tStd_M_lt> bases = database.select(tStd_M_lt.class, new Where(tStd_M_lt.FIELDS.ITEM_ID.getDatabaseFieldName(), OPERATOR.LIKE, "?"), "%Base%");
for (tStd_M_lt base : bases)
{
List<tShower_Base_Kit> kits = database.selectByForiegnKey(tShower_Base_Kit.class, base);
}
The project is called azirt.