手写mybatis-预编译前的sql语句

sql表 mybatis数据库中的gxa_user表

/*
 Navicat Premium Data Transfer

 Source Server         : root
 Source Server Type    : MySQL
 Source Server Version : 80028
 Source Host           : localhost:3306
 Source Schema         : mybatis

 Target Server Type    : MySQL
 Target Server Version : 80028
 File Encoding         : 65001

 Date: 05/06/2024 20:48:12
*/

SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;

-- ----------------------------
-- Table structure for gxa_user
-- ----------------------------
DROP TABLE IF EXISTS `gxa_user`;
CREATE TABLE `gxa_user`  (
  `id` bigint(0) NOT NULL AUTO_INCREMENT,
  `username` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `salt` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `phone` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
  `created` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0),
  `last_login_time` datetime(0) NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP(0),
  `status` int(0) NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 47 CHARACTER SET = utf8 COLLATE = utf8_general_ci ROW_FORMAT = Dynamic;

-- ----------------------------
-- Records of gxa_user
-- ----------------------------
INSERT INTO `gxa_user` VALUES (1, '强哥', 'RbWEEsXVVxiR765qwusODQ==', 'e46d82f4-66b1-457d-8e70-36232b0a656e', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (2, '张老师', 'RbWEEsXVVxiR765qwusODQ==', 'e46d82f4-66b1-457d-8e70-36232b0a656e', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (3, '王国强', 'RbWEEsXVVxiR765qwusODQ==', 'e46d82f4-66b1-457d-8e70-36232b0a656e', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (11, '噗噗', '123456', '111', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (16, '噗噗2', '123456', '111', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (17, '补补', '123456', '111', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (20, '补补', '123456', '111', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (21, 'map', '8888', '222', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (23, 'map', '8888', '222', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (28, '123456', '12345', '123455', '123456', '2024-06-03 21:45:15', '2024-06-03 21:45:15', 1);
INSERT INTO `gxa_user` VALUES (29, 'gxaUser', '12345', '123455', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (30, 'mybatis', '12345', '123455', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (31, 'mybatis', '12345', '123455', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (32, 'mybatis', '12345', '123455', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (33, 'mybatisdemo', '123456', '11', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (34, 'mybatisdemo', '123456', '11', '123456789', '2024-06-03 21:42:18', '2024-06-03 21:42:18', 1);
INSERT INTO `gxa_user` VALUES (35, 'mybatisdemo', '123456', '11', '123568', '2024-06-03 21:47:49', '2024-06-03 21:47:49', 1);
INSERT INTO `gxa_user` VALUES (36, 'mybatisdemo', '123456', '11', '123568', '2024-06-03 21:50:22', '2024-06-03 21:50:22', 1);
INSERT INTO `gxa_user` VALUES (42, 'mybatis', '12345', '123455', '1234556', '2024-06-03 22:02:47', NULL, 1);
INSERT INTO `gxa_user` VALUES (43, 'mybatis', '12345', '123455', '1234556', '2024-06-03 22:04:07', '2024-06-03 22:04:07', 1);
INSERT INTO `gxa_user` VALUES (44, 'mybatis', '12345', '123455', '1234556', '2024-06-03 22:06:07', '2024-06-03 22:06:07', 1);
INSERT INTO `gxa_user` VALUES (45, 'mybatis', '12345', '123455', '1234556', '2024-06-05 14:38:22', '2024-06-05 14:38:22', 1);
INSERT INTO `gxa_user` VALUES (46, 'mybatis', '12345', '123455', '1234556', '2024-06-05 16:15:04', '2024-06-05 16:15:04', 1);

SET FOREIGN_KEY_CHECKS = 1;

jdbc.properties

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=123456

准备五个注解放在annotation包里面

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

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Delete {
    String value() default "";
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Insert {
    String value() default "";
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Select {
    String value() default "";
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Update {
    String value() default "";
}
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.PARAMETER)
@Retention(RetentionPolicy.RUNTIME)
public @interface Param {
    String value() default "";
}

配置数据库连接以及事务

import com.alibaba.druid.pool.DruidDataSource;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;

public class JdbcUtils {
    public static DataSource dataSource;
    public static Properties properties=new Properties();
    public static ThreadLocal<Connection> threadLocal=new ThreadLocal<>();

    static {
        try {
            InputStream resourceAsStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties");
            properties.load(resourceAsStream);
            DruidDataSource druidDataSource = new DruidDataSource();
            druidDataSource.setDriverClassName(properties.getProperty("jdbc.driver"));
            druidDataSource.setUrl(properties.getProperty("jdbc.url"));
            druidDataSource.setUsername(properties.getProperty("jdbc.username"));
            druidDataSource.setPassword(properties.getProperty("jdbc.password"));
            dataSource=druidDataSource;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

    }
    public static Connection getConnection(){
        try {
            if (threadLocal.get()==null)
                threadLocal.set(dataSource.getConnection());
                return threadLocal.get();
        } catch (SQLException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }
    public static void close(){
        if (threadLocal.get()!=null){
            try{
                threadLocal.get().close();
            }catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException("连接关闭失败");
            }
            threadLocal.set(null);
        }
    }
    public static void rollback(){
        if(threadLocal.get()!=null){
            try{
                threadLocal.get().rollback();
            }catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException("回滚失败");
            }
        }

    }
    public static void commit(){
        if (threadLocal.get()!=null){
            try{
                threadLocal.get().commit();
            }catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException("提交失败");
            }

        }

    }
    public static void start(){

            try{
                getConnection().setAutoCommit(false);
            }catch (Exception e){
                e.printStackTrace();
                throw new RuntimeException("开启事务失败");
            }


    }

}

根据上面的表创建javabean实体类

/**
 * (GxaUser)实体类
 *
 * @author makejava
 * @since 2024-05-24 15:16:19
 */
public class GxaUser{
    
    private Long id;
    
    private String username;
    
    private String password;
    
    private String salt;
    
    private String phone;
    
    private LocalDateTime created;
    
    private LocalDateTime last_login_time;
    
    private Integer status;


    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public LocalDateTime getCreated() {
        return created;
    }

    public void setCreated(LocalDateTime created) {
        this.created = created;
    }

    public LocalDateTime getLastLoginTime() {
        return last_login_time;
    }

    public void setLastLoginTime(LocalDateTime lastLoginTime) {
        this.last_login_time = lastLoginTime;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "GxaUser{" +
                "id=" + id +
                ", username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                ", phone='" + phone + '\'' +
                ", created=" + created +
                ", lastLoginTime=" + last_login_time +
                ", status=" + status +
                '}';
    }
}

Dto传输参数给数据库的

public class GxaUserDto {

    
    private String username;
    
    private String password;
    
    private String salt;
    
    private String phone;
    
    private Date created;
    
    private Date last_login_time;
    
    private Integer status;



    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getSalt() {
        return salt;
    }

    public void setSalt(String salt) {
        this.salt = salt;
    }

    public String getPhone() {
        return phone;
    }

    public void setPhone(String phone) {
        this.phone = phone;
    }

    public Date getCreated() {
        return created;
    }

    public void setCreated(Date created) {
        this.created = created;
    }

    public Date getLastLoginTime() {
        return last_login_time;
    }

    public void setLastLoginTime(Date lastLoginTime) {
        this.last_login_time = lastLoginTime;
    }

    public Integer getStatus() {
        return status;
    }

    public void setStatus(Integer status) {
        this.status = status;
    }

    @Override
    public String toString() {
        return "GxaUser{" +
                " username='" + username + '\'' +
                ", password='" + password + '\'' +
                ", salt='" + salt + '\'' +
                ", phone='" + phone + '\'' +
                ", created=" + created +
                ", lastLoginTime=" + last_login_time +
                ", status=" + status +
                '}';
    }
}

mapper接口类

import com.ssj.annotation.Delete;
import com.ssj.annotation.Insert;
import com.ssj.annotation.Select;
import com.ssj.annotation.Update;
import com.ssj.entity.GxaUser;
import com.ssj.entity.GxaUserDto;
import com.ssj.entity.GxaUserDto2;

import java.util.HashMap;
import java.util.List;

public interface GxaUserMapper {
    @Select("Select * from gxa_user where id=?")
    GxaUser findUserById(Long id);
    @Select("Select * from gxa_user")
    List<GxaUser> findUser();
    @Insert("Insert into gxa_user(username,password,salt,phone,created,last_login_time,status)\n" +
            "        values(?,?,?,?,?,?,?)")
    int insertUser(GxaUserDto user);
    @Update("update gxa_user set username=? where id=?")
    int update(String username,Long id);
    @Delete("Delete from gxa_user where id=?")
    int delete(Long id);
}

sql语句预编译工具类


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


public class SQLUtils {


    /**
     * 将SQL字符串中的命名参数替换为"?"占位符。
     *
     * @param sql 包含命名参数的SQL查询字符串,格式为#{paramName}。
     * @param selectParams 要替换的参数名称列表。
     * @return 将命名参数替换为"?"占位符后的SQL查询字符串。
     */
    public static String replaceParam(String sql, List<Object> selectParams) {
        // 遍历参数名称列表
        for (int i = 0; i < selectParams.size(); i++) {
            // 获取当前的参数名称
            Object paramName = selectParams.get(i);
            // 将SQL字符串中出现的命名参数替换为"?"
            sql = sql.replace("#{" + paramName + "}", "?");
        }
        // 返回修改后的SQL字符串
        return sql;
    }

    /**
     * 将SQL字符串中的命名参数替换为"?"占位符。
     *
     * @param sql 包含命名参数的SQL查询字符串,格式为#{paramName}。
     * @param parameterName 要替换的参数名称数组。
     * @return 将命名参数替换为"?"占位符后的SQL查询字符串。
     */
    public static String replaceParam(String sql, String[] parameterName) {
        // 遍历参数名称数组
        for (int i = 0; i < parameterName.length; i++) {
            // 获取当前的参数名称并去除前后的空白字符
            String string = parameterName[i].trim();
            // 将SQL字符串中出现的命名参数替换为"?"
            sql = sql.replace("#{" + string + "}", "?");
        }
        // 返回修改后的SQL字符串
        return sql;
    }

    /**
     * 从SQL查询字符串的WHERE子句中提取参数名称列表。
     *
     * @param sql 包含WHERE子句和命名参数的SQL查询字符串。
     * @return 从WHERE子句中提取的参数名称列表。
     */
    public static List<Object> getSelectParams(String sql) {
        List<Object> paramList = new ArrayList<>();

        // 查找WHERE子句的起始索引
        int whereIndex = sql.toLowerCase().indexOf("where");
        if (whereIndex == -1) {
            // 如果没有WHERE子句,返回空列表
            return paramList;
        }

        // 从SQL字符串中提取WHERE子句
        String whereClause = sql.substring(whereIndex + 5).trim();
        if (whereClause.isEmpty()) {
            // 如果WHERE子句为空,返回空列表
            return paramList;
        }

        // 按"and"分割WHERE子句,得到各个条件
        String[] paramsStrs = whereClause.split("\\s+and\\s+");
        // 遍历每个条件
        for (String paramsStr : paramsStrs) {
            // 按"="分割条件,提取参数
            if (paramsStr.contains("=")) {
                String[] parts = paramsStr.split("=");
                if (parts.length == 2) {
                    String param = parts[1].replace("#{", "").replace("}", "").trim();
                    if (!param.isEmpty()) {
                        // 将参数名称添加到列表中
                        paramList.add(param);
                    }
                }
            }
        }
        // 返回参数名称列表
        return paramList;
    }

    /**
     * 从INSERT SQL查询字符串的VALUES子句中提取参数名称列表。
     *
     * @param sql 包含INSERT语句和命名参数的SQL查询字符串。
     * @return 从VALUES子句中提取的参数名称数组。
     */
    public static String[] getInsertParams(String sql) {
        // 查找VALUES子句的起始索引
        int startIndex = sql.indexOf("values");
        // 从SQL字符串中提取VALUES子句,去除参数名称中的#{和},并去除括号
        String values = sql.substring(startIndex + 6).replaceAll("#\\{", "").replaceAll("}", "").
                replace("(", "").replace(")", "");
        // 按逗号分割清理后的VALUES子句,得到各个参数名称
        return values.split(",");
    }

    public static List<Object> getUpdateParams(String sql) {
        List<Object> paramList = new ArrayList<>();

        // 查找SET子句的起始索引
        int setStartIndex = sql.toLowerCase().indexOf("set") + 3;
        int whereStartIndex = sql.toLowerCase().indexOf("where");

        // 如果没有WHERE子句
        if (whereStartIndex == -1) {
            // 提取整个SET子句
            String setClause = sql.substring(setStartIndex).trim();
            addSetParams(paramList, setClause);
        } else {
            // 提取SET子句中的参数
            String setClause = sql.substring(setStartIndex, whereStartIndex).trim();
            addSetParams(paramList, setClause);

            // 提取WHERE子句中的参数
            String whereClause = sql.substring(whereStartIndex + 5).trim();
            addWhereParams(paramList, whereClause);
        }

        return paramList;

    }
    // 辅助方法:提取SET子句中的参数
    private static void addSetParams(List<Object> paramList, String setClause) {
        String[] setParams = setClause.split(",");
        for (String setParam : setParams) {
            String param = setParam.split("=")[1].replace("#{", "").replace("}", "").trim();
            paramList.add(param);
        }
    }
    // 辅助方法:提取WHERE子句中的参数
    private static void addWhereParams(List<Object> paramList, String whereClause) {
        String[] whereParams = whereClause.split("\\s+and\\s+");
        for (String whereParam : whereParams) {
            if (whereParam.contains("=")) {
                String[] parts = whereParam.split("=");
                if (parts.length == 2) {
                    String param = parts[1].replace("#{", "").replace("}", "").trim();
                    if (!param.isEmpty()) {
                        paramList.add(param);
                    }
                }
            }
        }
    }
}

jdk动态地理实现上面mapper接口

import com.ssj.annotation.*;

import java.lang.reflect.*;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;

public class MybatisUtils {
    public static <T> T getMapper(Class<T> clazz) {
        return (T) Proxy.newProxyInstance(clazz.getClassLoader(), new Class[]{clazz}, new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println("该 " + method.getName() + " 方法被调用了");
                if (method.isAnnotationPresent(Insert.class)) {
                    Insert annotation = method.getAnnotation(Insert.class);
                    String sql = annotation.value();
                    return executeInsert(method,sql, args);
                } else if (method.isAnnotationPresent(Delete.class)) {
                    Delete annotation = method.getAnnotation(Delete.class);
                    String sql = annotation.value();
                    return executeDelete(method,sql, args);
                } else if (method.isAnnotationPresent(Update.class)) {
                    Update annotation = method.getAnnotation(Update.class);
                    String sql = annotation.value();
                    return executeUpdate(method,sql, args);
                } else if (method.isAnnotationPresent(Select.class)) {
                    Select annotation = method.getAnnotation(Select.class);
                    String sql = annotation.value();
                    return executeQuery(sql, args, method);
                }
                return null;
            }

            private int executeInsert(Method method,String sql, Object[] args) throws Exception {
                if (args.length == 0) {
                    System.out.println("args长度为0");
                    throw new IllegalArgumentException("Invalid argument for insert operation");
                }
                //插入参数
                String[] insertParam = SQLUtils.getInsertParams(sql);
                //参数绑定
                ConcurrentHashMap<String, Object> paramMap = getMethodParam(method, args);
                //将参数值加入list
                List<Object> paramValueList = addParamToList(insertParam, paramMap);
                //预编译sql语句
                sql = SQLUtils.replaceParam(sql, insertParam);

                try (Connection connection = JdbcUtils.getConnection();
                     PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                    JdbcUtils.start();
//                    setPreparedStatementParameters(preparedStatement, args[0]);
                    if (paramValueList!=null){
                        // 设置PreparedStatement参数
                        for (int i = 0; i < paramValueList.toArray().length; i++) {
                            // 将方法参数设置到PreparedStatement中
                            preparedStatement.setObject(i + 1, paramValueList.get(i));
                        }
                    }

                    int rows = preparedStatement.executeUpdate();
                    JdbcUtils.commit();
                    return rows;
                }catch (Exception e){
                    JdbcUtils.rollback();
                    JdbcUtils.commit();
                    e.printStackTrace();
                    throw new RuntimeException("数据库连接异常");
                }finally {
                    JdbcUtils.close();
                }
            }
            private int executeUpdate(Method method,String sql, Object[] args) throws Exception {
                //插入参数
                List<Object> insertParam = SQLUtils.getUpdateParams(sql);
                //参数绑定
                ConcurrentHashMap<String, Object> paramMap = getMethodParam(method, args);
                //将参数值加入list
                List<Object> paramValueList = addParamToList(insertParam, paramMap);
                //预编译sql语句
                sql = SQLUtils.replaceParam(sql, insertParam);
                try (Connection connection = JdbcUtils.getConnection();
                     PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                    JdbcUtils.start();
                    for (int i = 0; i < paramValueList.toArray().length; i++) {
                        System.out.println("修改参数: " + args[i]);
                        preparedStatement.setObject(i + 1, paramValueList.get(i));
                    }

                    int rows = preparedStatement.executeUpdate();
                    JdbcUtils.commit();
                    return rows;
                } catch (Exception e) {
                    JdbcUtils.rollback();
                    throw e;
                } finally {
                    JdbcUtils.close();
                }
            }
            private int executeDelete(Method method,String sql, Object[] args) throws Exception {
                //插入参数
                List<Object> insertParam = SQLUtils.getSelectParams(sql);
                //参数绑定
                ConcurrentHashMap<String, Object> paramMap = getMethodParam(method, args);
                //将参数值加入list
                List<Object> paramValueList = addParamToList(insertParam, paramMap);
                //预编译sql语句
                sql = SQLUtils.replaceParam(sql, insertParam);
                try (Connection connection = JdbcUtils.getConnection();
                     PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                    JdbcUtils.start();
                    for (int i = 0; i < paramValueList.toArray().length; i++) {
                        System.out.println("删除参数: " + args[i]);
                        preparedStatement.setObject(i + 1, paramValueList.get(i));
                    }

                    int rows = preparedStatement.executeUpdate();
                    JdbcUtils.commit();
                    return rows;
                } catch (Exception e) {
                    JdbcUtils.rollback();
                    throw e;
                } finally {
                    JdbcUtils.close();
                }
            }

            // 执行查询操作
            private Object executeQuery(String sql, Object[] args, Method method) throws Exception {
                //插入参数
                List<Object> selectParams = SQLUtils.getSelectParams(sql);
                //参数绑定
                ConcurrentHashMap<String, Object> paramMap = getMethodParam(method, args);
                //将参数值加入list
                List<Object> paramValueList = addParamToList(selectParams, paramMap);
                //预编译sql语句
                sql = SQLUtils.replaceParam(sql, selectParams);
                try (Connection connection = JdbcUtils.getConnection();
                     PreparedStatement preparedStatement = connection.prepareStatement(sql)) {
                    System.out.println("args.length="+args);
                    if (args!=null){
                        // 设置PreparedStatement参数
                        for (int i = 0; i < paramValueList.toArray().length; i++) {
                            // 将方法参数设置到PreparedStatement中
                            preparedStatement.setObject(i + 1, paramValueList.get(i));
                        }
                    }
                    // 执行查询操作
                    ResultSet resultSet = preparedStatement.executeQuery();

                    // 获取方法的返回类型
                    Class<?> returnType = method.getReturnType();
                    // 如果返回类型是List,则将结果集映射为List对象
                    if (returnType == List.class) {
                        return mapResultSetToList(resultSet, getGenericReturnType(method));
                    } else {
                        // 如果不是List,则将结果集映射为单个对象
                        if (resultSet.next()) {
                            return mapResultSetToObject(resultSet, returnType);
                        }
                    }
                    return null;
                }catch (Exception e){
                    e.printStackTrace();
                    throw new RuntimeException("数据库连接异常");
                }finally {
                    JdbcUtils.close();
                }
            }

            private void setPreparedStatementParameters(PreparedStatement preparedStatement, Object param) throws Exception {
                System.out.println(param);
                Class<?> clazz = param.getClass();
                Field[] fields = clazz.getDeclaredFields();
                int index = 1;

                for (Field field : fields) {
                    field.setAccessible(true);
                    Object value = field.get(param);
                    System.out.println("insert--- 参数:"+value);
//                    if (value==null) continue;
                    preparedStatement.setObject(index++, value);
                }
            }



            // 将ResultSet映射为对象列表
            private <T> List<T> mapResultSetToList(ResultSet resultSet, Class<T> clazz) throws Exception {
                List<T> list = new ArrayList<>();
                // 遍历结果集,将每行数据映射为对象并添加到列表中
                while (resultSet.next()) {
                    list.add(mapResultSetToObject(resultSet, clazz));
                }
                return list;
            }

            // 将ResultSet映射为单个对象
            private <T> T mapResultSetToObject(ResultSet resultSet, Class<T> clazz) throws Exception {
                T obj = clazz.getDeclaredConstructor().newInstance();
                ResultSetMetaData metaData = resultSet.getMetaData();
                // 遍历结果集的元数据,将每列的数据映射到对象的相应字段中
                for (int i = 1; i <= metaData.getColumnCount(); i++) {
                    String columnName = metaData.getColumnName(i);
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(obj, resultSet.getObject(i));
                }
                return obj;
            }

            // 获取方法的泛型返回类型
            private Class<?> getGenericReturnType(Method method) {
                Type returnType = method.getGenericReturnType();
                // 如果返回类型是参数化类型,则获取实际的类型参数
                if (returnType instanceof ParameterizedType) {
                    ParameterizedType parameterizedType = (ParameterizedType) returnType;
                    return (Class<?>) parameterizedType.getActualTypeArguments()[0];
                }
                return Object.class;
            }
            // 判断一个类是否为基本类型或包装类型
            private  boolean isPrimitiveOrWrapper(Class<?> type) {
                return type.isPrimitive() || type == Boolean.class || type == Byte.class ||
                        type == Character.class || type == Double.class || type == Float.class ||
                        type == Integer.class || type == Long.class || type == Short.class ||
                        type == String.class;
            }

            private ConcurrentHashMap<String, Object> getMethodParam(Method method, Object[] args) {
                ConcurrentHashMap<String, Object> paramMap = new ConcurrentHashMap<>();
                Parameter[] parameters = method.getParameters();
                for (int i = 0; i < parameters.length; i++) {
                    Param param = parameters[i].getAnnotation(Param.class);
                    if (param == null) {
                        continue;
                    }
                    String paramName = param.value();
                    System.out.println("paramName="+paramName);
                    Object paramValue = args[i];
                    System.out.println("paramValue="+paramValue);

                    // 如果参数不是基本类型或包装类型,则将其属性名和值添加到 paramMap 中
                    if (!isPrimitiveOrWrapper(paramValue.getClass())) {
                        addObjectFieldsToParamMap(paramMap, paramName, paramValue);
                    } else {
                        paramMap.put(paramName, paramValue);
                    }
                }
                return paramMap;
            }

            // 将对象的属性名和值添加到 paramMap 中
            private void addObjectFieldsToParamMap(ConcurrentHashMap<String, Object> paramMap, String paramName, Object paramValue) {
                Field[] fields = paramValue.getClass().getDeclaredFields();
                for (Field field : fields) {
                    field.setAccessible(true);
                    try {
                        Object fieldValue = field.get(paramValue);
                        System.out.println("filedValue="+fieldValue);
                        String fieldName = paramName + "." + field.getName();
                        System.out.println("fieldName="+fieldName.substring(fieldName.indexOf(".")+1));
                        paramMap.put(fieldName.substring(fieldName.indexOf(".")+1), fieldValue);
                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                    }
                }
            }
            private List<Object> addParamToList(String[] insertParam, ConcurrentHashMap<String, Object> paramMap) {
                List<Object> paramValueList = new ArrayList<>();
                for (String param : insertParam) {
                    Object paramValue = paramMap.get(param.trim());
                    paramValueList.add(paramValue);
                }
                return paramValueList;
            }
            private List<Object> addParamToList(List<Object> insertParam, ConcurrentHashMap<String, Object> paramMap) {
                List<Object> paramValueList = new ArrayList<>();
                for (Object param : insertParam) {
                    Object paramValue = paramMap.get(param);
                    paramValueList.add(paramValue);
                }
                return paramValueList;
            }

        });
    }
}

在这里插入图片描述

项目结构

在这里插入图片描述
完整代码,请移步gitee
https://gitee.com/xiaobei_xiaohe/mybatisDemo2

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值