First, let's explain why callback is used,
In our daily life and work, there is a situation in which we do one thing, but some steps in this process are not sure how to do it, but we can first agree on how to do it. for a program, there is a business, and several small logics are not sure how to do it, but we can define some methods (Unified parameters and return values) to correspond to these logics first, the specific implementation of these logic is implemented by the specific executed code.
For example, for JDBC access, if we use PreparedStatement to process SQL statements, we must initialize the connection, initialize PreparedStatement, encapsulate PreparedStatement, insert SQL parameters, execute SQL statements, and obtain the ResultSet, encapsulate the ResultSet into the object we want and close the connection. It is not clear to encapsulate the PreparedStatement to insert SQL parameters and encapsulate the ResultSet into the object we want, we can define these two steps as Callback functions and teach specific code execution.
As mentioned above, we can define a JdbcCallback interface to define this callback function,
Java code
Package com. balance. easycalendar. dao. template;
Import java. SQL. PreparedStatement;
Import java. SQL. ResultSet;
Import java. SQL. SQLException;
Import java. util. List;
Import com. balance. easycalendar. to. BaseTO;
Public interface JdbcCallback {
Public List <BaseTO> packResult (ResultSet rs) throws SQLException;
Public void packParams (PreparedStatement stmt) throws SQLException;
}
Define a JdbcCallbackTemplate to execute the specific method, and reference A JdbcCallback to complete the uncertain steps,
Java code
Package com. balance. easycalendar. dao. template;
Import java. SQL. Connection;
Import java. SQL. DriverManager;
Import java. SQL. PreparedStatement;
Import java. SQL. ResultSet;
Import java. util. List;
Import com. balance. easycalendar. dao. exception. DAOException;
Import com. balance. easycalendar. to. BaseTO;
Import com. balance. easycalendar. util. MessageProperties;
Public class JdbcCallbackTemplate {
Private JdbcCallback temp;
Public void setTemp (JdbcCallback temp ){
This. temp = temp;
}
Protected String url;
Protected String username;
Protected String password;
Protected String driver;
Private PreparedStatement stmt = null;
Private Connection con = null;
Public JdbcCallbackTemplate (){
MessageProperties pro = MessageProperties. getInstance ("jdbc. properties ");
Url = pro. getValue ("db. url ");
Driver = pro. getValue ("db. driver ");
Username = pro. getValue ("db. username ");
Password = pro. getValue ("db. password ");
}
Public List <BaseTO> query (String SQL) throws DAOException {
Try {
Class. forName (driver );
Con = DriverManager. getConnection (url, username, password );
Stmt = con. prepareStatement (SQL );
Temp. packParams (stmt );
ResultSet rs = stmt.exe cuteQuery ();
Return temp. packResult (rs );
} Catch (Exception e ){
Throw new DAOException (e );
} Finally {
Try {
Stmt. close ();
Con. close ();
} Catch (Exception e ){
E. printStackTrace ();
}
}
}
Public boolean excute (String SQL) throws DAOException {
Try {
Class. forName (driver );
Con = DriverManager. getConnection (url, username, password );
Stmt = con. prepareStatement (SQL );
Temp. packParams (stmt );
Return stmt.exe cute ();
} Catch (Exception e ){
Throw new DAOException (e );
} Finally {
Try {
Stmt. close ();
Con. close ();
} Catch (Exception e ){
E. printStackTrace ();
}
}
}
}
This Template defines two methods. excute is used to execute add, modify, delete, and so on. query is used to execute queries. In these two methods, the encapsulated parameters and encapsulated results are not sure, therefore, the callback function defined above is used for implementation, and the specific implementation is handed over to the specific implementation class for implementation. (MessageProperties is a resource reference class I wrote. You can refer to another blog of mine: Write a configuration file reader in the Multi-sample mode)
Next let's look at the specific implementation,
Instantiate a jdbcCallbackTemplate in BaseDAO
Java code
Package com. balance. easycalendar. dao;
Import com. balance. easycalendar. dao. template. JdbcCallbackTemplate;
Import com. balance. easycalendar. util. MessageProperties;
Public abstract class BaseDAO {
Protected JdbcCallbackTemplate jdbcCallbackTemplate = new JdbcCallbackTemplate ();
Public String getSql (String sqlId ){
MessageProperties pro = MessageProperties. getInstance ("sqls. properties ");
Return pro. getValue (sqlId );
}
}
Define a TaskDAO to execute specific database access. First, inject the instantiated JdbcCallback (to implement specific callback functions) to jdbccalltemplate, and then you can call the query and excute methods in the Template.
Java code
Package com. balance. easycalendar. dao;
Import java. SQL. PreparedStatement;
Import java. SQL. ResultSet;
Import java. SQL. SQLException;
Import java. util. ArrayList;
Import java. util. List;
Import com. balance. easycalendar. dao. exception. DAOException;
Import com. balance. easycalendar. dao. template. JdbcCallback;
Import com. balance. easycalendar. dao. template. JdbcCallbackAdapter;
Import com. balance. easycalendar. to. BaseTO;
Import com. balance. easycalendar. to. TaskTO;
Public class TaskDAO extends BaseDAO {
Public TaskTO getTask (final String taskId) throws DAOException {
JdbcCallbackTemplate. setTemp (new JdbcCallback (){
@ Override
Public void packParams (PreparedStatement stmt) throws SQLException {
Stmt. setString (1, taskId );
}
@ Override
Public List <BaseTO> packResult (ResultSet rs) throws SQLException {
List <BaseTO> tasks = new ArrayList <BaseTO> ();
While (rs. next ()){
TaskTO taskTO = new TaskTO ();
TaskTO. setTaskId (rs. getString ("TASK_ID "));
TaskTO. setTaskName (rs. getString ("TASK_NAME "));
TaskTO. setTaskDesc (rs. getString ("TASK_DESC "));
Tasks. add (taskTO );
}
Return tasks;
}
});
List <BaseTO> tasks = jdbcCallbackTemplate. query (getSql ("task. search. bytaskid "));
Return (TaskTO) tasks. get (0 );
}
Public boolean insertTask (final String taskId, final String taskName, final String taskDesc) throws DAOException {
JdbcCallbackTemplate. setTemp (new JdbcCallbackAdapter (){
@ Override
Public void packParams (PreparedStatement stmt) throws SQLException {
Stmt. setString (1, taskId );
Stmt. setString (2, taskName );
Stmt. setString (3, taskDesc );
}
});
Return jdbcCallbackTemplate. excute (getSql ("task. insert "));
}
Public boolean delTask (final String taskId) throws DAOException {
JdbcCallbackTemplate. setTemp (new JdbcCallbackAdapter (){
@ Override
Public void packParams (PreparedStatement stmt) throws SQLException {
Stmt. setString (1, taskId );
}
});
Return jdbcCallbackTemplate. excute (getSql ("task. delete. bytaskid "));
}
}
I also read SQL using MessageProperties, which is defined in a separate properties file,
SQL code
Task. search. bytaskid = select TASK_ID, TASK_NAME, TASK_DESC from TB_TASKS where TASK_ID =?
Task. insert = insert into TB_TASKS (TASK_ID, TASK_NAME, TASK_DESC) values (?,?,?)
Task. delete. bytaskid = Delete from TB_TASKS where TASK_ID =?