美文网首页
注解,反射的简单应用

注解,反射的简单应用

作者: xc2023 | 来源:发表于2019-03-27 15:45 被阅读0次

    java的注解和反射学了一直没有用到,主要是框架帮我们封装好了,那就好了,仿写框架就可以开拓新思路
    仿mybatis写一个简易的orm框架

    注解 (sql注解)

    /**
     * @author
     * sql操作
    *运行时检查
    *注解标记的位置,在方法上
     * */
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.METHOD)
    public @interface Select {
    
        String value();
    
    }
    

    mapper接口

    /**
     * @author cainiao
     * */
    public interface UserMapper {
    
        @Select(value = "select * from user where id = #{id}")
        User select(int id);
    
        @Insert(value = "insert into user () values ()")
        void insert(User user);
    
        void update(User user);
    
        void delete(int id);
    }
    

    jdbc的工具类,为了简单,就不用数据库连接池

    /**
     * @author 连接数据库
     */
    public class JDBCConfig {
    
        private static String url = null;
        private static String driver = null;
        private static String username = null;
        private static String password = null;
        private static final String file = "db.properties";
        static {
            try {
                InputStream input = JDBCConfig.class.getClassLoader().getResourceAsStream(file);
                Properties properties = new Properties();
                properties.load(input);
                driver = properties.getProperty("driver");
                url = properties.getProperty("url");
                username = properties.getProperty("username");
                password = properties.getProperty("password");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        public static Connection getConnection() throws Exception{
            Class.forName(driver);
            return DriverManager.getConnection(url, username, password);
        }
        public static void getClose(Connection conn, PreparedStatement ps, ResultSet rs){
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    rs=null;
                }
            }
            if(ps!=null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    ps = null;
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }finally{
                    conn = null;
                }
            }
        }
    }
    

    包装数据的工具类

    /**
     * @author cainiao
     * 封装返回数据
     */
    public class MapperUtil {
    
        //增 删 改
        public static int update(String sql,Object...values) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            int rows = -1 ;
            try {
                conn = JDBCConfig.getConnection();
                ps = conn.prepareStatement(sql);
                int len = values.length;
                for(int i = 0;i<len;i++){
                    ps.setObject(i+1, values[i]);
                }
                rows = ps.executeUpdate();
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }finally{
                JDBCConfig.getClose(conn, ps,rs);
                return rows;
            }
        }
        /**
         * 查询
         * */
        public static <T> List<T> query(Class<T> clazz, String sql, Object[] values) {
            Connection conn = null;
            PreparedStatement ps = null;
            ResultSet rs = null;
            List<T> beans = new ArrayList<>();
            try {
                conn = JDBCConfig.getConnection();
                ps = conn.prepareStatement(sql);
                int valueCount = values.length;
                for (int i = 0; i < valueCount; i++) {
                    ps.setObject(i + 1, values[i]);
                }
                rs = ps.executeQuery();
                ResultSetMetaData meta = rs.getMetaData();
                int colum = meta.getColumnCount();
                while (rs.next()) {
                    T bean = clazz.newInstance();
                    for (int i = 0; i < colum; i++) {
                        String label = meta.getColumnName(i + 1);
                        Field field = bean.getClass().getDeclaredField(label);
                        field.setAccessible(true);
                        Object value = rs.getObject(label);
                        field.set(bean, value);
                    }
                    beans.add(bean);
                }
            } catch (Exception e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            } finally {
                JDBCConfig.getClose(conn, ps, rs);
            }
            return beans;
        }
        public static void main(String[] args) {
            ArrayList list = (ArrayList) MapperUtil.query(User.class,"select * from user where id = ?",new Object[]{19});
            for (Object object:list){
                System.out.println((User)object);
            }
        }
    }
    

    简单的java对象

    @Table(value = "user")
    public class User {
    
        @Property(value = "id")
        private int id;
        private String username;
        private String password;
        private String salt;
        private int state;
        private String email;
        private String phone;
        private Date created;
        private Date modified;
    }
    <!--  setter和getter方法 -->
    

    mapper接口没有实现类,要实现其功能需要用到jdk动态代理,这里代理不是做切面用,而是拿到接口的方法的各种参数
    jdk动态代理

    /**
     * @author jdk动态代理
     */
    public class MapperProxy<T> implements InvocationHandler {
    
        private Class<T> target;
        /**
    *存放截取过程中的sql片段
    */
        static List<String> list = new ArrayList<>();
    
        public MapperProxy(Class<T> target) {
            this.target = target;
        }
    
        /**
         * 拿到接口类
         * 代理类
         * 调用的方法
         * 方法的参数值
         */
        @Override
        public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
            //获取返回值类型
            Type type = method.getGenericReturnType();
            //获取参数类型
            Type[] types = method.getGenericParameterTypes();
            //变量名
            Parameter[] parameters = method.getParameters();
            //返回信息
            Object object = null;
            Annotation[] annotations = method.getDeclaredAnnotations();
            for (Annotation annotation : annotations) {
                String name = annotation.annotationType().getSimpleName();
                String sql = null;
                switch (name) {
                    case "Select":
                        sql = method.getDeclaredAnnotation(Select.class).value();
                        object = select(sql, type, args, parameters);
                        break;
                    case "Insert":
                        sql = method.getDeclaredAnnotation(Insert.class).value();
                        break;
                    case "Update":
                        sql = method.getDeclaredAnnotation(Select.class).value();
                        break;
                    case "Delete":
                        sql = method.getDeclaredAnnotation(Select.class).value();
                        break;
                    default:
                }
            }
            return object;
        }
    
        /**
         * 查询方法
         */
        private Object select(String sql, Type type, Object[] args, Parameter[] parameters) throws ClassNotFoundException {
            Class<?> clazz = Class.forName("com.orm.pojo.User");
            StringBuilder sb = new StringBuilder();
            jiequ(sql);
            for (int i = 0; i < args.length; i++) {
                sb.append(list.get(i));
            }
            System.out.println(sb);
            //转为string ,不转会越界报错
            sql = sb + "";
            //执行sql
            List objects = MapperUtil.query(clazz, sql, args);
            if (objects.size() == 1) {
                try {
                    return objects.get(0);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return objects;
        }
    
        private void insert(Type type, Type[] types, Object[] args) {
    
        }
    
        private void update(Type type, Type[] types, Object[] args) {
    
        }
    
        private void delete(Type type, Type[] types, Object[] args) {
    
        }
    
        /**
         * sql截取
         */
        public void jiequ(String sql) {
            if (sql.contains("#")) {
                String[] sqls = sql.split("and", 2);
                for (int i = 0; i < sqls.length; i++) {
                    if (i == 0) {
                        String[] temps = sqls[i].split("\\#");
                        for (int j = 0; j < sqls.length; j++) {
                            if (j == 0) {
                                list.add(temps[j] + "?");
                            }
                        }
                    } else {
                        jiequ(sqls[i]);
                    }
                }
            }
        }
    
        public static void main(String[] args) {
    
        }
    
    }
    

    这里stringbuilder必须先转为String,不然prepareStatement会报越界错误
    创建代理的类

    /**
     * @author
     * */
    public class MapperFactory {
    
        public static <T> T newInstance(Class<T> target){
            MapperProxy mapperProxy = new MapperProxy<T>(target);
            return (T) Proxy.newProxyInstance(Thread.currentThread().getContextClassLoader(),
                    new Class[]{target},mapperProxy);
        }
    }
    

    测试类

    /**
     * @author
     * */
    public class UserService {
        /**
         * 注入mapper
         * */
        private UserMapper userMapper = MapperFactory.newInstance(UserMapper.class);
    
        public void get(int id){
            User user = userMapper.select(id);
            System.out.println(user);
        }
    
        public static void main(String[] args) {
            UserService userService = new UserService();
            userService.get(19);
        }
    }
    

    测试


    aaaa.png

    还有不足,引用pojo类没有动态的获取

    github:https://github.com/cailonghao/Imitation-writing

    相关文章

      网友评论

          本文标题:注解,反射的简单应用

          本文链接:https://www.haomeiwen.com/subject/lgvzvqtx.html