Java advanced features: use reflection to encapsulate common addition, deletion, modification and query methods

  • Import dependencies: Create a new maven project and import the following dependencies:
 <dependencies>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.49</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.24</version>
        </dependency>

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.2.8</version>
        </dependency>
    </dependencies>
  • Create druid.properties configuration file
#驱动加载
driverClassName=com.mysql.jdbc.Driver
#注册驱动
url=jdbc:mysql://127.0.0.1:3306/yourDbName?characterEncoding=utf-8&useSSL=false
#连接数据库的用户名
username=root
#连接数据库的密码
password=yourPassword
#属性类型的字符串,通过别名的方式配置扩展插件, 监控统计用的stat 日志用log4j 防御sql注入:wall
filters=stat
#初始化时池中建立的物理连接个数。
initialSize=2
#最大的可活跃的连接池数量
maxActive=300
#获取连接时最大等待时间,单位毫秒,超过连接就会失效。配置了maxWait之后,缺省启用公平锁,并发效率会有所下降, 如果需要可以通过配置useUnfairLock属性为true使用非公平锁。
maxWait=60000
  • Custom annotations: respectively represent the table name, primary key columns and non-primary key columns
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableName {
    
    
    String value();
}
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableColumn {
    
    
    String value();
}

@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface TableColumn {
    
    
    String value();
}
  • Create the entity class that needs to be operated: take the user table as an example
    insert image description here
/**
 * @author wjcAdministrator
 * @version 1.0
 * @date 2022/7/27 14:47
 */
@AllArgsConstructor
@NoArgsConstructor
@Data
@TableName("user")
public class User implements Serializable {
    
    
    @TableId(value = "id")
    private Integer id;
    /**
    *当实体属性名与表中列名一致时候,可不添加@TableColumn注解,直接取属性名作为参数即可
    */
    private String username;
    private String password;
    private Integer tel;
    private String email;

	/**
	*建立三个参数的构造函数是为了测试insert方法传递部分参数新增,数据库字段tel和email允许为null
	*/
    public User(Integer id, String username, String password) {
    
    
        this.id = id;
        this.username = username;
        this.password = password;
    }
}

  • Extract and encapsulate tool classes for obtaining database connections and date formatting:
public class ConnFactory {
    
    
    private static DataSource dataSource;

    /**
     * 静态代码块,从数据库连接池中创建连接
     */
    static {
    
    
        try {
    
    
            InputStream in = ConnFactory.class.getClassLoader().getResourceAsStream("druid.properties");
            Properties properties = new Properties();
            properties.load(in);
            dataSource = DruidDataSourceFactory.createDataSource(properties);
        } catch (IOException e) {
    
    
            e.printStackTrace();
        } catch (Exception e){
    
    
            e.printStackTrace();
        }
    }

    /**
     * 封装从连接池中获取连接的方法
     * @return
     */
    public static Connection getConn(){
    
    
        Connection connection = null;
        try {
    
    
            connection = dataSource.getConnection();
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return connection;
    }

    /**
     * 封装通用的关闭、释放资源的方法
     * @param set
     * @param ps
     * @param conn
     */
    public static void close(ResultSet set, PreparedStatement ps,Connection conn){
    
    
        try{
    
    
            if(set!=null){
    
    
                set.close();
            }

        } catch (Exception e){
    
    
            e.printStackTrace();
        }
        try{
    
    
            if(ps!=null){
    
    
                ps.close();
            }

        } catch (Exception e){
    
    
            e.printStackTrace();
        }try{
    
    
            if(conn!=null){
    
    
                conn.close();
            }

        } catch (Exception e){
    
    
            e.printStackTrace();
        }

    }
}
public class DateFormat {
    
    
    public static String format(Date date){
    
    
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-mm-dd HH:mm:ss");
        return  simpleDateFormat.format(date);
    }
}
  • Encapsulate the BaseDao class
public class BaseDao<T>  {
    
    
    private Class cls;

    /**
     * 构造方法,将继承BaseDao的类上的注解类型获取到并转换为Class类型
     */
    public BaseDao(){
    
    
        Class<? extends BaseDao> aClass = this.getClass();
        ParameterizedType type = (ParameterizedType) aClass.getGenericSuperclass();
        Type[] actualTypeArguments = type.getActualTypeArguments();
        this.cls = (Class) actualTypeArguments[0];
    }

    /**
     * 封装一个通用的根据主键id查询其对应的数据的查询方法
     * @param id
     * @return
     */
    public T selectAnyOneByPrimary(Integer id){
    
    
        Connection conn = ConnFactory.getConn();
        StringBuilder stringBuilder = new StringBuilder("select ");
        Field[] declaredFields = cls.getDeclaredFields();
        ArrayList<String> fieldNames = new ArrayList<>();
        for (Field field: declaredFields) {
    
    
            field.setAccessible(true);
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            TableColumn tableColumnAnnotation = field.getAnnotation(TableColumn.class);
            if(tableIdAnnotation != null){
    
    
                fieldNames.add(tableIdAnnotation.value());
            }else if(tableColumnAnnotation != null){
    
    
                fieldNames.add(tableColumnAnnotation.value());
            }else {
    
    
                fieldNames.add(field.getName());
            }
        }
        String columnNames = fieldNames.toString().replace("[","").replace("]"," from");
        stringBuilder.append(columnNames+" ");
        TableName tableNameAnnotation = (TableName) cls.getAnnotation(TableName.class);
        String tableName = "";
        if(tableNameAnnotation != null){
    
    
            tableName = tableNameAnnotation.value();
        }else{
    
    
            tableName = cls.getSimpleName();
        }
        stringBuilder.append(tableName+" where ");
        String primaryKey = "";
        for(Field field:declaredFields){
    
    
            field.setAccessible(true);
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            if(tableIdAnnotation != null){
    
    
                primaryKey = tableIdAnnotation.value();
                break;
            }
        }
        stringBuilder.append(primaryKey+" = ?");
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        try {
    
    
            preparedStatement = conn.prepareStatement(String.valueOf(stringBuilder));
            preparedStatement.setInt(1,id);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
    
    
                Object o = cls.newInstance();
                for (Field field: declaredFields) {
    
    
                    field.setAccessible(true);
                    TableId tableIdAnnotation = field.getAnnotation(TableId.class);
                    TableColumn tableColumnAnnotation = field.getAnnotation(TableColumn.class);
                    if(tableIdAnnotation != null){
    
    
                        field.set(o,resultSet.getObject(tableIdAnnotation.value()));
                    }else if(tableColumnAnnotation != null){
    
    
                        field.set(o,resultSet.getObject(tableColumnAnnotation.value()));
                    }else{
    
    
                        field.set(o,resultSet.getObject(field.getName()));
                    }
                }
                if(o != null){
    
    
                    return (T) o;
                }else{
    
    
                    return null;
                }
            }
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        } catch (InstantiationException e) {
    
    
            e.printStackTrace();
        }
        return null;
    }


    /**
     * 封装一个通用的分页查询所有数据的查询方法
     * @return
     */
    public List<T> selectList(Integer currentPage,Integer pageSize){
    
    
        Connection conn = ConnFactory.getConn();
        StringBuilder stringBuilder = new StringBuilder("select ");
        Field[] declaredFields = cls.getDeclaredFields();
        ArrayList<String> fieldNames = new ArrayList<>();
        for (Field field: declaredFields) {
    
    
            field.setAccessible(true);
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            TableColumn tableColumnAnnotation = field.getAnnotation(TableColumn.class);
            if(tableIdAnnotation != null){
    
    
                fieldNames.add(tableIdAnnotation.value());
            }else if(tableColumnAnnotation != null){
    
    
                fieldNames.add(tableColumnAnnotation.value());
            }else {
    
    
                fieldNames.add(field.getName());
            }
        }
        String columnNames = fieldNames.toString().replace("[","").replace("]"," from");
        stringBuilder.append(columnNames+" ");
        TableName tableNameAnnotation = (TableName) cls.getAnnotation(TableName.class);
        String tableName = "";
        if(tableNameAnnotation != null){
    
    
            tableName = tableNameAnnotation.value();
        }else{
    
    
            tableName = cls.getSimpleName();
        }
        stringBuilder.append(tableName+" limit ?,? ");
        PreparedStatement preparedStatement = null;
        ResultSet resultSet = null;
        ArrayList<T> list = new ArrayList<>();

        try {
    
    
            preparedStatement = conn.prepareStatement(String.valueOf(stringBuilder));
            preparedStatement.setObject(1,currentPage);
            preparedStatement.setObject(2,pageSize);
            resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
    
    
                Object o = cls.newInstance();
                for (Field field: declaredFields) {
    
    
                    field.setAccessible(true);
                    TableId tableIdAnnotation = field.getAnnotation(TableId.class);
                    TableColumn tableColumnAnnotation = field.getAnnotation(TableColumn.class);
                    if(tableIdAnnotation != null){
    
    
                        field.set(o,resultSet.getObject(tableIdAnnotation.value()));
                    }else if(tableColumnAnnotation != null){
    
    
                        field.set(o,resultSet.getObject(tableColumnAnnotation.value()));
                    }else{
    
    
                        field.set(o,resultSet.getObject(field.getName()));
                    }
                }
                list.add((T) o);
            }
            return list;
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }catch (InstantiationException e) {
    
    
            e.printStackTrace();
        } catch (IllegalAccessException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            ConnFactory.close(resultSet,preparedStatement,conn);
        }
        return null;
    }

    /**
     * 封装一个通用的新增方法
     * @param t
     * @return
     */
    public int insert(T t){
    
    

        Connection conn = ConnFactory.getConn();
        StringBuilder stringBuilder = new StringBuilder("insert into ");
        Class<?> aClass = t.getClass();
        TableName tableNameAnnotation = aClass.getAnnotation(TableName.class);
        String tableName = "";
        if(tableNameAnnotation != null){
    
    
            tableName = tableNameAnnotation.value();
        }else{
    
    
            tableName = aClass.getSimpleName();
        }
        stringBuilder.append(tableName);
        Field[] declaredFields = aClass.getDeclaredFields();
        ArrayList<String> fieldNames = new ArrayList<>();
        for (Field field: declaredFields) {
    
    
            field.setAccessible(true);
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            TableColumn tableColumnAnnotation = field.getAnnotation(TableColumn.class);
            if(tableIdAnnotation != null){
    
    
                fieldNames.add(tableIdAnnotation.value());
            }else if(tableColumnAnnotation != null){
    
    
                fieldNames.add(tableColumnAnnotation.value());
            }else {
    
    
                fieldNames.add(field.getName());
            }
        }
        String columnNames = fieldNames.toString().replace("[","(").replace("]",")" + "values");
        stringBuilder.append(columnNames);

        ArrayList<Object> placeholderList = new ArrayList<>();
        ArrayList<Object> columnValues = new ArrayList<>();
        for (Field field: declaredFields) {
    
    
            field.setAccessible(true);
            try {
    
    
                if(field.get(t) instanceof String){
    
    
                    columnValues.add(field.get(t).toString());
                }else if(field.get(t) instanceof Date){
    
    
                    String format = DateFormat.format((Date) field.get(t));
                    columnValues.add(format);
                }else{
    
    
                    columnValues.add(field.get(t));
                }
                placeholderList.add("?");
            } catch (IllegalAccessException e) {
    
    
                e.printStackTrace();
            }
        }
        String str = placeholderList.toString().replace("[","(").replace("]",")");
        stringBuilder.append(str);
        PreparedStatement preparedStatement = null;
        try {
    
    
            preparedStatement = conn.prepareStatement(String.valueOf(stringBuilder));
            for (int i = 0; i < columnValues.size(); i++) {
    
    
                preparedStatement.setObject(i+1,columnValues.get(i));
            }
            int i = preparedStatement.executeUpdate();
            if(i > 0){
    
    
                return  i;
            }else{
    
    
                return 0;
            }
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }finally {
    
    
            ConnFactory.close(null,preparedStatement,conn);
        }
        return 0;
    }

    /**
     * 封装一个根据传递的泛型对象参数进行修改的通用方法
     * @param t
     * @return
     */
    public int update(T t){
    
    
        Connection conn = ConnFactory.getConn();
        StringBuilder stringBuilder = new StringBuilder("update ");
        TableName tableNameAnnotation = (TableName) cls.getAnnotation(TableName.class);
        String tableName = "";
        if(tableNameAnnotation != null){
    
    
            tableName = tableNameAnnotation.value();
        }else {
    
    
            tableName = cls.getSimpleName();
        }

        stringBuilder.append(tableName+" set ");

        Field[] declaredFields = cls.getDeclaredFields();
        ArrayList<Object> list = new ArrayList<>();
        for (int i = 0; i <declaredFields.length; i++) {
    
    
            declaredFields[i].setAccessible(true);
            try {
    
    
                if(i == declaredFields.length -1 ){
    
    
                    stringBuilder.append(declaredFields[i].getName()+" = ?");
                }else{
    
    
                    stringBuilder.append(declaredFields[i].getName()+" = ?,");
                }
                list.add(declaredFields[i].get(t));
            } catch (IllegalAccessException e) {
    
    
                e.printStackTrace();
            }
        }
        stringBuilder.append(" where ");
        Object primaryKey = null;
        Object primaryKeyValue = null;
        for(Field field:declaredFields) {
    
    
            field.setAccessible(true);
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            if (tableIdAnnotation != null) {
    
    
                try {
    
    
                    primaryKeyValue = field.get(t);
                    primaryKey = tableIdAnnotation.value();
                    stringBuilder.append(primaryKey + " = ?" );
                    break;
                } catch (IllegalAccessException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
            PreparedStatement preparedStatement = null;
            try {
    
    
                preparedStatement = conn.prepareStatement(String.valueOf(stringBuilder));
                for (int i = 0; i < list.size(); i++) {
    
    
                    preparedStatement.setObject(i+1,list.get(i));
                }
                preparedStatement.setObject(list.size()+1,primaryKeyValue);
                int i = preparedStatement.executeUpdate();
                if(i > 0){
    
    
                    return i;
                }else{
    
    
                    return 0;
                }
            } catch (SQLException e) {
    
    
                e.printStackTrace();
            }
        return 0;
    }

    /**
     * 封装一个通用的根据主键进行删除的通用方法
     * @param id
     * @return
     */
    public int delete(Integer id){
    
    
        Connection conn = ConnFactory.getConn();
        StringBuilder stringBuilder = new StringBuilder("delete from ");

        TableName tableNameAnnotation = (TableName) cls.getAnnotation(TableName.class);
        String tableName = "";
        if(tableNameAnnotation != null){
    
    
            tableName = tableNameAnnotation.value();
        }else {
    
    
            tableName = cls.getSimpleName();
        }

        stringBuilder.append(tableName+" where ");
        Field[] declaredFields = cls.getDeclaredFields();
        String primaryKey = "";
        for(Field field:declaredFields){
    
    
            field.setAccessible(true);
            TableId tableIdAnnotation = field.getAnnotation(TableId.class);
            if(tableIdAnnotation != null){
    
    
                primaryKey = tableIdAnnotation.value();
                break;
            }
        }
        stringBuilder.append(primaryKey+" = ? ");
        PreparedStatement preparedStatement = null;
        try {
    
    
            preparedStatement = conn.prepareStatement(String.valueOf(stringBuilder));
            preparedStatement.setObject(1,id);
            int i = preparedStatement.executeUpdate();
            if(i > 0){
    
    
                return i;
            }else{
    
    
                return 0;
            }
        } catch (SQLException e) {
    
    
            e.printStackTrace();
        }
        return 0;
    }
}
  • Create a UserDao class that inherits from the BaseDao class
public class UserDao extends BaseDao<User> {
    
    }

  • Create a test class: ready to start testing
public class MyOrmTest {
    
    
    public static void main(String[] args) {
    
    

        UserDao userDao = new UserDao();

        int insert = userDao.insert(new User(null, "11111","1111"));
        System.out.println("新增了"+insert);

        List<User> users = userDao.selectList(1,2);
        System.out.println("user分页查询的列表是"+users);

        int delete = userDao.delete(8);
        System.out.println("删除了嘛"+delete);

        User user = userDao.selectAnyOneByPrimary(12);
        System.out.println("根据主键查询的user对象是"+user);

        int update = userDao.update(new User(10, "123456", "123456"));
        System.out.println("修改成功了吗"+update);

    }
}
  • Test result: print with spliced ​​sql statement
    insert image description here
  • Optional: Make it into a jar package for your friends to use (although it is very lj, but it is also my own hard work)
    no matter how bad it is, you can always install it in front of laymen
    insert image description here
  • end flowering

Guess you like

Origin blog.csdn.net/weixin_44834205/article/details/126041911
Recommended