java学习笔记8

本文详细介绍了数据库中的表关系(一对多、多对多)、数据库的三大范式、多表查询(内连接、外连接、子查询)以及视图的创建与使用。此外,还深入探讨了Java反射技术,包括获取类、构造器、成员变量和方法对象,以及如何通过反射创建对象、设置属性值和调用方法。最后,提到了动态代理的概念及其在Java中的实现,并展示了JDBC的基本操作,如DDL、DML和DQL语句的执行。
摘要由CSDN通过智能技术生成

1.表和表之间的关系

一对多的关系:
      分类表和商品表
      部门表和员工表
 多对多的关系
      采用中间表      学生表和课程表
      

2.数据库的三大范式

三大范式:呈递次规范(每一个都依赖上一次);
1Nf:第一次范式
数据库表中的每一列都是不可在拆分的原子数据
2NF:第二范式
满足第一范式的基础上
每一张表的非主键字段必须完全依赖与主键字段,不能产生部分依赖
3NF:第三范式
满足第二范式的基础上,非主键字段必须完全依赖主键字段,非主键字段不能产生传递依赖

3.多表查询

分类:
   内连接查询(连接调试及室内不多得情况下,尽量采用隐式内连接)
       隐式内连接
 where语句作为条件
 语法:
 select 
    字段列表    1)查询哪些字段
from 
    表名1,表名2 2)查询哪些表
where       
    连接条件;   3)连接条件
 举例:
 查询部门表和员工表的所有信息

 SELECT 
    *
FROM
    emp, 员工表
    dept 部门表
WHERE 
    emp.`dept_id` = dept.`id` ;
       显示内连接
  语法:
  select
        字段类别
    from
        表名1
    inner join 表名2
    on 
        连接条件;
举例:
 查询员工表的信息,同时关联查询部门表的部门名称

 SELECT
     e.id '员工编号',
     e.`NAME` '员工姓名',
     e.`gender` '性别',
     e.`join_date` '入职日期',
     d.`name` '部门名称'
FROM
      emp e
INNER JOIN  dept d  -- inner 可以省略不写
ON 
    e.`dept_id` = d.`id` ;
    外连接查询
        左外连接
   可以将表名1中所有的数据全部查询以及他们的交集的数
   语法:
    select
            字段列表
        from    表名1
        left outer(outer可以省略) join 表名2   
        on
            连接条件;
  举例:查询所有员工的信息以及他们的部门名称
 
 SELECT
    e.*, -- 显示所有员工信息
    d.`name` '部门名称'
FROM
    emp e -- 将emp表数据全部查询
LEFT  JOIN  -- 中间outer省略
    dept d 
ON
    e.`dept_id` = d.`id` ;
        右外连接
   将右表中所有的数据全部查询以及他们的交集的数
   语法:
    select
            字段列表
        from    表名1
        right outer join 表名2
        on
            连接条件;
    子查询
       情况1:单行单列
       利用where条件后面可以携带比较运算符<=,>=,<,>,赋值运算符=
    举例:查询工资最高的员工的信息
    select max(salary) from emp;
       情况2:多行多列
       查询数据的时候,利用or或者in语句,
    举例:查询在2号或者3号部门的员工的信息
   
 SELECT 
  emp.`id` '员工编号',
  emp.`NAME` '员工姓名',
  emp.`gender` '性别',
  emp.`salary` '工资',
  emp.`join_date` '入职日期',
  emp.`dept_id` '部门编号' 
FROM
  emp 
WHERE dept_id IN 
  (SELECT 
    id 
  FROM
    dept 
  WHERE NAME = '市场部' 
    OR NAME = '财务部') ;
  子查询之复杂查询
  举例:查询入职日期大于'2019-03-14'号的员工信息以及所在部门的信息
  
SELECT
    e.`id` '员工编号',
    e.`NAME` '员工姓名',
    e.`gender` '性别',
    e.`salary` '工资',
    e.`join_date` '入职日期',
    d.`name` '部门名称'
FROM 
    emp e , -- 员工表
    dept d  -- 部门表
WHERE
    e.`join_date` > '2019-03-14' 
    AND 
    e.`dept_id` = d.`id` ;
视图
创建视图:
 create view 视图名 as select语句;
 举例:
 CREATE VIEW 
    myview -- 一张虚表:名称 myview
 AS
    SELECT id,NAME,gender,age FROM stu_test
     WHERE  id < 4 ;
修改或者添加/删除的时候,可能会造成基本的数据被更改,
添加视图的检查语言:当前虚拟表中不满足条件的时候,直接报错
修改视图:
alter view 视图名字 as select 语句 条件查询 with check option;
有得情况不能修改视图
1.当基本表使用聚合函数的时候
2.视图中不能使用系统或者用户变量的
3.临时表中不能创建视图

4.数据库的事务

事务的概念:
 在执行某个业务功能中,当这个业务功能他能同时执行多个sql语句的时候,将这多个sql语句的执行过程看成一个整体,要么同时执行成功,要么同时执行失败.
 举例:转账
START TRANSACTION ;开启事务
UPDATE account SET balance = balance - 500 WHERE id = 1 ;
UPDATE account SET balance = balance + 500 WHERE id = 2 ;
如果没有问题就提交事务
commit 提交事务
如果出现了问题,直接回滚
rollback;
事务出现的本身,就是为了解决业务出现的不正常的数据,特点:
ACID:传统型事务
--  原子性:事务是一个不可再拆分的,是一个整体;
-- 一致性:事务在操作业务数据的前后,总量保持不变的
-- 隔离性:事务和事务之间,不能互相影响
-- 持久性:对数据的修改,一旦提交commit,对数据的操作都是永久性的.

5.反射

定义:
   jvm在加载类的时候,引导类加载器--校验java代码的而语法,如果语法存在问题,编译报错,没有问题--执行代码.
宗旨:
    要想获取类的或者接口的字节码文件对象
        获取构造器对象Constructor,创建对象
        获取成员变量所在的对象Field,给成员变量赋值
        获取成员方法所在的对象Method,调用成员方法并去使用它;
java代码的三个阶段
 source:源码阶段
 class:编译--类加载阶段
 runtime:运行阶段
 三种获取字节码文件对象的方法
 public class RelectDemo {
​
    public static void main(String[] args) throws ClassNotFoundException {
​
        //创建两个Person对象
       // Person p = new Person() ;
      //  Person p2 = new Person() ;
       // System.out.println(p);
        //System.out.println(p2);
       // System.out.println(p == p2) ;
​
        System.out.println("--------------------------------") ;
​
        //如何获取类的字节码文件对象
        //方式1:Object类的getClass() 获取
        //public final Class<?> getClass()
       /* System.out.println(p.getClass());  //class 包名.类名 (class com.qf.reflect_01.Person)
        System.out.println(p2.getClass());
        System.out.println(p.getClass() == p2.getClass()) ;*/
​
        System.out.println("--------------------------------") ;
​
        //方式2:任意Java类型(自定义类型/sun公司提供任意的类)的class属性
        Class personClazz = Person.class ;
        System.out.println(personClazz);//class com.qf.reflect_01.Person
       // System.out.println(personClazz == p2.getClass());
​
        System.out.println("--------------------------------") ;
        //方式3:反射类中字节码文件对象 Class 里面静态方法,返回值是当前类本身 ,参数为String
        //public static Class<?> forName(String className) throws ClassNotFoundException :使用比较多的功能,因为参数为String,可以作为配置文件的内容
       // Class c = Class.forName("Person");//参数必须是类的全限定名称:包名.类名
        Class c = Class.forName("com.qf.reflect_01.Person");//参数必须是类的全限定名称:包名.类名
​
        System.out.println(c); //class com.qf.reflect_01.Person
        System.out.println(c==personClazz);
      //  System.out.println(c==p2.getClass());
​
        /*
        *
        * 总结:获取类的或者接口
        * 的字节码文件对象有三种方式
        *   1)Object类的getClass()方法 ---对象名.getClass()
        *   2)任意Java类型的class属性 ---- 类名/接口名.class
        *   3)Class类中的静态方法
        *       Class.forName("类或者接口的全限定名称") ; //包名.类名:全限定名称
        * */
    }
​
}

5.1通过反射获取类的构造器对象Constructor

public class ReflectDemo2 {
​
    public static void main(String[] args) throws Exception {
​
        //没有使用反射
        Person p = new Person();
​
        System.out.println(p);
​
        System.out.println("----------------------------------");
​
        //使用反射--获取构造方法所在的Constructor对象 ---->创建类的实例
        //1)获取当前类的字节码文件对象  class xx_01.Person
        Class c = Class.forName("com.qf.reflect_01.Person");
        //System.out.println(c);
​
        //2)通过Class类中:获取这个类所有的公共的构造方法
        //public Constructor<?>[] getConstructors()
        //public Constructor<?>[] getDeclaredConstructors():获取这个类中所有的构造方法,包括私有,或者受保护的
//        Constructor[] constructors = c.getConstructors();
      /*  Constructor[] constructors = c.getDeclaredConstructors();
        for(Constructor con : constructors){
            System.out.println(con) ;*/
            /*
            * public com.qf.reflect_01.Person(java.lang.String,int)
             public com.qf.reflect_01.Person()
            *
            *
            * private com.qf.reflect_01.Person(java.lang.String,int,java.lang.String)
             public com.qf.reflect_01.Person(java.lang.String,int)
             com.qf.reflect_01.Person(java.lang.String)
             public com.qf.reflect_01.Person()
            * */
        // }
​
        //获取单个的公共的构造方法所在的Constructor
        //public Constructor<T> getConstructor(Class<?>... parameterTypes)
        //参数:参数类型的class---->就是类型的字节码文件对象 :可变参数,可能有参数类型
        Constructor con = c.getConstructor();
        //通过Constructor 创建当前类实例 public T newInstance(Object... initargs) :参数:实际参数 值
        Object obj = con.newInstance();
        System.out.println(obj);
​
        System.out.println("-------------------------------------");
​
        /**
         * 之前的写法
         *  Person p = new Person("高") ;
         *  输出p
         */
//         Person p2  = new Person("高") ;
​
        //反射的创建创建带一个参数的类的实例
        // Person(String name){
        //        this.name = name ;
        //    }
​
        //public Constructor<T> getDeclaredConstructor(Classs<?>... parameterTypes):获取单个的指定的构造方法,参数为参数类型的class
        Constructor constructor = c.getDeclaredConstructor(String.class);//参数类型的字节码文件对象
        System.out.println(constructor);
        //当前获取的构造方法Constructor:是一个默认的并不是公共的,所以要使用取消Java语言访问检查
        //public void setAccessible(boolean flag)
        constructor.setAccessible(true);//参数为true 取消Java语言访问检查
        //创建当前类的实例(Person)
        Object myObject = constructor.newInstance("高") ;
        System.out.println(myObject) ;
​
​
        System.out.println("------------------------------------")  ;
​
​
//        之前写法
        Person p2 = new Person("高",42) ;
        System.out.println(p2);
        System.out.println("-----------------------------------------------------");
        //通过反射获取public Person(String name,int age){} 创建Person类实例
​
        //获取Person类的字节码文件对象
        Class personClazz = Class.forName("com.qf.reflect_01.Person") ;
        //获取构造器方法所在的Constructor对象
        Constructor personCon = personClazz.getConstructor(String.class,int.class) ;
        //创建当前Person类的实例
        Object personObj = personCon.newInstance("赵", 45);
        System.out.println(personObj) ;
​
        System.out.println("---------------------------------------------") ;
​
        //使用反射之前
       // Person p3 = new Person("高",42,"西安市鄠邑区") ;
​
        //private Person(String name,int age,String address){} 创建Person类实例
        //获取Person类的字节码文件对象
        Class personClazz2 = Class.forName("com.qf.reflect_01.Person") ;
        //获取构造方法所在的Constructor对象:指定的构造方法
        Constructor personCon2 =
                personClazz2.getDeclaredConstructor(String.class, int.class, String.class);
​
        //取消java语言访问检查public void setAccessible(boolean flag)
        personCon2.setAccessible(true) ;
        //创建当前类实例
        Object personObj2 = personCon2.newInstance("李", 39, "北京市朝阳区");
        System.out.println(personObj2) ;
​
        System.out.println("---------------------------------------------") ;
​
        //另外一种方式:创建当前类实例
        //只要能够获取当前类的字节码文件对象Class  ---- 直接newInstance
        //public T newInstance()
        Class myClazz = Class.forName("com.qf.reflect_01.Person");
        Object personObj3 = myClazz.newInstance(); //默认执行的这个了无参构造方法,公共的
        System.out.println(personObj3);
    }
​
}
​

5.2通过反射获取成员变量的类对象,并且进行赋值

public class ReflectDemo3 {
    public static void main(String[] args) throws Exception {
​
        //之前的给成员变量赋值
      /*  Person p = new Person() ;
        p.address  = "西安市" ;
        System.out.println(p);*/
​
      //现在要使用反射的方式
        //1)获取当前类的字节码文件对象
        Class personClazz = Class.forName("com.qf.reflect_01.Person") ;
        //2)通过反射获取成员变量所在的Field类对象
        //public Field[] getFields():获取所有的公共的字段的类对象
//        Field[] fields = personClazz.getFields();
        //public Field[] getDeclaredFields():获取所有的字段(成员变量)的类对象,包括默认,受保护,私有
       /* Field[] fields = personClazz.getDeclaredFields();
        for(Field field :fields){
            System.out.println(field) ;
        }*/
​
        //2)获取公共的无参构造方法所在的Constructor
        Constructor con = personClazz.getConstructor();
        Object obj = con.newInstance(); //Person类对象
        System.out.println(obj) ;
        //3)现在获取指定的默认的name所在的字段类对象Field
        //public Field getDeclaredField(String name): 参数为指定的属性名称
        Field nameField = personClazz.getDeclaredField("name") ;
​
        //name字段:在person类中是默认的修饰符:
        nameField.setAccessible(true); //取消Java语言访问检查
        //Field
        //public void set(Object obj, Object value) :将参数值绑定在当前类的实例
        //给成员变量赋值
        nameField.set(obj,"高") ;
        System.out.println(obj) ;
​
        //    private int age ; //年龄
        System.out.println("--------------------------------------") ;
        Field ageField = personClazz.getDeclaredField("age");
        //取消Java语言访问检查
        ageField.setAccessible(true) ;
        //赋值
        ageField.set(obj,42) ;
        System.out.println(obj) ;
        //    public String address ; //地址
        //通过反射的方式赋值--获取成员变量类对象赋值Field
        System.out.println("---------------------------------") ;
        Field addressField = personClazz.getField("address");
        //直接赋值
        addressField.set(obj,"西安市鄠邑区") ;
        System.out.println(obj) ;
    }
}

5.3通过反射获取成员方法所在的类的对象Mthod,并且用方法调用

public class ReflectDemo {
    public static void main(String[] args) throws Exception {
​
        //之前的写法
        //创建Person类对象
        Person p = new Person() ;
        p.show();
​
        System.out.println("--------------------------------------") ;
        //现在反射来操作
        //1)获取Person类的字节码文件对象
        Class pClazz = Class.forName("com.qf.reflect_01.Person") ;
​
        // 获取所有的公共的成员方法的类对象Method
        //public Method[] getMethods(): 获取当前类的公共的成员方法,以及包括继承的类的公共方法
        //Method[] methods = pClazz.getMethods();
        //public Method[] getDeclaredMethods():获取所有的成员方法类对象,只包含自己的,不包括继承的
       /* Method[] methods = pClazz.getDeclaredMethods() ;
        for(Method method :methods){
            System.out.println(method); //自己当前类的以及父类Object
        }*/
       //通过构造器创建当前Person类对象
        Object obj = pClazz.getConstructor().newInstance();
        //2)获取公共的show方法所在的类对象并且调用这个方法
        //public Method getMethod(String name,Class<?>... parameterTypes)
        //参数1:成员方法的方法名
        //参数2:成员方法携带参数类型的class
        Method showMethod = pClazz.getMethod("show") ;
       //底层方法调用Method里面调用机制
        //public Object invoke(Object obj,Object... args):调用当前这个方法,并且方法的实际参数绑定在指定的 当前类实例上
       //返回值:如果当前方法本身void,单独调用即可,如果有返回值,直接返回Object:代表任何Java类对象
        showMethod.invoke(obj);
        System.out.println("-----------------------------------") ;
​
        //调用这个方法
        //  private String function2(String s){
        //        return  s ;
        //    }
     /*   Person p2 = new Person() ;
        p2.function2("hello") ; 私有方法*/
​
     //获取指定的私有的成员方法所在类对象Method
        //public 方法 getDeclaredMethod(String name,Class<?>... parameterTypes)
        //参数1:成员方法的方法名
        //        //参数2:成员方法携带参数类型的class
        Method function2Method = pClazz.getDeclaredMethod("function2", String.class) ;
        //私有方法,取消Java语言访问检查
        function2Method.setAccessible(true) ;
        //调用
        //public Object invoke(Object obj,Object... args):
        Object returnObj = function2Method.invoke(obj, "hello,高圆圆"); //相当于Object obj = new String() ;
        System.out.println(returnObj) ;
​
        // void method(String str){
        //        System.out.println(str);
        //    }
        System.out.println("-----------------------------") ;
        Method mMethod   = pClazz.getDeclaredMethod("method", String.class);
        //取消java语言访问检查
        mMethod.setAccessible(true) ;
        //调用
        mMethod.invoke(obj,"jdbc") ;
​
       /* private String function(){
            return  "helloJavaEE" ;
        }*/
       //反射方式调用
        System.out.println("-----------------------------") ;
        Method functionMethod = pClazz.getDeclaredMethod("function");
        functionMethod.setAccessible(true) ;
        Object returnObj2 = functionMethod.invoke(obj);
        System.out.println(returnObj2) ;
    }
}

5.4动态代理

目的:使用代理角色帮助真实角色完成事情,程序中,就是对业务功能进行增强
 动态代理---是在程序中过程中,通过反射获取代理对象!
 *              jdk动态代理:基于接口
 *
 *                      核心类:Proxy
 *                          java.lang.reflect.Proxy:反射代理
 *                          静态功能:
 *                          public static Object newProxyInstance(ClassLoader loader,
 *
 *                                      Class<?>[] interfaces,
 *                                       InvocationHandler h)
 *                           参数1:当前基于接口的类加载
 *                           参数2:实现接口的列表的Class
 *                           参数3:基于代理的处理程序的接口
 举例
 public class UserTest {
​
    public static void main(String[] args) {
​
        //针对用户模块实现增删查改的功能
        UserDao ud = new UserDaoImpl() ; //真实角色
        ud.add() ;
        ud.delete() ;
        ud.update() ;
        ud.find() ;
        System.out.println("--------------------------------------------") ;
​
        //实际开发中,添加/删除/修改/查询业务功能----都会存在系统监控:校验权限
        UserDao ud2 = new UserDaoImpl2() ;
        ud2.add();
        ud2.delete() ;
        ud2.update() ;
        ud2.find() ;
​
        System.out.println("---------------------------------------------------------") ;
​
        //使用jdk的动态代理实现:代理对象的创建
        //对ud产生代理对象 :ud真实角色
​
        //创建基于代理的处理的接口对象
        MyInvocationHandler handler = new MyInvocationHandler(ud) ;
        /**
         *  public static Object newProxyInstance(ClassLoader loader,
         *
         *                                        Class<?>[] interfaces, //public Class<?>[] getInterfaces() :接口列表所在的Class[
         *  *                                      InvocationHandler h)//参数3:实现代理的处理程序:接口
         */
        //
        UserDao udProxy = (UserDao) Proxy.newProxyInstance(
                ud.getClass().getClassLoader(),
                ud.getClass().getInterfaces(),
                handler
        );
        udProxy.add() ;
        udProxy.delete() ;
        udProxy.update() ;
        udProxy.find();
    }
}
public interface UserDao {
    void add() ;
    void delete() ;
    void update() ;
    void find() ;
}
public class MyInvocationHandler implements InvocationHandler {
​
    //代理的角色可以是任意Java类对象
    private Object target ; //目标对象
    public MyInvocationHandler(Object target){//Object target = new XXX() ;多态
        this.target = target ;
    }
​
    /**
     *
     * @param proxy 代理
     * @param method 当前需要被增强的方法
     * @param args  当前被增强方法的实际参数 数组
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args)
            throws Throwable {
        System.out.println("权限校验") ;
        Object obj = method.invoke(target, args);
        System.out.println("产生日志记录");
        return obj; //代理对象
    }
}
public class UserDaoImpl implements  UserDao {
    @Override
    public void add() {
        System.out.println("用户添加功能");
    }
​
    @Override
    public void delete() {
        System.out.println("删除功能");
    }
​
    @Override
    public void update() {
        System.out.println("修改功能");
    }
​
    @Override
    public void find() {
        System.out.println("查询功能");
    }
}

6.JDBC

定义:java连接数据库
七大步骤:
//1)导入mysql驱动jar包
//2)注册驱动
Class.forName("com.mysql.cj.jdbc.Driver") ;
//3)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/库名?characterEncoding=utf8&....",
    "root",
    "123456"
) ;
//4)准备sql语句
String sql = "update 表名 set 字段名称 = 值 where 条件" ;//查询语句
//5)获取执行对象
Statement stmt = conn.createStatement() ;
//6)执行sql语句
int count = stmt.executeUpdate(sql) ;//executeQuery(sql语句)--->ResultSet
//7)释放资源
//结果集对象.close() ;
执行对象.close() ;
连接对象.close() ;
举例:DDL/DML语句操作,增,删,改

public class JDBCDemo2 {
    public static void main(String[] args) {
​
        Connection connection = null ;
        Statement stmt = null ;
        try {
            //原生的7个步骤
            //注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver") ;
            //获取数据库的连接对象
            connection = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/javaee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
                    "root",
                    "123456"
            );
            //sql语句
            String sql = "CREATE TABLE account(" +
                    " id INT PRIMARY KEY AUTO_INCREMENT, " +
                    " NAME VARCHAR(10), " +
                    " money INT " +
                    ") " ;
            //获取执行对象:通过Connection
            stmt = connection.createStatement();
            //执行sql:通过executeUpdate(String sql)
            int count = stmt.executeUpdate(sql);
            System.out.println("创建成功"+count) ;
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            if(stmt!=null){
                try {
                    stmt.close() ;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close() ;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
执行DQL语句,查询
public class JdbcExecuteQueryDemo {
    public static void main(String[] args) {
        Connection connection = null ;
        Statement stmt = null ;
        ResultSet rs = null ;
        //注册驱动
        try {
            Class.forName("com.mysql.cj.jdbc.Driver") ;
            //获取连接对象
            connection = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/javaee_2110?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
                    "root",
                    "123456"
            ) ;
​
            //sql
            //查询账户表所有数据
            String sql = "select * from account" ;
            //获取执行对象
            stmt = connection.createStatement() ;
            //执行查询操作
            // ResultSet executeQuery(String sql):将
            rs = stmt.executeQuery(sql) ;
  System.out.println("账户id\t账户名称\t账户金额");
            while(rs.next()){
​
                int id = rs.getInt(1) ;
                String name = rs.getString(2);
                int money = rs.getInt(3);
                System.out.println(id+"\t\t"+name+"\t\t"+money) ;
            }
​
​
​
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            if(rs!=null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(stmt!=null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(connection!=null){
                try {
                    connection.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
​
    }
}
例题:  查询javaee_2110数据库中student的所有数据,将每一条学生数据封装到Student学生类中
 *将所有的数据结果,封装List集合中<Student>,最终将结果遍历出来!
 
public class JdbcTest {
    public static void main(String[] args) {
​
​
        //调用一个方法---->结果List<Student>
        List<Student> list = findAllStudent() ;
        for(Student student:list){
            System.out.println(student);
        }
    }
​
    //获取所有的学生数据,将学生数据都封装List中
    public static List<Student> findAllStudent() {
​
        Connection connection = null ;
        Statement stmt = null ;
        ResultSet rs = null ;
        try {
            //获取连接对象
            connection = JdbcUtils.getConnection();
            //sql
            String sql = "select * from student";
​
            //获取执行对
            stmt = connection.createStatement() ;
            //获取结果集对象
            rs = stmt.executeQuery(sql) ;
            //创建ArrayList<Student>
            ArrayList<Student> arrayList = new ArrayList<>() ;
​
            //声明Student类型的变量
            Student student = null ;
            //遍历结果
            while(rs.next()){
                //封装学生数据
                student = new Student() ;
​
                //通过索引值/列的标签名称获取内容
                int id = rs.getInt("id");
                String name = rs.getString("name");
                int age = rs.getInt("age");
                String sex = rs.getString("sex");
                String address = rs.getString("address");
                int math = rs.getInt("math");
                int english = rs.getInt("english");
​
                student.setId(id) ;
                student.setName(name); ;
                student.setAge(age); ;
                student.setSex(sex);
                student.setAddress(address);
                student.setMath(math);
                student.setEnglish(english);
                //添加集合中
                arrayList.add(student) ;
            }
            return arrayList ;
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return  null ;
​
    }
}
预编译:

PreparedStatement prepareStatement(String sql):获取预编译对象,同时将参数化的sql发送给数据库
 *                  通过预编译的sql语句对象,它的内存中就可以对参数?(占位符)进行赋值
public class PreparedStatementDemo {
    public static void main(String[] args) {
        Connection conn = null ;
        PreparedStatement stmt = null ;
​
        try {
            //获取连接对象
            conn = JdbcUtils.getConnection();
            //现在要javaee_2110的student表中插入数据
            //参数化的sql
           // String sql = "insert into student(name,age,sex,address,math,english) values(?,?,?,?,?,?)"  ;
            String sql = "update student set id = ? where  name = ?"  ;
            //PreparedStatement prepareStatement(String sql):获取预编译对象,同时将参数化的sql发送给数据库
            stmt =   conn.prepareStatement(sql);
            //预编译对象内存中存储了这些字段名称,需要它赋值
            //void setXXX(int parameterIndex,XXX x)
            //参数1:就是第几个占位符号(占位符的索引值,从1开始)
            //参数2:赋的实际参数---根据字段类型
            //参数赋值
            stmt.setInt(1,10) ;
            stmt.setString(2,"陈天宇");
            //在执行之前,需要进行参数赋值
            //int executeUpdate()
            //ResultSet executeQuery()
            int count = stmt.executeUpdate();
            System.out.println("影响了"+count+"行");
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.close(stmt,conn);
        }
    }
} 
面试题: PreparedStatement和Statement 区别
 *      前者:预编译对象,执行都是参数化的sql
 *           写的sql的参数都是占位符号?,可以有效防止sql注入(不存在字符串拼接)
 *           sql就执行一次,可以发送不同的参数进行赋值,执行sql效率相对大于Statement
 *      后者:普通的执行对象,每次指定的都是静态的sql,存在硬编码,而且存在字符串拼接,
 *          可以造成sql注入,不安全
 *          执行sql效率低,每次executeUpdate/Query(String sql)都要发送sql

6.1注解

注解不是注释,注释--->针对代码解释说明的文字,普通注释不能被解析,除非文档注释
 *注解:---标记类,方法,参数,成员变量,由一种特殊的含义 (能被解析的)
 *
 * 注解的本质就是接口interface---->前面加入了@标记
 * 注解中的属性----->(就是接口中的方法名)
 * 注解的分类
 *      jdk内置注解
 * @Overrid:标记当前这个方法是否为重写方法: 重写了类/抽象类或者接口
 * @Deprecated:标记某个方法是过时方法
 * @SuppressWarnings:压制警告, 一般企业中, 项目部署上线的时候,代码中不能黄色警告线!
 * @FunctionalInteface:函数式接口 :jdk8后,
 *      接口如果一个抽象方法,那么这个接口就可以是函数式接口----使用lambda表达式
 *  内置注解底层依赖的元注解
 *       @Target(ElementType.METHOD)
 *              标记当前这个注解所作用的范围
 *              属性:
 *                  ElementType[] values()--->返回值枚举的数组--->里面一些常量
 *                          TYPE,当前注解可以作用在类上
 *                          FIELD,当前这个注解可以作用成员属性上
                            METHOD,  ...当前这个注解可以作用在方法上
 *       @Retention(RetentionPolicy.SOURCE) :
 *              当做标记@Override注解的保留的阶段
 *                       RetentionPolicy value();
 *
 *                              返回值枚举类型
 *                                      SOURCE :原码编译阶段
 *                                      CLASS: 类 的加载
 *                                      RUNTIME:运行阶段
 *  注解中的属性(方法名)---返回值类型  (5种 类型!)
 *          String
 *  *          枚举类型Enum
 *  *          注解类型@Annotation
 *  *          基本类型
 *  *          以上类型的数组
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值