接口定义

SqlSession

定义SqlSession的基本行为,具体说明见注释。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
public interface SqlSession {

/**
* 查询多个
* @param statementId sql的id
* @param params 参数列表
* @param <E> 返回类型
* @return List<E>
*/
<E> List<E> selectList(String statementId, Object... params) throws Exception;

/**
* 按条件查询单个
* @param statementId sql的id
* @param params 参数列表
* @param <T> 返回类型
* @return T
*/
<T> T selectOne(String statementId, Object... params) throws Exception;

/**
* 更新内容
* @param statementId sql的id
* @param params 参数列表
* @return 受影响的行数
*/
int update(String statementId, Object params) throws Exception;

/**
* 保存对象
* @param statementId sql的id
* @param params 参数列表
* @return 受影响的行数
*/
int save(String statementId, Object params) throws Exception;

/**
* 删除对象
* @param statementId sql的id
* @param params 参数列表
* @return 受影响的行数
*/
int delete(String statementId, Object params) throws Exception;

/**
* 生成实现类
* @param mapperClass 待实现接口
* @param <T> 类型
* @return 动态代理类
*/
<T> T getMapper(Class<T> mapperClass);

/**
* 关闭连接
*/
void close();
}

SqlSessionFactory

定义生产SqlSession的工厂接口

1
2
3
4
5
6
7
8
public interface SqlSessionFactory {

/**
* 生产一个SqlSession
* @return SqlSession
*/
SqlSession openSession();
}

Executor

Executor用来封装具体操作,解决原生JDBC的痛点,去除大量的模板代码。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public interface Executor {

/**
* 查找
* @param configuration 核心配置类
* @param mappedStatement 已封装的sql
* @param params 参数
* @param <E> 返回值类型
* @return 结果
*/
<E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;

/**
* 更新
* @param configuration 核心配置类
* @param mappedStatement 已封装的sql
* @param params 参数
* @return 受影响的行数
*/
int update(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception;

/**
* 关闭连接
*/
void close();
}

SqlSessionFactoryBuilder

SqlSessionFactoryBuilder使提供给使用者使用的外部接口,用来从输入流中解析配置文件并且返回一个SqlSessiob工厂对象。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class SqlSessionFactoryBuilder {

/**
* 构建SqlSessionFactory
* @param in 主配置文件流
* @return DefaultSqlSessionFactory
*/
public SqlSessionFactory build(InputStream in) throws Exception {
//使用dom4j解析配置文件,封装到Configuration
XMLConfigBuilder builder = new XMLConfigBuilder();
Configuration configuration = builder.parseConfig(in);
//创建SqlSessionFactory对象:生产SqlSession
return new DefaultSqlSessionFactory(configuration);
}
}

实现

SimpleExecutor

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
public class SimpleExecutor implements Executor {
private PreparedStatement statement;
private Connection connection;
@Override
@SuppressWarnings({"unchecked", "Duplicates"})
public <E> List<E> query(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
//注册驱动,获取连接
connection = configuration.getDataSource().getConnection();
//获取sql
String sql = mappedStatement.getSql();
//转换sql
BoundSql boundSql = getBoundSql(sql);
//获取预处理对象
statement = connection.prepareStatement(boundSql.getSqlText());
//设置参数
String paramType = mappedStatement.getParamType();
Class<?> type = getClassType(paramType);
List<ParameterMapping> mappingList = boundSql.getParameterMappingList();
for (int i = 0; i < mappingList.size(); i++) {
ParameterMapping parameterMapping = mappingList.get(i);
String content = parameterMapping.getContent();
Field field = type.getDeclaredField(content);
//开启暴力访问
field.setAccessible(true);
E o = (E)field.get(params[0]);
//i从0开始,所以加一
statement.setObject(i+1, o);
}
//执行sql
ResultSet resultSet = statement.executeQuery();
String resultType = mappedStatement.getResultType();
Class<?> resultTypeClass = getClassType(resultType);
//封装结果集
List<Object> objects = new ArrayList<>();
while (resultSet.next()) {
Object o = resultTypeClass.getDeclaredConstructor().newInstance();
ResultSetMetaData metaData = resultSet.getMetaData();
for (int i = 0; i < metaData.getColumnCount(); i++) {
//获取字段名
String columnName = metaData.getColumnName(i+1);
Object value = resultSet.getObject(columnName);
//根据表和实体关系,完成封装,内省
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName, resultTypeClass);
Method writeMethod = propertyDescriptor.getWriteMethod();
writeMethod.invoke(o, value);
}
objects.add(o);
}
return (List<E>) objects;
}

@Override
@SuppressWarnings("Duplicates")
public int update(Configuration configuration, MappedStatement mappedStatement, Object... params) throws Exception {
connection = configuration.getDataSource().getConnection();
String sql = mappedStatement.getSql();
BoundSql boundSql = getBoundSql(sql);
statement = connection.prepareStatement(boundSql.getSqlText());
//设置参数
String paramType = mappedStatement.getParamType();
Class<?> type = getClassType(paramType);
List<ParameterMapping> mappingList = boundSql.getParameterMappingList();
for (int i = 0; i < mappingList.size(); i++) {
ParameterMapping parameterMapping = mappingList.get(i);
String content = parameterMapping.getContent();
Field field = type.getDeclaredField(content);
//开启暴力访问
field.setAccessible(true);
Object o = field.get(params[0]);
//i从0开始,所以加一
statement.setObject(i+1, o);
}
//执行sql
return statement.executeUpdate();
}

@Override
public void close() {
try {
statement.close();
connection.close();
} catch (SQLException ignored) {}
}

private Class<?> getClassType(String paramType) throws ClassNotFoundException {
if (paramType != null) {
return Class.forName(paramType);
}
throw new NullPointerException("paramType is null");
}

/**
* 把 #{} 转换为 ?
* 解析出#{}的值
* @param sql 待处理的sql
* @return 封装后的BoundSql
*/
private BoundSql getBoundSql(String sql) {
//标记处理类
ParameterMappingTokenHandler tokenHandler = new ParameterMappingTokenHandler();
GenericTokenParser genericTokenParser = new GenericTokenParser("#{", "}", tokenHandler);
//解析出来的sql
String parseSql = genericTokenParser.parse(sql);
//解析出来的参数名
List<ParameterMapping> mappings = tokenHandler.getParameterMappings();
return new BoundSql(parseSql, mappings);
}
}

DefaultSqlSession

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
public class DefaultSqlSession implements SqlSession {

private final Configuration configuration;

private Executor executor;

public DefaultSqlSession(Configuration configuration) {
this.configuration = configuration;
}

@Override
public <E> List<E> selectList(String statementId, Object... params) throws Exception {
//调动simpleExecutor的query方法
executor = new SimpleExecutor();
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
return executor.query(configuration, mappedStatement, params);
}

@Override
public <T> T selectOne(String statementId, Object... params) throws Exception {
List<T> t = selectList(statementId, params);
if (t.size() == 1) {
return t.get(0);
} else if (t.size() > 1){
throw new RuntimeException("返回结果过多");
}
throw new RuntimeException("返回结果为空");
}

@Override
public int update(String statementId, Object params) throws Exception {
executor = new SimpleExecutor();
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
return executor.update(configuration, mappedStatement, params);
}

@Override
public int save(String statementId, Object params) throws Exception {
executor = new SimpleExecutor();
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
return executor.update(configuration, mappedStatement, params);
}

@Override
public int delete(String statementId, Object params) throws Exception {
executor = new SimpleExecutor();
MappedStatement mappedStatement = configuration.getMappedStatementMap().get(statementId);
return executor.update(configuration, mappedStatement, params);
}

@Override
@SuppressWarnings("unchecked")
public <T> T getMapper(Class<T> mapperClass) {
//jdk动态代理
Object o = Proxy.newProxyInstance(DefaultSqlSession.class.getClassLoader(), new Class[]{mapperClass}, (proxy, method, args) -> {
String methodName = method.getName();
String className = method.getDeclaringClass().getName();
String statementId = className + "." + methodName;
//获取返回值类型
Type genericReturnType = method.getGenericReturnType();
if (genericReturnType instanceof ParameterizedType) {
return selectList(statementId, args);
}
return selectOne(statementId, args);
});
return (T) o;
}

@Override
public void close() {
try {
executor.close();
}catch(Exception ignore){}
}
}

DefaultSqlSessionFactory

1
2
3
4
5
6
7
8
9
10
11
12
13
public class DefaultSqlSessionFactory implements SqlSessionFactory {

private final Configuration configuration;

public DefaultSqlSessionFactory(Configuration configuration) {
this.configuration = configuration;
}

@Override
public SqlSession openSession() {
return new DefaultSqlSession(configuration);
}
}