1.学习视频:JDBC封装(4)—>直播

    2.学习内容*
    1>封装JDBC的目的:
    1.减少代码的冗余(ORM框架)
    2.增强底层执行的性能(连接池)
    2>复习注解
    1.注解写法
    @XXXX (信息)
    2.注解放置在哪里写
    类 方法 属性 构造 变量 参数(前面)
    3.Java中定义好的注解
    @Deprecated 废弃的
    @Override 检测方法是否是重写
    @SuppressWarnings 去掉程序中的警告(尽量不要用 尽量通过编写代码去掉警告)
    4.如何自己定义注解
    描述一个自己的类 @interface
    类的上面通过元注解来描述
    @Target
    @Retention
    @Inherited
    想要携带一些信息 自定义注解类型 添加方法
    方法要求必须有返回值 返回值类型:
    基本 String 枚举 注解 数组
    方法的作用:将我们传递的信息 搬走了 交给别人
    5.注解的作用
    充当注释 仅仅是一个文字说明
    代码检测 @Override
    携带信息
    6.如何访问到注解对象 @XXX—>定义
    如何获取里面的信息(需要反射机制)
    反射读取注解内的SQL

    1. 3>代理模式<br />为其他对象提供一个代理以控制对某个对象的访问。代理类主要负责为委托了(真实对象)预处理消息、过滤消息、传递消息给委托类,代理类不现实具体服务,而是利用委托类来完成服务,并将执行结果封装处理。<br />其实就是代理类为被代理类预处理消息、过滤消息并在此之后将消息转发给被代理类,之后还能进行消息的后置处理。代理类和被代理类通常会存在关联关系(即上面提到的持有的被带离对象的引用),代理类本身不实现服务,而是通过调用被代理类中的方法来提供服务。<br />静态代理<br />创建一个接口,然后创建被代理的类实现该接口并且实现该接口中的抽象方法。之后再创建一个代理类,同时使其也实现这个接口。在代理类中持有一个被代理对象的引用,而后在代理类方法中调用该对象的方法。<br />动态代理<br />利用反射机制在运行时创建代理类。<br />动态代理具体步骤:
    2. 1. 通过实现 InvocationHandler 接口创建自己的调用处理器;
    3. 1. 通过为 Proxy 类指定 ClassLoader 对象和一组 interface 来创建动态代理类;
    4. 1. 通过反射机制获得动态代理类的构造函数,其唯一参数类型是调用处理器接口类型;
    5. 1. 通过构造函数创建动态代理类实例,构造时调用处理器对象作为参数被传入。

    链接:https://www.jianshu.com/p/9bcac608c714—>详解代理模式(来自简书)

    3.练习的代码—>查询单条已及多条sql语句(任何表格都可)—其中含有反射

    1. //设计一个方法 将rs结果集的值取出 存入一个新的容器中
    2. Object handleResult(ResultSet rs, Class resultType) throws SQLException {
    3. Object result = null;
    4. if(resultType==int.class || resultType==Integer.class){
    5. result = rs.getInt(1);
    6. }else if(resultType==float.class || resultType==Float.class){
    7. result = rs.getFloat(1);
    8. }else if(resultType==String.class){
    9. result = rs.getString(1);
    10. }else{
    11. // map domain
    12. if(resultType== Map.class){ //map
    13. result = this.getMap(rs);
    14. }else{ //domain
    15. result = this.getObject(rs,resultType);
    16. }
    17. }
    18. return result;
    19. }
    20. //设计一个方法 负责帮助handleResult方法拼接 map类型
    21. //只需要提供给handleResult一个方法使用 private就够了
    22. private Map getMap(ResultSet rs) throws SQLException {
    23. //创建一个Map对象-->用来存放列名和其对应值
    24. Map result = new HashMap<String,Object>();
    25. //将结果集的信息取出
    26. ResultSetMetaData rsmd = rs.getMetaData();
    27. //对该信息进行遍历
    28. for(int i=1;i<=rsmd.getColumnCount();i++){//结果集的列从1开数的,循环是小于等于列名
    29. //获取结果集中查询到的列名
    30. String columnName = rsmd.getColumnName(i);
    31. //通过列名获取 列值
    32. Object value = rs.getObject(columnName);
    33. //存入map集合中
    34. result.put(columnName,value);
    35. }
    36. return result;
    37. }
    38. //设计另一个方法 负责帮助handleResult方法拼接对象
    39. private Object getObject(ResultSet rs,Class resultType) throws SQLException {
    40. Object obj = null;//存储最后的值
    41. try {
    42. //通过反射创建一个domain类型的对象
    43. obj = resultType.newInstance();//调用了一个默认无参数的构造方法创建了一个对象 new Bank
    44. //通过rs取值 存入obj中
    45. ResultSetMetaData rsmd = rs.getMetaData();
    46. for(int i=1;i<=rsmd.getColumnCount();i++){//遍历结果集
    47. //获取结果集中的每一个列名
    48. String columnName = rsmd.getColumnName(i);
    49. //获取对应列名的值 写列名或者i都可以
    50. Object value = rs.getObject(columnName);
    51. //根据columnName反射找到obj中的某一个属性 操作属性将value存入
    52. //Field field = resultType.getDeclaredField(columnName);
    53. Field field = obj.getClass().getDeclaredField(columnName);
    54. //修改属性权限
    55. field.setAccessible(true);//其实应该找寻属性对应的set方法 invoke那个set方法
    56. //直接操作私有属性 取值
    57. field.set(obj,value);
    58. //操作属性 给属性赋值
    59. //Atm atm = new Atm(); Atm atm = clazz.newInstance();
    60. // Field field = clazz.getField(); filed--->aname
    61. //atm.setAname("zzt"); field.set(atm,"zzt");
    62. }
    63. } catch (InstantiationException e) {
    64. e.printStackTrace();
    65. } catch (IllegalAccessException e) {
    66. e.printStackTrace();
    67. } catch (NoSuchFieldException e) {
    68. e.printStackTrace();
    69. }
    70. return obj;
    71. }
    1. public <T>T selectList(String sql,Object obj,Class resultType){
    2. try {
    3. //0.创建一个用来存储最终返回值的变量
    4. ArrayList<T> List = new ArrayList<T>();
    5. //1.解析SQL
    6. //keyList{aname,apassword,abalance} 按照解析顺序存储的key
    7. //newSQL--->还原成原来那种带有问号的形式--->pstat对象才认识
    8. SQLAndKey sqlAndKey = handler.parseSQL(sql);
    9. //2.加载驱动
    10. Class.forName(className);
    11. //3.获取连接
    12. Connection conn = DriverManager.getConnection(url, user, password);
    13. //4.状态参数(newSQL)
    14. PreparedStatement pstat = conn.prepareStatement(sqlAndKey.getSQL());//调用sqlAndKey获取没有标识符含 ? 的sql语句
    15. //5.将SQL和值拼接在一起
    16. if(obj!=null){
    17. handler.handleParameter(pstat,obj,sqlAndKey.getKeyList());
    18. }/** 如果1个值 直接拿来用
    19. * 设计一个方法 好多类型判断
    20. * 如果n个值 遍历keyList
    21. * 每一次循环拿到一个key
    22. * 根据key去容器(map,domain)中获取值
    23. * pstat.setObject(位置,值)
    24. */
    25. //6.执行
    26. ResultSet rs = pstat.executeQuery();
    27. while(rs.next()){
    28. //7.将结果集中的数据取出---存入一个新的容器类
    29. List.add((T)handler.handleResult(rs,resultType));
    30. }
    31. //8.关闭
    32. rs.close();
    33. pstat.close();
    34. conn.close();
    35. } catch (Exception e) {
    36. e.printStackTrace();
    37. }
    38. //返回最终对象
    39. return List;
    40. }
    41. //重载hhh 如果obj==null,可以直接调这个方法啦
    42. public <T> List<T> selectList(String sql,Class resultType){
    43. return this.selectList(sql,null,resultType);
    44. }
    45. //设计一个方法 可以查询任何一个表格单条语句
    46. public <T> T selectOne(String sql,Object obj,Class resultType){
    47. return (T)this.selectList(sql,obj,resultType).get(0);
    48. }
    1. //查询多条方法
    2. public List<Bank> selectAll(){
    3. String sql = "select * from bs";
    4. return sqlSession.selectList(sql,null,Bank.class);
    5. }
    6. //查询单条
    7. public Bank selectOne1(String bname){
    8. String sql = "select * from bs where bname = #{bname}";
    9. return sqlSession.selectOne(sql,bname,Bank.class);
    10. }
    11. public static void main(String[] args) {
    12. BankDao dao = new BankDao();
    13. //List<Bank> list = dao.selectAll();
    14. Bank bank = dao.selectOne1("小小");
    15. System.out.println(bank);
    16. }

    总结:
    这次的直播讲解了查询SQL语句的方法,这种方法可以查询单条或者多条语句,该方法用到了反射机制,跟昨天讲解的增删改方法有相似之处,昨天的听懂了,所以今天的理解也比较容易。

    不足之处:
    在反射方面,没有很好的掌握,在老师提到时,不能很快想到,对其中的方法用法学习也只是在皮毛上……