admin管理员组

文章数量:1122854

Java学习十四,JDBC,反射

目录

  • 1.JDBC入门
    • 1.1.JDBC的概念
    • 1.1 JDBC的基本操作
    • 1.2 JDBC的API
    • 1.3 JDBC的CRUD操作(createStatement类)
    • 1.4 JDBC防sql注入(prepareStatement类)
    • 1.5 JDBC连接池
  • 2.反射入门
    • 2.1 反射的概述
    • 2.2 反射的作用
    • 2.3 反射常用对象
      • 2.3.1 Class类
    • 2.3.2 Constructor类
      • 2.3.3 Field类
      • 2.3.4 Method类

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的入门程序*/@Testpublic 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语句的对象,并且执行sqlString 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查询所有*/@Testpublic 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语句的对象,并且执行sqlString 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的修改*/@Testpublic 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语句的对象,并且执行sqlstatement = 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的修改*/@Testpublic 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语句的对象,并且执行sqlstatement = 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的添加*/@Testpublic 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语句的对象,并且执行sqlstatement = 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();//编写sqlString sql = "select * from user where username=? and password=?";//预处理sqlpst= connection.prepareStatement(sql);pst.setString(1,usernames);pst.setString(2,passwords);//执行sqlpst.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 {/*** 手动设置连接池*/@Testpublic 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();//编写sqlString sql = "select * from user";//预编译sqlpstm = 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();}}/*** 使用位置文件的方式*/@Testpublic void demo1() {Connection con = null;PreparedStatement pstm = null;ResultSet rel = null;try {//创建连接池ComboPooledDataSource datasource = new ComboPooledDataSource();//获得连接con = datasource.getConnection();//编写sqlString sql = "select * from user";//预编译sqlpstm = 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();*/@Testpublic 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 {@Testpublic 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());}@Testpublic 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类* 操作公有属性和私有属性*/@Testpublic void demo4() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {//获得classClass<?> aClass = Class.forName("fanshe.person");person p = (person) aClass.newInstance();   //默认调用无参构造//获取属性Field name = aClass.getField("name");//操作属性name.set(p, "李四");System.out.println(name.get(p));}@Testpublic void demo5() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {//获取classClass<?> 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类* 操作公有方法和私有方法*/@Testpublic 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));}@Testpublic 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,"小花蛤"));}
}

本文标签: Java学习十四JDBC反射