栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java入门--------JDBC4(尚马day25) week6(6)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java入门--------JDBC4(尚马day25) week6(6)

7. 反射(了解) 7.1 问题
所有的CRUD的功能实现  
  1. 获得连接
  2. 准备sql
  3. 预编译sql(将sql发送到数据库中)
  4. 占位符进行赋值---->麻烦
  5. 执行sql
     executeUpdate()/executeQuery()
  6. dql: select
      rs.get ---->麻烦

public static  T findOne(String sql, Class tClass, Object... params) {
    Connection connection = getConn();
    T t = null;
    try {
        PreparedStatement statement = connection.prepareStatement(sql);
        //占位符赋值
        int length = params.length;
        for (int index = 0; index < length; index++) {
            statement.setObject((index + 1), params[index]);
        }
        //执行sql
        ResultSet rs = statement.executeQuery();
        if (rs.next()) {
​
            //创建对象的方式: 反射
            t = tClass.getDeclaredConstructor().newInstance();
            //查询的临时表的数据在rs对象中
            //需要将指定的行记录转换成指定的对象
            //在rs里面: 获得查询的列  查询列对应的数据
            ResultSetmetaData metaData = rs.getmetaData();
            int columnCount = metaData.getColumnCount();//查询列数
            for (int i = 1; i <= columnCount; i++) {
                String columnName = metaData.getColumnName(i);//获得每列的名称
                //获得每个列的具体的数据类型---->java语言里面具体的类型
                String columnClassName = metaData.getColumnClassName(i);
                //获得每列的数据
                Object columnValue = rs.getObject(i);
                //列的数据赋值给类属性----> private  set
                //调用set方法进行对属性赋值  setId  setName  setPassword  setUserImage
                StringBuilder methodName = new StringBuilder("set");
                String[] array = columnName.split("_");
​
                for (String str : array) {
                    String firstChar = String.valueOf(str.charAt(0));
                    str = str.replaceFirst(firstChar, firstChar.toUpperCase());
                    methodName.append(str);
                }
                // System.out.println(columnName + "=====" + columnValue + "-----" + columnClassName+"----"+ Arrays.toString(array)+"----"+methodName);
                //调用这个方法 类名.静态方法  /  引用.方法
                //使用反射的知识点 唤醒方法 invoke指定的方法  -----> Class
                //反射的基础是  Class
                //获得Class类对象的3种方式:  getClass  类名.class  Class.forName()
​
                //根据指定的方法名  调用方法
                //public Method getDeclaredMethod(String name, Class... parameterTypes) name:方法名  parameterTypes:方法的参数类型
                if (columnClassName.contains("Date") || columnClassName.contains("Timestamp")) {
                    columnClassName = "java.util.Date";
                }
                Method method = tClass.getDeclaredMethod(methodName.toString(), Class.forName(columnClassName));//一个方法就封装成method对象
​
                //调用方法
                //public Object invoke(Object obj, Object... args)  obj: 对象   args:实参 应该是列的数据
                method.invoke(t, columnValue);
            }
        }
​
    } catch (Exception throwables) {
        throwables.printStackTrace();
    }
    return t;
}
​

7.2 概念

java语言具有动态性。

java语言 不是一门动态的语言。  有反射机制,java有动态性。
动态语言:
   在程序运行期间 可以使用一些技术更改整个类的结构。
动态性:
  在程序运行期间  可以内省整个class文件的里面的所有的内容。
  
​
首先,反射机制极大的提高了程序的灵活性和扩展性,降低模块的耦合性,提高自身的适应能力。
其次,通过反射机制可以让程序创建和控制任何类的对象,无需提前硬编码目标类。
再次,使用反射机制能够在运行时构造一个类的对象、判断一个类所具有的成员变量和方法、调用一个对象的方法。
最后,反射机制是构建框架技术的基础所在,使用反射可以避免将代码写死在框架中。
​
​
缺点:
1. 性能问题:使用反射基本上是一种解释操作,用于字段和方法接入时要远慢于直接代码。因此反射机制主要应用在对灵活性和拓展性要求很高的系统框架上,普通程序不建议使用。
2. 使用反射会模糊程序内部逻辑;程序员希望在源代码中看到程序的逻辑,反射却绕过了源代码的技术,因而会带来维护的问题,反射代码比相应的直接代码更复杂。

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键

换句话说,Java程序可以加载一个运行时才得知名称的class,获悉其完整构造(但不包括methods定义),并生成其对象实体、或对其fields设值、或唤起其methods。这种“看透class”的能力(the ability of the program to examine itself)被称为introspection(内省、内观、反省)。Reflection和introspection是常被并提的两个术语

7.3 操作
把class文件分割以下几个部分:
  //1.属性----Field
  //2.方法----Method
  //3.构造----Constructor
1. 操作属性
private static void testField() {
​
        //反射操作属性: 取值/赋值----> Class
        //1.必须获得Class对象
        // 对象.getClass();
        // 类名/接口.class
        // Class.forName(String path)
        try {
            Class aClass = Class.forName("com.javasm.reflect.Animal");
           
​
            //使用反射创建Animal对象----> 默认调用无参构造
            //Object instance = aClass.newInstance();
           
​
            Constructor constructor = aClass.getDeclaredConstructor(int.class, String.class);
            constructor.setAccessible(true);
            Object newInstance = constructor.newInstance(11111, "张三");
            System.out.println(newInstance);
​
            //num进行取值/赋值
            Field field = aClass.getDeclaredField("num");
            System.out.println(field);
            field.setAccessible(true);
​
            //public Object get(Object obj)  obj:具体类型的对象
            Object data = field.get(newInstance);
            System.out.println(data);
            //field.set(instance,1000);
            //System.out.println(field.get(instance));
​
​
        } catch (Exception e) {
            e.printStackTrace();
        }
​
​
    }

2. 操作方法
private static void testMethod() {
​
​
    try {
        //使用反射技术调用myMethod
        Class aClass = (Class) Class.forName("com.javasm.reflect.Animal");
​
        Animal animal = aClass.getDeclaredConstructor().newInstance();
        
​
        Method myMethod = aClass.getDeclaredMethod("myMethod", String.class);
​
        Object returnData = myMethod.invoke(animal, "张三");
        System.out.println(returnData);
    } catch (Exception e) {
        e.printStackTrace();
    }
​
}

8. DBUtils

简化JDBC操作。

所有的CRUD的功能实现  
  1. 获得连接
  2. 准备sql
  3. 预编译sql(将sql发送到数据库中)
  4. 占位符进行赋值---->麻烦
  5. 执行sql
     executeUpdate()/executeQuery()
  6. dql: select
      rs.get ---->麻烦----> 将每一行记录自动的装配成对象
      

8.0 常用API
1. QueryRunner  sql执行器
   执行任意一条sql语句。
   1.1 常用构造
  
       public QueryRunner(DataSource ds) { 
          super(ds);
       }
   1.2 常用方法
     int update(Connection conn, String sql, Object... params);
      执行DMLsql   返回值是受影响记录数。
    
     T query(String sql, ResultSetHandler rsh, Object... params)
   
 
2. DbUtils 工具类。 里面封装了一些释放资源以及与事务相关的方法。
   void closeQuietly(Connection conn);关闭连接
  
3. ResultSetHandler: 将ResultSet里面的每一行记录装配成指定的类对象  反射
​
   public interface ResultSetHandler {
    T handle(ResultSet rs) throws SQLException;
    }
    
​
ScalarHandler: 将指定1列的数据转换成对象。 一行一列
   count  last_insert_id  max min avg sum

8.1 新增
@Override
public int addUserInfo(UserInfo userInfo) throws SQLException {
​
    Connection connection = DBUtil.getConn();
    //执行sql: 结构化查询语言
    //对于DBUtils而言  所有的sql语句执行 都必须使用QueryRunner进行执行sql
​
    //1. 更新 DML  INSERT DELETE UPDATE   executeUpdate()  update()
    //2. 查询 DQL SELECT  executeQuery()  query()
    int result = new QueryRunner().update(connection, UserInfoSql.ADD_USER_SQL,
                                          userInfo.getName(),
                                          userInfo.getGender(),
                                          userInfo.getPhone(),
                                          userInfo.getAge(),
                                          userInfo.getBalance(),
                                          userInfo.getPassword(),
                                          userInfo.getBirthday(),
                                          userInfo.getUserImage());
    //在DBUtils.jar里面  提供一个工具类  DBUtils
    DbUtils.closeQuietly(connection);
    return result;
}
9. 数据库连接池

打开一次连接 操作使用一次 就释放资源。 资源很浪费。

在程序运行期间 多次重复有效的使用可用的连接对象? 实现资源的重复利用率、

9.1 原理

9.2 使用

https://mvnrepository.com/artifact/com.alibaba/druid/1.2.8

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/768805.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号