注解|注解,反射的简单应用

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 = "https://www.it610.com/article/select * from user where id = #{id}") User select(int id); @Insert(value = "https://www.it610.com/article/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 List query(Class clazz, String sql, Object[] values) { Connection conn = null; PreparedStatement ps = null; ResultSet rs = null; List 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 = https://www.it610.com/article/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 = "https://www.it610.com/article/user") public class User {@Property(value = "https://www.it610.com/article/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; }

mapper接口没有实现类,要实现其功能需要用到jdk动态代理,这里代理不是做切面用,而是拿到接口的方法的各种参数
jdk动态代理
/** * @author jdk动态代理 */ public class MapperProxy implements InvocationHandler {private Class target; /** *存放截取过程中的sql片段 */ static List list = new ArrayList<>(); public MapperProxy(Class 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 newInstance(Class target){ MapperProxy mapperProxy = new MapperProxy(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

    推荐阅读