模板设计模式
模板方法模式(Template Method Pattern),又叫模板模式(Template Pattern),在一个抽象类公开定义了执行它的方法的模板。它的子类可以按需要重写方法实现,但调用将以抽象类中定义的方式进行。
该模式的主要优点如下。
1) 它封装了不变部分,扩展可变部分。它把认为是不变部分的算法封装到父类中实现,而把可变部分算法由子类继承实现,便于子类继续扩展。
2) 它在父类中提取了公共的部分代码,便于代码复用。
3) 部分方法是由子类实现的,因此子类可以通过扩展方式增加相应的功能,符合开闭原则。
案例
JdbcTemplate uml 图:
1 pom
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
</dependencies>
2 JdbcFactory
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.util.HashMap;
import java.util.Map;
public class JdbcFactory {
/**
* ###########################DB配置########################
*/
private static final String URL = "jdbc:mysql://localhost:3306/test?charset=utf8mb4&serverTimezone=UTC&useUnicode=true&useSSL=false";
private static final String USERNAME = "root";
private static final String PASSWORD = "123456";
private static final String DRIVER = "com.mysql.jdbc.Driver";
private static DataSource db;
static {
Map<String, String> map = new HashMap<>();
map.put(DruidDataSourceFactory.PROP_DRIVERCLASSNAME, DRIVER);
map.put(DruidDataSourceFactory.PROP_URL, URL);
map.put(DruidDataSourceFactory.PROP_USERNAME, USERNAME);
map.put(DruidDataSourceFactory.PROP_PASSWORD, PASSWORD);
try {
db = DruidDataSourceFactory.createDataSource(map);
} catch (Exception e) {
db = null;
e.printStackTrace();
}
}
private JdbcFactory() {
}
public static DataSource getInstance() {
return db;
}
}
3 RowMapper
/**
* ORM 定制化接口
*/
public interface RowMapper<T> {
T mapRow(ResultSet rs, int rowNum) throws SQLException;
}
4 JdbcTemplate
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public abstract class JdbcTemplate {
private DataSource dataSource;
public JdbcTemplate(DataSource dateSource) {
this.dataSource = dateSource;
}
public <T> List<T> executeQuery(String sql, RowMapper<T> rowMapper, Object[] values) {
try {
//1 获取连接
Connection connection = this.getConnection();
//2 创建语句集
PreparedStatement pstm = this.createPrepareStatement(connection, sql);
//3 执行语句集
ResultSet rs = execute(pstm, values);
//4 处理结果集
List<T> list = paresResultSet(rs, rowMapper);
//5 关闭结果集
this.closeResultSet(rs);
//6 关闭语句集
this.closeStatement(pstm);
//7 关闭连接
this.closeConnection(connection);
//8 返回
return list;
} catch (Exception e) {
e.printStackTrace();
}
return new ArrayList<>();
}
protected void closeConnection(Connection connection) throws SQLException {
if (connection != null) {
connection.close();
}
}
protected void closeStatement(PreparedStatement pstm) throws SQLException {
pstm.close();
}
protected void closeResultSet(ResultSet rs) throws SQLException {
rs.close();
}
protected <T> List<T> paresResultSet(ResultSet rs, RowMapper<T> rowMapper) throws SQLException {
List<T> result = new ArrayList<>();
int rowNum = 1;
while (rs.next()) {
result.add(rowMapper.mapRow(rs, rowNum++));
}
return result;
}
private ResultSet execute(PreparedStatement pstm, Object[] values) throws SQLException {
if (values != null) {
for (int i = 0; i < values.length; i++) {
pstm.setObject(i, values[i]);
}
}
return pstm.executeQuery();
}
protected PreparedStatement createPrepareStatement(Connection connection, String sql) throws SQLException {
return connection.prepareStatement(sql);
}
private Connection getConnection() throws SQLException {
return this.dataSource.getConnection();
}
}
5 业务类
@Data
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class Student {
private Integer id;
private String name;
private Integer age;
}
public class StudentDao extends JdbcTemplate {
public StudentDao(DataSource dateSource) {
super(dateSource);
}
public List<Student> selectAll() {
String sql = "select * from t_student";
return super.executeQuery(sql, (rs, rowNum) -> {
Student student = new Student();
student.setId(rs.getInt("id"));
student.setAge(rs.getInt("age"));
student.setName(rs.getString("name"));
return student;
}, null);
}
}
6 测试
public class JdbcTest {
public static void main(String[] args) throws Exception {
DataSource instance = JdbcFactory.getInstance();
StudentDao studentDao=new StudentDao(instance);
List<Student> students = studentDao.selectAll();
System.out.println(students.toString());
}
}