Skip to content

Commit

Permalink
支持简单参数绑定
Browse files Browse the repository at this point in the history
  • Loading branch information
FuriousPws002 committed Apr 10, 2024
1 parent 94cf9bb commit bb5360a
Show file tree
Hide file tree
Showing 34 changed files with 734 additions and 6 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@
# 功能模块
[1.注册Mapper接口](https://github.com/FuriousPws002/mini-mybatis/wiki/1.%E6%B3%A8%E5%86%8CMapper%E6%8E%A5%E5%8F%A3 "Markdown") <br>
[2.解析xml中静态sql的mapper](https://github.com/FuriousPws002/mini-mybatis/wiki/2.%E8%A7%A3%E6%9E%90xml%E4%B8%AD%E9%9D%99%E6%80%81sql%E7%9A%84mapper "Markdown") <br>
[3.执行静态sql](https://github.com/FuriousPws002/mini-mybatis/wiki/3.%E6%89%A7%E8%A1%8C%E9%9D%99%E6%80%81sql "Markdown") <br>
[3.执行静态sql](https://github.com/FuriousPws002/mini-mybatis/wiki/3.%E6%89%A7%E8%A1%8C%E9%9D%99%E6%80%81sql "Markdown") <br>
[4.参数绑定](https://github.com/FuriousPws002/mini-mybatis/wiki/4.%E5%8F%82%E6%95%B0%E7%BB%91%E5%AE%9A "Markdown") <br>
18 changes: 18 additions & 0 deletions src/main/java/org/apache/ibatis/annotations/Param.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.apache.ibatis.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

/**
* @author furious 2024/4/10
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.PARAMETER)
public @interface Param {

String value();
}
17 changes: 16 additions & 1 deletion src/main/java/org/apache/ibatis/binding/MapperMethod.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.reflection.ParamNameResolver;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;

Expand All @@ -14,16 +15,18 @@
public class MapperMethod {

private final SqlCommand command;
private final MethodSignature method;

public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, mapperInterface, method);
}

public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
case INSERT: {
result = sqlSession.insert(command.getName(), args);
result = sqlSession.insert(command.getName(), method.convertArgsToSqlCommandParam(args));
break;
}
default:
Expand Down Expand Up @@ -57,4 +60,16 @@ public SqlCommandType getType() {
}
}

public static class MethodSignature {

private final ParamNameResolver paramNameResolver;

public MethodSignature(Configuration configuration, Class<?> mapperInterface, Method method) {
this.paramNameResolver = new ParamNameResolver(method);
}

public Object convertArgsToSqlCommandParam(Object[] args) {
return paramNameResolver.getNamedParams(args);
}
}
}
49 changes: 49 additions & 0 deletions src/main/java/org/apache/ibatis/builder/SqlSourceBuilder.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package org.apache.ibatis.builder;

import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;
import org.apache.ibatis.parsing.GenericTokenParser;
import org.apache.ibatis.parsing.TokenHandler;
import org.apache.ibatis.session.Configuration;

/**
* @author furious 2024/4/10
*/
public class SqlSourceBuilder extends BaseBuilder {
public SqlSourceBuilder(Configuration configuration) {
super(configuration);
}

public SqlSource parse(String originalSql, Class<?> parameterType) {
ParameterMappingTokenHandler handler = new ParameterMappingTokenHandler(configuration);
GenericTokenParser parser = new GenericTokenParser("#{", "}", handler);
String sql = parser.parse(originalSql);
return new StaticSqlSource(sql, handler.getParameterMappings());
}

private static class ParameterMappingTokenHandler extends BaseBuilder implements TokenHandler {

private List<ParameterMapping> parameterMappings = new ArrayList<>();

public ParameterMappingTokenHandler(Configuration configuration) {
super(configuration);
}

public List<ParameterMapping> getParameterMappings() {
return parameterMappings;
}

@Override
public String handleToken(String content) {
parameterMappings.add(buildParameterMapping(content));
return "?";
}

private ParameterMapping buildParameterMapping(String content) {
return new ParameterMapping(configuration, content);
}
}
}
11 changes: 10 additions & 1 deletion src/main/java/org/apache/ibatis/builder/StaticSqlSource.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
package org.apache.ibatis.builder;

import java.util.List;

import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.SqlSource;

/**
Expand All @@ -9,13 +12,19 @@
public class StaticSqlSource implements SqlSource {

private final String sql;
private final List<ParameterMapping> parameterMappings;

public StaticSqlSource(String sql) {
this(sql, null);
}

public StaticSqlSource(String sql, List<ParameterMapping> parameterMappings) {
this.sql = sql;
this.parameterMappings = parameterMappings;
}

@Override
public BoundSql getBoundSql(Object parameterObject) {
return new BoundSql(this.sql);
return new BoundSql(sql, parameterMappings, parameterObject);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ public void parseStatementNode() {
String id = context.getAttribute("id");
String nodeName = context.getName();
SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
SqlSource sqlSource = new StaticSqlSource(context.getBody());
SqlSource sqlSource = configuration.getLanguageDriver().createSqlSource(configuration, context, null);
builderAssistant.addMappedStatement(id, sqlCommandType, sqlSource);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ private Statement prepareStatement(StatementHandler handler) throws SQLException
Connection connection = configuration.getDataSource().getConnection();
connection.setAutoCommit(true);
stmt = handler.prepare(connection, null);
handler.parameterize(stmt);
return stmt;
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package org.apache.ibatis.executor.parameter;

import java.sql.PreparedStatement;
import java.sql.SQLException;

/**
* @author furious 2024/4/10
*/
public interface ParameterHandler {

Object getParameterObject();

void setParameters(PreparedStatement ps) throws SQLException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import java.util.Objects;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
Expand All @@ -20,6 +21,7 @@ public class PrepareStatementHandler implements StatementHandler {
protected final Executor executor;
protected final MappedStatement mappedStatement;
protected BoundSql boundSql;
protected final ParameterHandler parameterHandler;

public PrepareStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
this.configuration = mappedStatement.getConfiguration();
Expand All @@ -29,6 +31,7 @@ public PrepareStatementHandler(Executor executor, MappedStatement mappedStatemen
boundSql = mappedStatement.getBoundSql(parameterObject);
}
this.boundSql = boundSql;
this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
}

@Override
Expand All @@ -42,4 +45,9 @@ public int update(Statement statement) throws SQLException {
ps.execute();
return ps.getUpdateCount();
}

@Override
public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,6 @@ public interface StatementHandler {
Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException;

int update(Statement statement) throws SQLException;

void parameterize(Statement statement) throws SQLException;
}
18 changes: 18 additions & 0 deletions src/main/java/org/apache/ibatis/mapping/BoundSql.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,32 @@
package org.apache.ibatis.mapping;

import java.util.List;

/**
* @author furious 2024/4/7
*/
public class BoundSql {

private final String sql;
private final List<ParameterMapping> parameterMappings;
private final Object parameterObject;

public BoundSql(String sql) {
this(sql, null, null);
}

public BoundSql(String sql, List<ParameterMapping> parameterMappings, Object parameterObject) {
this.sql = sql;
this.parameterMappings = parameterMappings;
this.parameterObject = parameterObject;
}

public List<ParameterMapping> getParameterMappings() {
return parameterMappings;
}

public Object getParameterObject() {
return parameterObject;
}

public String getSql() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ public Configuration getConfiguration() {

public BoundSql getBoundSql(Object parameterObject) {
BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
return new BoundSql(boundSql.getSql());
return new BoundSql(boundSql.getSql(),boundSql.getParameterMappings(),parameterObject);
}

public static class Builder {
Expand Down
56 changes: 56 additions & 0 deletions src/main/java/org/apache/ibatis/mapping/ParameterMapping.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
package org.apache.ibatis.mapping;

import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.type.TypeHandler;

/**
* @author furious 2024/4/10
*/
public class ParameterMapping {

private Configuration configuration;
private String property;
private Class<?> javaType = Object.class;
private TypeHandler typeHandler;

public ParameterMapping() {
}

public ParameterMapping(Configuration configuration, String property) {
this.configuration = configuration;
this.property = property;
this.typeHandler = configuration.getTypeHandlerRegistry().getUnknownTypeHandler();
}

public Configuration getConfiguration() {
return configuration;
}

public void setConfiguration(Configuration configuration) {
this.configuration = configuration;
}

public String getProperty() {
return property;
}

public void setProperty(String property) {
this.property = property;
}

public Class<?> getJavaType() {
return javaType;
}

public void setJavaType(Class<?> javaType) {
this.javaType = javaType;
}

public TypeHandler getTypeHandler() {
return typeHandler;
}

public void setTypeHandler(TypeHandler typeHandler) {
this.typeHandler = typeHandler;
}
}
31 changes: 31 additions & 0 deletions src/main/java/org/apache/ibatis/parsing/GenericTokenParser.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package org.apache.ibatis.parsing;

import org.apache.commons.lang3.ArrayUtils;
import org.apache.commons.lang3.StringUtils;

/**
* @author furious 2024/4/10
*/
public class GenericTokenParser {

private final String openToken;
private final String closeToken;
private final TokenHandler handler;

public GenericTokenParser(String openToken, String closeToken, TokenHandler handler) {
this.openToken = openToken;
this.closeToken = closeToken;
this.handler = handler;
}

public String parse(String text) {
String[] tokens = StringUtils.substringsBetween(text, openToken, closeToken);
if (ArrayUtils.isEmpty(tokens)) {
return text;
}
for (String token : tokens) {
text = text.replace(openToken + token + closeToken, handler.handleToken(token));
}
return text;
}
}
9 changes: 9 additions & 0 deletions src/main/java/org/apache/ibatis/parsing/TokenHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package org.apache.ibatis.parsing;

/**
* @author furious 2024/4/10
*/
public interface TokenHandler {

String handleToken(String content);
}
8 changes: 8 additions & 0 deletions src/main/java/org/apache/ibatis/parsing/XNode.java
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ public XNode(XPathParser xpathParser, Node node) {
this.body = parseBody(node);
}

public XNode newXNode(Node node) {
return new XNode(xpathParser, node);
}

public <T> T getAttribute(String name) {
return (T) attributes.getProperty(name);
}
Expand All @@ -46,6 +50,10 @@ public String getName() {
return name;
}

public Node getNode() {
return node;
}

private Properties parseAttributes(Node n) {
Properties attributes = new Properties();
NamedNodeMap attributeNodes = n.getAttributes();
Expand Down
Loading

0 comments on commit bb5360a

Please sign in to comment.