Java学习十四,JDBC,反射

1.JDBC入门

1.1.JDBC的概念

JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序。

1.1 JDBC的基本操作

1.我们先创建数据库jdbctest
在这里插入图片描述
2.我们创建demo.java来操作数据库

package jdbc;

import org.junit.Test;

import java.sql.*;

public class demo1 {
    private ResultSet res = null;
    private Statement statement = null;
    private Connection connection = null;

    /**
     * JDBC的入门程序
     */
    @Test
    public void demo() {
        try {
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获得连接    jdbc:mysql://地址:端口/数据库名称
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
            //3.创建执行sql语句的对象,并且执行sql
            String sql = "select * from user";
            statement = connection.createStatement(); //创建执行的对象
            res = statement.executeQuery(sql);    //执行sql
            //输出
            while (res.next()) {
                int id = res.getInt("uid");
                String name = res.getString("name");
                String username = res.getString("username");
                String password = res.getString("password");
                System.out.println("id:" + id + " name:" + name + " username:" + username + " password:" + password);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.释放资源
            try {
                res.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

1.2 JDBC的API

  • DriverManager类
    作用:
    1. 注册驱动:Class.forName("com.mysql.jdbc.Driver");
    2. 获得连接 :Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
  • Connection类
    作用:
    1. 创建执行SQL语句的对象:
     Statement createStatement();   执行sql语句,有依赖注入的风险
     PreparedStatement prepareStatement(sql);   预编译sql语句,解决依赖注入问题
     CallableStatement prepareCall(sql);    执行sql存储过程
    2. 事务的管理
     connection.setAutoCommit(false); 设置事务是否自动提交
     connection.commit();    事务提交
     connection.rollback();  事务回滚
  • Statement类
    作用:
    1. 执行sql语句
     ResultSet res = statement.executeQuery(sql); 执行select语句,返回结果
     boolean execute = statement.execute(sql); 执行select语句,成功返回true
     int i = statement.executeUpdate(sql);  执行sql中的select/insert/update语句
    2. 执行批量操作
     statement.addBatch(sql);  批量任务的添加
     statement.executeBatch();  批量任务的执行
     statement.clearBatch();  批量任务的清除
  • ResultSet类
    作用:获取结果集(其实就是获得查询语句的结果封装)

1.3 JDBC的CRUD操作(createStatement类)

package jdbc;

import org.junit.Test;

import java.sql.*;

public class crud {
    private Statement statement = null;
    private Connection connection = null;
    private ResultSet resultSet = null;

    /**
     * JDBC查询所有
     */
    @Test
    public void select(){
        try {
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获得连接    jdbc:mysql://地址:端口/数据库名称
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
            //3.创建执行sql语句的对象,并且执行sql
            String sql = "select * from user";
            statement = connection.createStatement(); //创建执行的对象
            resultSet = statement.executeQuery(sql);    //执行sql
            //输出
            while (resultSet.next()) {
                int id = resultSet.getInt("uid");
                String name = resultSet.getString("name");
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                System.out.println("id:" + id + " name:" + name + " username:" + username + " password:" + password);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.释放资源
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }

    /**
     * JDBC的修改
     */
    @Test
    public void del() {
        try {
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获得连接    jdbc:mysql://地址:端口/数据库名称
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
            //3.创建执行sql语句的对象,并且执行sql
            statement = connection.createStatement(); //创建执行的对象
            String sql = "delete from user where uid='3'";
            int res = statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.释放资源
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }



    /**
     * JDBC的修改
     */
    @Test
    public void update() {
        try {
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获得连接    jdbc:mysql://地址:端口/数据库名称
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
            //3.创建执行sql语句的对象,并且执行sql
            statement = connection.createStatement(); //创建执行的对象
            String sql = "update user set username='222222' where name='33'";
            int res = statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.释放资源
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }


    /**
     * JDBC的添加
     */
    @Test
    public void add() {
        try {
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获得连接    jdbc:mysql://地址:端口/数据库名称
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbctest", "root", "root");
            //3.创建执行sql语句的对象,并且执行sql
            statement = connection.createStatement(); //创建执行的对象
            String sql = "insert into user values (null,'11','22','33')";
            int res = statement.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //4.释放资源
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

1.4 JDBC防sql注入(prepareStatement类)

package jdbc;

import org.junit.Test;

import java.sql.*;

public class crud {
    private Statement statement = null;
    private Connection connection = null;
    private ResultSet resultSet = null;

    /**
     * 防止sql注入
     */
    public void security_sql(String usernames,String passwords) {
        PreparedStatement pst=null;
        try {
            //获取连接
            connection = gongju.lianjie();
            //编写sql
            String sql = "select * from user where username=? and password=?";
            //预处理sql
            pst= connection.prepareStatement(sql);
            pst.setString(1,usernames);
            pst.setString(2,passwords);
            //执行sql
            pst.executeQuery(sql);
            //输出
            while (resultSet.next()) {
                int id = resultSet.getInt("uid");
                String name = resultSet.getString("name");
                String username = resultSet.getString("username");
                String password = resultSet.getString("password");
                System.out.println("id:" + id + " name:" + name + " username:" + username + " password:" + password);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            gongju.close(resultSet, statement, connection);
        }
    }
}

1.5 JDBC连接池

在这里插入图片描述
首先必须创建c3p0-config.xml(名字不能随意)

<?xml version='1.0' encoding='UTF-8'?>
<c3p0-config>
    <!--mysql的配置-->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbctest</property>
        <property name="user">root</property>
        <property name="password">root</property>
        <property name="initialPoolSize">10</property>
        <property name="maxPoolSize">100</property>
    </default-config>
</c3p0-config>

其次便可以连接使用了

package jdbc;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.junit.Test;

import java.beans.PropertyVetoException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;


public class lianjiechi {
    /**
     * 手动设置连接池
     */
    @Test
    public void demo() {
        Connection con = null;
        PreparedStatement pstm = null;
        ResultSet rel = null;

        try {
            //创建连接池
            ComboPooledDataSource datasource = new ComboPooledDataSource();
            //设置连接池的参数
            datasource.setDriverClass("com.mysql.jdbc.Driver");
            datasource.setJdbcUrl("jdbc:mysql://localhost:3306/jdbctest");
            datasource.setUser("root");
            datasource.setPassword("root");
            datasource.setInitialPoolSize(2);   //启动初始连接数
            datasource.setMaxPoolSize(20);  //最大连接数
            //获得连接
            con = datasource.getConnection();
            //编写sql
            String sql = "select * from user";
            //预编译sql
            pstm = con.prepareStatement(sql);
            rel = pstm.executeQuery();
            //输出
            while (rel.next()) {
                System.out.println(rel.getInt("uid") + " " + rel.getString("name"));
            }
        } catch (PropertyVetoException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    /**
     * 使用位置文件的方式
     */
    @Test
    public void demo1() {
        Connection con = null;
        PreparedStatement pstm = null;
        ResultSet rel = null;

        try {
            //创建连接池
            ComboPooledDataSource datasource = new ComboPooledDataSource();
            //获得连接
            con = datasource.getConnection();
            //编写sql
            String sql = "select * from user";
            //预编译sql
            pstm = con.prepareStatement(sql);
            rel = pstm.executeQuery();
            //输出
            while (rel.next()) {
                System.out.println(rel.getInt("uid") + " " + rel.getString("name")+" "+rel.getString("Username"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

    }
}

2.反射入门

2.1 反射的概述

JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
在这里插入图片描述

2.2 反射的作用

在日常的第三方应用开发过程中,经常会遇到某个类的某个成员变量、方法或是属性是私有的或是只对系统应用开放,这时候就可以利用Java的反射机制通过反射来获取所需的私有成员或是方法。当然,也不是所有的都适合反射,之前就遇到一个案例,通过反射得到的结果与预期不符。阅读源码发现,经过层层调用后在最终返回结果的地方对应用的权限进行了校验,对于没有权限的应用返回值是没有意义的缺省值,否则返回实际值起到保护用户的隐私目的。

2.3 反射常用对象

类名用途
Class类代表类的实体,在运行的Java应用程序中表示类和接口
Constructor类代表类的构造方法
Field类代表类的成员变量(成员变量也称为类的属性)
Method类代表类的方法

在这里插入图片描述

2.3.1 Class类

获取Class类的方法有3种:

  1. 通过类名.class;
  2. 对象.getclass();
  3. class.forName(); 常用
    Class类代表某个类的字节码,并提供了加载字节码的方法:forName("包名.类名"),forName用于加载字节码到内存中,并封装成一个对象;
package fanshe;

import org.junit.Test;

public class demo {
    /**
     * 获取class的方法
     * 1. 通过类名.class;
     * 2. 对象.getclass();
     * 3. class.forName();
     */
    @Test
    public void demo1() {
        //1.通过类名.class;
        Class<person> personClass1 = person.class;
        //2. 对象.getclass();
        Class<person> personClass2 = (Class<person>) new person().getClass();
        //3. class.forName();
        try {
            Class personClass3 = Class.forName("fanshe.person");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}

2.3.2 Constructor类

方法用途
newInstance(Object… initargs)根据传递的参数创建类的对象
package fanshe;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class demo {

    @Test
    public void demo2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class aClass = Class.forName("fanshe.person");
        Constructor c = aClass.getConstructor();
        person person = (fanshe.person) c.newInstance();    //相当于person person=new person();
        System.out.println(person.eat());
    }

    @Test
    public void demo3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        Class<?> aClass = Class.forName("fanshe.person");
        Constructor<?> c = aClass.getConstructor(String.class, String.class);
        person person= (fanshe.person) c.newInstance("轩轩","女");  //相当于person person=new person("轩轩","女");
        System.out.println(person.eat());
    }
}

分别运行demo2和demo3,得到结果不同:
在这里插入图片描述在这里插入图片描述

2.3.3 Field类

方法用途
setAccessible(boolean)设置变量是否可以访问
getField(String name)获得某个公有的属性对象
getFields()获得所有公有的属性对象(包含父类)
getDeclaredField(String name)获得某个属性对象
getDeclaredFields()获得所有属性对象
package fanshe;

import org.junit.Test;

import java.lang.reflect.Field;

public class demo {


    /**
     * Field类
     * 操作公有属性和私有属性
     */
    @Test
    public void demo4() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //获得class
        Class<?> aClass = Class.forName("fanshe.person");
        person p = (person) aClass.newInstance();   //默认调用无参构造

        //获取属性
        Field name = aClass.getField("name");
        //操作属性

        name.set(p, "李四");
        System.out.println(name.get(p));
    }

    @Test
    public void demo5() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //获取class
        Class<?> aClass = Class.forName("fanshe.person");
        person p = (person) aClass.newInstance();

        //获取属性
        Field sex = aClass.getDeclaredField("sex");

        //设置可以被操作
        sex.setAccessible(true);
        sex.set(p,"不男不女");

        System.out.println(sex.get(p));
    }
}

2.3.4 Method类

方法用途
getMethod(String name, Class…<?> parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class…<?> parameterTypes)获得该类某个方法
getDeclaredMethods()获得该类所有方法
invoke(Object obj, Object… args)传递object对象及参数调用该对象对应的方法
package fanshe;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class demo {


    /**
     * Method类
     * 操作公有方法和私有方法
     */
    @Test
    public void demo6() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class<?> aClass = Class.forName("fanshe.person");
        //实例化
        person p = (person) aClass.newInstance();
        //获取属性
        Field name = aClass.getField("name");
        name.set(p, "花花");
        //获取共有方法
        Method eat = aClass.getMethod("eat");
        //执行方法
        System.out.println(eat.invoke(p));
    }

    @Test
    public void demo7() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException, NoSuchMethodException, InvocationTargetException {
        Class<?> aClass = Class.forName("fanshe.person");
        //实例化
        person p = (person) aClass.newInstance();
        //获取私有方法
        Method run = aClass.getDeclaredMethod("run",String.class);
        run.setAccessible(true);
        System.out.println(run.invoke(p,"小花蛤"));
    }
}

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值