On the encapsulation of JDBC template class in Java EE and the reasonable construction of project package structure (i)

Source: Internet
Author: User
Tags findone stmt

Starting today, let's talk about some of the knowledge in Java EE development, Java EE Development is used for enterprise-level development, but now the enterprise generally does not use JDBC development, most of them use their own company developed a set of frameworks, But the architecture of these frameworks will typically mimic the famous Java EE Open Source three development framework SSH (struts2+spring+hibernate) or the now popular SSM Development Framework (Spring+springmvc+mybatis)

In-depth customization to suit the actual development needs of your business. Some people have said that since the company is to re-study a set of frameworks, there is a need to learn the three main framework of open source, the answer is yes. Because the three frameworks are in fact many small and medium-sized companies are still in use, on the other hand learn the three framework will be very helpful to you to understand and learn the framework within the company. Then some people said, I directly learn three framework SSH or SSM, and learn some jdbc, JSP, Servlet, el expressions, Jstl tags, and so on? The answer is yes. In fact, the so-called three frameworks, which are only highly encapsulated, make development easier, more convenient, and more efficient, while the real core is the knowledge of JDBC and servlets. STRUTS2 is actually encapsulated on the basis of a servlet, and hibernate is a highly encapsulated JDBC that transforms relational-oriented data operations into object-oriented programming operations. Speaking so much, in a word: learning some basic knowledge and some internal mechanism principles will help to better learn and understand framework development. The difference between a code farmer and an engineer is whether you use a frame or a frame.

First of all, you should be based on the JDBC database (here to MySQL database for example) some additions and deletions of the operation are very clear and familiar with it, then we first look at the most primitive jdbc manipulation steps:

First step: Register the database driver with the Java reflection principle

class.forname ("Com.mysql.jdbc.Driver");

Step two: Get the Connection Connection object

Connection conn=drivermanager.getconnection ("Jdbc:mysql://127.0.0.1:3306/cms", "root", "root")

Step three: Preprocess the SQL statement and return a PreparedStatement preprocessing object.

PreparedStatement pstmt=conn.preparestatement (SQL);

Fourth step: If a placeholder uses a preprocessing object to assign a placeholder through some set methods

Pstmt.setstring ("name", username)

Fifth step: Execute the SQL statement, there are two ways to execute the SQL statement method is that there is no result set return (generally used to: add, delete, change), and another is the result set (query) returned by the

int executeupdate ();
Result ExecuteQuery ();

Sixth step: Results resultset processing result set

Seventh step: Freeing up resources main need to close connection connection object, PreparedStatement preprocessing SQL statement object, resultset result set

Note The order of closing: first created and then closed

Rs.close ();

Pstmt.close ();

Conn.close ();

The general basic JDBC to the database operation will go through the above steps, the actual steps may not be so much, they refined a bit. Now we can think about, our most primitive database JDBC operation, each time the addition and deletion of the changes will involve the above steps, some people say that this is not simple to each operation to define a method, the code paste copy changes can be. This way we will find that there will be a lot of code duplication and redundancy. It is very easy to think that many people will be able to extract the same code and then call it directly the next time they use it. All right, so what code do we need to extract the packages? In fact, it is very simple, we are not difficult to find whether or not to delete and change the operation, all need to get the connection object, and then finally need to release resources, we may wish to extract the code and then in the additions and deletions to refer to the method to reference the code. We can define a ConnectionFactory class, and then define a static method in which to return a connection object, and then define a close method.

Package Com.mikyou.common;import Java.sql.connection;import Java.sql.drivermanager;import Java.sql.preparedstatement;import Java.sql.resultset;import Java.sql.sqlexception;public class ConnectionFactory {/ * * Get Connection * */private static string driver;private static string url;private static string user;private static string pass word;/** * @Mikyou * Use static code blocks to initialize some parameters in advance, * we all know that the code in the static code block starts to load when the ConnectionFactory class is loaded in the method area * so you can play a pre-load and a role with initialization * */static{//in order to extend driver= "com.mysql.jdbc.Driver"; url= "Jdbc:mysql://127.0.0.1:3306/cms"; user= "root";p assword= "root ";} /** * @Mikyou * Get Connection Object * */public static Connection getconnection () throws Exception{class.forname (driver); return Driverm Anager.getconnection (Url,user,password);} /** * @Mikyou * for freeing resources * @param RS * @param pstmt * @param conn * First you need to determine if these parameters are empty, because there are operations and all involved in these three objects * For example, adding operations does not involve resultset R S * */public static void Close (ResultSet rs,preparedstatement pstmt,connection conn) throws Sqlexception{if (Rs!=null) {RS . Close ();} if (pstmt!=null) {pstmt. Close ();} if (conn!=null) {conn.close ();}}}
However, we are only simplifying part of the previous step, which is just the first step in encapsulation, followed by the real JDBC package.  Before encapsulation, let's consider a few questions, some of which are commonly used in the database using JDBC, some people say that 4 actually have at least 5 methods at the time of project development: Add Delete update Queryone Queryall. Well, let's make it clear that there are 5 ways to do that. Then let's analyze what the 5 methods have in common and different points, or what methods can be transformed into one class and which are the other. I can easily find and quickly classify: add,delete,update (no result set) Queryone (with a result set) Queryall (with an indeterminate number of result sets), so according to these three categories we correspond to three methods in the JdbcTemplate template class , the same method is used to deal with the same class of problems. corresponding to the template class, respectively.

Update (no result set) FindOne (returns a result set) FindAll (returns an indeterminate number of result sets).

With the establishment of these three methods, we go into these three ways:

The first Update method, how to use the definition of a common Update method to unify add,delete,update three operations. That depends on the similarities and differences of the three operation methods, first we conclude that the execution of these three methods of SQL statement is not the same, so the SQL statement needs to be passed through an external call, and then find that the SQL statement placeholder is to be assigned to the placeholder is not the same time, so also need to pass the time of the external call, However, one of the problems that comes up is to assign a placeholder to an external pass-through, because we know that the number of types and placeholders is different when dealing with placeholders, so we can conclude that the type of placeholder is uncertain and the number is uncertain, so I believe everyone should have guessed how to pass it here. In fact, can be passed in a variety of ways, you can use the set with the object type generic list<object> or the object array object[], and then passed in is required to assign a placeholder, we can go through the collection or array and then use the SetObject ( Key,value) to handle placeholders, the first method is actually analyzed, and encapsulation is easy. The package is as follows:

public void Update (String sql, object[] agrs) {try {Connection conn=null; PreparedStatement pstmt=null;try {conn=connectionfactory.getconnection ();//Get Connection object Pstmt=conn.preparestatement (SQL )///preprocessing sqlfor (int i = 0; i < agrs.length; i++) {//Handle placeholder Pstmt.setobject (i+1, agrs[i]);//Note: Why is the set placeholder ordinal in +1,jdbc starting from 1, Special case, in the future hibernate are all starting from 0}pstmt.executeupdate ();//Because you do not need to return a result set, use executeupdate} finally {Connectionfactory.close ( NULL, PSTMT, conn);//Close Connection}} catch (Exception e) {}}


The second method and the third method are slightly more troublesome than the first method, why? Because it has a result set back, how do we get these result sets and deal with these result sets? If you learn Android or learn javase GUI programming friends it's easy to think of a callback method that uses a custom listener to return a result set and process those result sets in a callback method. Because in the Android or GUI to some UI control will have a listener inside the callback method, through the callback method parameters can be passed the value, similar to the Onclicklistener interface in Android. So we can emulate an interface callback mechanism that passes our result set as a callback method parameter. But here's a little bit of a change that we can pass the result set, but our result set is divided into two cases: the first one returns a result set, the second returns the result set of indeterminate number, how to solve this problem? Because our defined interface returns only one object at a time, for indeterminate result sets, multiple objects can be returned more than once through a loop, and multiple objects are put into the collection, which resolves the problem returned by the result set. So the next thing to think about is what is the type of the return value for the query and Queryall methods? Our template method should be generic, suitable for different bean classes, so it is easy to think of the generics in Java, using generics, you can determine the type of the query return value of T,queryall return value of type List<t> This makes it possible to apply all the bean classes.

The first step: Customizing a listener Onimapperlistener

1. Define an interface first: Onimapperlistener

Package Com.mikyou.common;import java.sql.resultset;/** * Map Listener interface * */public interface onimapperlistener<t>{ Public T Mapper (ResultSet RS);//flag tag Variable  RS Returns the result set T means that the result set return value type is processed, the type of the general return value is the corresponding bean type}

2, then to the JdbcTemplate template class to define aonimapperlistener<t> The reference to the interface class listener, and then define a method Setonimapperlistener () to initialize the onimapperlistener<t > Interface Reference, This is not very similar to Android Setonclicklistener (), in fact the meaning is the same.

Private onimapperlistener< t> listener;public void Setonmapperlistener (onimapperlistener< T> Mapper) {// Initialize the mapping listener This.listener=mapper;}

3. Package Queryone and Queryall methods:

/** * @Mikyou * Queryone method * * */public t Queryone (String sql,object[] agrs) {T obj=null;try {Connection conn=null; PreparedStatement Pstmt=null; ResultSet rs=null;try {conn=connectionfactory.getconnection ();p stmt=conn.preparestatement (SQL); for (int i = 0; i < Agrs.length; i++) {pstmt.setobject (i+1, agrs[i]);} Rs=pstmt.executequery (); if (Rs.next ()) {if (listener!=null) {///indicates that the mapping listener has been registered, the Listener object is not empty obj=listener.mapper (RS);// The result set is passed as a parameter in the callback method}}} finally {Connectionfactory.close (RS, PSTMT, conn);}} catch (Exception e) {}return obj;} /** * @MIkyou * Queryall method * */public list<t> Queryall (String sql,object[] agrs) {list<t>list=new arraylist&lt ; T> (); try {Connection conn=null; PreparedStatement Pstmt=null; ResultSet rs=null;try {conn=connectionfactory.getconnection ();p stmt=conn.preparestatement (SQL); for (int i = 0; i < Agrs.length; i++) {pstmt.setobject (i+1, agrs[i]);} Rs=pstmt.executequery (); while (Rs.next ()) {if (listener!=null) {///indicates that the mapping listener has been registered, the Listener object is not empty T Obj=listener.mapper (RS); /result setIncoming callback method as a parameter in List.add (obj);}}} Finally {Connectionfactory.close (RS, PSTMT, conn);}} catch (Exception e) {}return list;}

Finally attach the complete JdbcTemplate template class can be used directly after the project:

<pre name= "code" class= "java" >package com.mikyou.common;import Java.sql.connection;import Java.sql.preparedstatement;import Java.sql.resultset;import Java.util.arraylist;import Java.util.List;public class jdbctemplate<t> {private onimapperlistener< t> listener;public void Setonmapperlistener ( onimapperlistener< t> Mapper) {//Initialize mapping listener This.listener=mapper;} public void Update (String sql, object[] agrs) {try {Connection conn=null; PreparedStatement pstmt=null;try {conn=connectionfactory.getconnection ();//Get Connection object Pstmt=conn.preparestatement (SQL )///Pre-sqlfor (int i = 0; i < agrs.length; i++) {//Handle placeholder Pstmt.setobject (i+1, agrs[i]);} Pstmt.executeupdate ();//Because you do not need to return a result set, use executeupdate} finally {connectionfactory.close (null, PSTMT, conn);//close connection }} catch (Exception e) {}}/** * @Mikyou * Queryone method * * */public T Queryone (String sql,object[] agrs) {T Obj=null;try {Co Nnection Conn=null; PreparedStatement Pstmt=null; ResultSet rs=null;try {conn=connectionfactory.getconnection ();Pstmt=conn.preparestatement (SQL); for (int i = 0; i < agrs.length; i++) {Pstmt.setobject (i+1, agrs[i]);} Rs=pstmt.executequery (); if (Rs.next ()) {if (listener!=null) {///indicates that the mapping listener has been registered, the Listener object is not empty obj=listener.mapper (RS);// The result set is passed as a parameter in the callback method}}} finally {Connectionfactory.close (RS, PSTMT, conn);}} catch (Exception e) {}return obj;} /** * @MIkyou * Queryall method * */public list<t> Queryall (String sql,object[] agrs) {list<t>list=new arraylist&lt ; T> (); try {Connection conn=null; PreparedStatement Pstmt=null; ResultSet rs=null;try {conn=connectionfactory.getconnection ();p stmt=conn.preparestatement (SQL); for (int i = 0; i < Agrs.length; i++) {pstmt.setobject (i+1, agrs[i]);} Rs=pstmt.executequery (); while (Rs.next ()) {if (listener!=null) {///indicates that the mapping listener has been registered, the Listener object is not empty T Obj=listener.mapper (RS); /result set passed as a parameter to the callback method in List.add (obj);}} Finally {Connectionfactory.close (RS, PSTMT, conn);}} catch (Exception e) {}return list;}}



We finally put the general JdbcTemplate template to build, good quality we have to test, we wrote a simple test to verify the template class encapsulation success or failure.

Where do we usually use this JdbcTemplate class? Or how to use it to use the JdbcTemplate class? We generally use the DAO layer, DAO is generally to the database of various additions and deletions to the operation, as for the project structure and sealing layer will be explained shortly. We'll write a Customerdao class to implement our listener and rewrite the callback method mapper method, where the parameter is the result set returned by the callback and used as the generic type by the customer, the Bean class.

Package Com.mikyou.dao;import Java.sql.resultset;import Java.sql.sqlexception;import java.util.list;import Com.mikyou.bean.customer;import com.mikyou.common.jdbctemplate;import com.mikyou.common.onimapperlistener;/** * @ Mikyou * jdbctemplate:<---&GT;JDBC template class * * */public class Customerdao implements onimapperlistener<customer>{ Private Jdbctemplate<customer>temp;public Customerdao () {temp=new jdbctemplate<customer> (); Temp.setonmapperlistener (this);//Register the mapping listener with Customerdao}/** * The following three methods have a common feature is that there is no need to have a return result set, So directly in the JdbcTemplate template class directly encapsulated into an update method can be * */public void Save (Customer customer) throws sqlexception{string sql= "insert Into Tb1_customer (name,gender,telephone,address) VALUES (?,?,?,?) "; O Bject[] Agrs={customer.getname (), Customer.getgender (), Customer.gettelephone (), customer.getaddress ()}; Temp.update (SQL, AGRS);} public void Update (customer customer) {String sql= "update tb1_customer set name=?,gender=?,telephone=?,address=? where Id=? "; O Bject[] Agrs={customer.getname (), CusTomer.getgender (), Customer.gettelephone (), customer.getaddress (), Customer.getid ()};temp.update (SQL, AGRS);} public void Delete (long id) {String sql= ' delete from Tb1_customer where id=? '; O bject[] agrs={id};temp.update (SQL, AGRS);} Public Customer Findbyname (string name) {string Sql= "select * from Tb1_customer where name=?"; O Bject[] Args={name};  Customer customer=temp.queryone (sql, args); return customer; }public list<customer> FindAll () {String sql= "select * from Tb1_customer"; object[] Args={};return Temp.queryall ( SQL, args);} /** * @Mikyou * Implement the corresponding callback method * @param RS Callback Returns the result set * @deprecated: processing result set and returning the type is our bean type Customer * */@Overridepublic Custome R Mapper (ResultSet Rs) {Customer customer=null;try {Long id=rs.getlong ("id"); String name=rs.getstring ("name"); String gender=rs.getstring ("gender"); String address=rs.getstring ("address"); String telephone=rs.getstring ("Telephone"); customer=new customer (ID, name, gender, telephone, address);} catch (SQLException e) {e.printstacktrace ();} return custoMer;}} 

Next we write a Daotest test class test:

Add Action:

private void Add () {Customerdao customerdao=new Customerdao (); try {customer customer=new customer (1L, "mikyou", "male", "123 456789 "," China "); Customerdao.save (customer); Customer Customer2=new Customer (2L, "Alice", "female", "123456789", "United States"); Customerdao.save (Customer2); catch (SQLException e) {//TODO auto-generated catch Blocke.printstacktrace ();}}


Operation Result:


Update operation:

private void Update () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); Customerdao.update ( New Customer (2L, "Bob", "Male", "123456789", "UK"));

Operation Result:


A query determines one of the following:

private void FindOne () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); Customer customer=customerdao.findbyname ("Bob"); System.out.println (Customer.tostring ());}


Query multiple:

private void FindAll () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); List<customer> Customers=customerdao.findall (); for (Customer customer:customers) {System.out.println ( Customer.tostring ());}}

Delete operation:

private void Delete () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); Customerdao.delete ( 1L);}

Daotest Test class:

Package Com.mikyou.test;import Java.sql.sqlexception;import Java.util.arraylist;import java.util.List;import Com.mikyou.bean.customer;import Com.mikyou.dao.customerdao;import       Com.sun.org.apache.bcel.internal.util.securitysupport;public class Daotest {public static void main (string[] args) { New Daotest (). Add ();//Add New Daotest (). Delete ();//delete//New Daotest (). Update ();//Change//new daotest (). FindOne ();//query specific one//new Daotest (). FINDALL ();//Query a collection}private void FindAll () {//TODO auto-generated method Stubcustomerda O customerdao=new Customerdao (); List<customer> Customers=customerdao.findall (); for (Customer customer:customers) {System.out.println ( Customer.tostring ());}} private void FindOne () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); Customer customer=customerdao.findbyname ("Bob"); System.out.println (Customer.tostring ());} private void Update () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); customeRdao.update (New Customer (2L, "Bob", "Male", "123456789", "UK")); private void Delete () {//TODO auto-generated method Stubcustomerdao customerdao=new Customerdao (); Customerdao.delete ( 1L);} private void Add () {Customerdao customerdao=new Customerdao (); try {customer customer=new customer (1L, "mikyou", "male", "123 456789 "," China "); Customerdao.save (customer); Customer Customer2=new Customer (2L, "Alice", "female", "123456789", "United States"); Customerdao.save (Customer2); catch (SQLException e) {//TODO auto-generated catch Blocke.printstacktrace ();}}}


Here JdbcTemplate template class Simple package that's it, is it better to just write a bunch of repetitive redundant code than before?

Next continue to talk about our Java EE package how to build and the entire Java EE project hierarchy, in fact, layering everyone looks more or less the same, but the overall classification is the same.

There is a service layer (abstract interface layer and interface implementation layer), the DAO layer (Data Control layer), the Web layer (the presentation layer) through these layers to reduce the coupling between the code, the implementation of data and views and business logic layer separation.


Here is the end, the following will continue to introduce the three framework of SSH, beginner Java ee, the above blog inevitably some problems, but also please correct me.

On the encapsulation of JDBC template class in Java EE and the reasonable construction of project package structure (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.