元数据与动态代理
元数据
通过元数据我们可以获得java代码执行的sql语句参数的个数,与参数的类型。也可以通过元数据获得java代码查询数据库得到的参数个数和参数类型。
获取参数元数据
1.通过PrepareStatement的getParameterMetaData的方法获取参数元数据对象ParameterMetaData
2.ParameterMeatData方法介绍
int getParameterCount() 获取参数的个数 String getParameterTypeName(int index) 获取参数的类型,方法的参数为要获得哪一列的参数类型,但是mysql不支持 Class.forName("com.mysql.jdbc.Driver"); //获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/day23","root","root"); String sql = "select * from contact where id=?"; //获取预编译对象 PreparedStatement ps = connection.prepareStatement(sql); //得到参数元数据对象 ParameterMetaData pmd = ps.getParameterMetaData(); //获取并打印sql语句的参数个数 System.out.println(pmd.getParameterCount()); ps.close(); connection.close();
获取结果的元数据
1.通过PrepareStatement对象的executeQuery()方法获得到的ResultSet对象,调用getMetaData()获取结果集元数据对象ResultSetMetaData
2.ResultSetMetaData常用方法介绍
String getColumnName(int i) 获取指定序号的列的列名 String getColumnTypeName(int i) 获取指定序号列的数据类型 Class.forName("com.mysql.jdbc.Driver"); //获取连接 Connection connection = DriverManager.getConnection("jdbc:mysql://localhost/day23", "root", "root"); String sql = "select * from contact"; //获取预编译对象 PreparedStatement ps = connection.prepareStatement(sql); //获得查询结果集对象 ResultSet resultSet = ps.executeQuery(); //获取结果的数据类型 ResultSetMetaData metaData = resultSet.getMetaData(); //获取查询到的列数 int columnCount = metaData.getColumnCount(); for(int i=1;columnCount>=i;i++){ //获取查询到的指定列的列名 获取查询的结果指定列的数据类型 System.out.println(metaData.getColumnName(i)+" "+metaData.getColumnTypeName(i)); } ps.close(); connection.close();
动态代理
代理模式的作用
代理对象可以对被代理对象的方法进行增强
代理模式分为静态代理和动态代理
使用静态代理的条件 你要增强的对象可以被继承,如果不可以被继承就不是使用静态代理
使用动态代理的条件 你要增强的对象必须要实现了接口,如果没有实现任何接口就不能使用动态代理
动态代理的使用
我们现在要对List集合的add方法进行增强,当添加数据前打印要添加数据了,添加成功显示添加数据成功
// Proxy java的动态代理对象 newProxyInstance为创建代理代理方法 //参数1:为ClassLoader 需要获得类加载器,一般为 当前类名.class.getClassLoader //参数2:要代理的对象实现的接口Class对象数组 //参数3:InvocationHandler接口的实现类 List<String> list = (List<String>)Proxy.newProxyInstance(Dome05.class.getClassLoader(), new Class[]{List.class}, new InvocationHandler() { //动态代理里面要维护 一个被代理对象 //其实动态代理只是增强原对象的一些方法,使用他只是在被代理对象的方法运行前和方法运行后面作一些处理,所以需要用到被代理对象 List<String> list = new ArrayList<>(); @Override //invoke方法,动态代理对象调用方法就会执行这一个方法 // 参数1:proxy,该对象就是被代理的对象,基本不在该方法里面使用这个参数 //参数2:method,为你调用的方法对象 //参数3:args ,为你调用方法传入的参数 public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //判断调用的方法是不是需要增强的方法 if("add".equals(method.getName())){ //增强处理 System.out.println("要添加数据了哦"); Object o = method.invoke(list,args); System.out.println("添加数据成功"); //返回 method.invoke()方法的返回值 return o; } //其他不需要增强的方法 就调用被代理对象的对应方法 return method.invoke(list,args); } });