JDBC

JDBC

作用:可以通过Java来操作数据库。
解耦:进行jdbc规范,若不进行规范,那么程序员学习将会变得困难。

JDBC入门程序

jdbc的入门步骤:
1.导入jar包
2.注册驱动
3.获取数据库连接
4.获取执行者对象
5.执行sql语句,并且接受sql语句返回结果
6.处理结果
7.释放资源

package com.jdbc;
import java.sql.*;
public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.导入jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据库连接
        Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");
        String sql="select * from student";
        //4.获取执行者对象
        Statement stmt = con.createStatement();
        //5.执行sql语句,并且接受sql语句返回结果
        ResultSet count = stmt.executeQuery(sql);
        //6.处理结果
        while (count.next()){
            System.out.println(count.getInt("sid")+"\t"+count.getString("name")+"\t"+count.getInt("age"));
        }
        //7.释放资源
        stmt.close();
        count.close();
    }
}

什么情况会触发类加载

1.new
2.使用静态方法
3.加载子类的时候父类被加载

DriverManager(驱动管理器)

1.加载驱动

Class.forName("com.mysql.jdbc.Driver");

2.获取连接,返回Connection对象
①.ip(ping ip)
②.数据库端口
③.数据库名称
④.账号密码

Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");

Connecton

1.创建statement对象
2.管理事务
①.原子性
②.一致性
③.隔离性
④.持久性

Statement

1.封装sql
2.执行DML语句
.executeUpdate
3.执行DQL语句
.executeQuery
4.释放资源

ResultSet

1.存储结构
2.作用:封装mysql服务器响应的数据

三层结构

1.dao
2.service
3.web

查询所有信息

1.查询所有信息需要用ArrayList来存储信息,集合类型为T,同时数据需要封装
2.DQL:
executeQuery

/*
    查询所有信息
 */
@Override
public ArrayList<Student> findAll() {
    ArrayList<Student> list = new ArrayList<>();
    Connection con = null;
    Statement stat = null;
    ResultSet rs = null;
    try {
        //获取连接
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");
        String sql = "select * from student";
        //4.获取执行者对象
        stat = con.createStatement();
        //5.执行sql语句,并且接受sql语句返回结果
        rs = stat.executeQuery(sql);
        //6.处理结果
        while (rs.next()) {
            int sid = rs.getInt("sid");
            String name = rs.getString("name");
            int age = rs.getInt("age");
            java.sql.Date birthday = rs.getDate("birthday");

            //封装Student对象
            Student stu = new Student(sid,name,age,birthday);

            //将student对象保存到集合中
            list.add(stu);
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        //7.释放资源
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    return list;
}

根据id查询信息

1.变化:和普通查询所有唯一不同的是SQL语句
2.sql语句的参数拼接:
只有数据为字符串类型时需要用上单引号
3.索引失效
如果在数字类型的id加上单引号,则mysql会认为那是一个字符串,所以索引会失效
4.DQL:
executeQuery

/*
    条件查询,根据id查询信息
 */
@Override
public Student findById(Integer sid) {
    Student stu = new Student();
    Connection con = null;
    Statement stat = null;
    ResultSet rs = null;

    try {
        //获取连接
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");

        String sql = "select * from student where sid=" + sid;
        //4.获取执行者对象
        stat = con.createStatement();
        //5.执行sql语句,并且接受sql语句返回结果
        rs = stat.executeQuery(sql);
        //6.处理结果
        while (rs.next()) {
           stu.setSid(rs.getInt("sid"));
           stu.setName(rs.getString("name"));
           stu.setAge(rs.getInt("age"));
           stu.setBirthday(rs.getDate("birthday"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        //7.释放资源
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    return stu;
}

添加信息

1.添加信息无需处理结果
2.DML:
executeUpdate
3.释放资源只需释放con和stat
4.由于date时间类型比较特殊,我们需要用SimpleDateFormat把时间设置为我们想要的格式

/*
    添加信息
 */
@Override
public int insert(Student stu) {
    Connection con = null;
    Statement stat = null;
    int result = 0;


    try {
        //获取连接
        con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");
        Date d = stu.getBirthday();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String birthday = sdf.format(d);
        String sql = "insert into student values(sid,'" + stu.getName() + "','" + stu.getAge() + "','" + birthday + "')";
        //4.获取执行者对象
        stat = con.createStatement();
        //5.执行sql语句,并且接受sql语句返回结果
        result = stat.executeUpdate(sql);

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        //6.释放资源
        if (con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //将结果返回
    return result;
}

修改信息

1.修改信息和添加信息唯一不同的就是sql语句
2.DML:
executeUpdate
3.释放资源只需释放con和stat

 /*
        修改信息
     */
    @Override
    public int update(Student stu) {
        Connection con = null;
        Statement stat = null;
        int result = 0;
        try {
            //2获取连接
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");
            //3获取执行者对象
            stat = con.createStatement();
            //4.执行sql语句,并且接受sql语句返回结果
            Date d = stu.getBirthday();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            String birthday = sdf.format(d);
            //UPDATE student SET sid=6, NAME='周七',age=52,birthday='2020-08-08' WHERE sid=4
            String sql = "UPDATE  student SET sid='" + stu.getSid() + "',name='" + stu.getName() + "',age='" + stu.getAge() + "',birthday='" + birthday + "' WHERE sid='" + stu.getSid() + "'";
            result = stat.executeUpdate(sql);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stat != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //将结果返回
        return result;
    }

删除信息

1.删除信息比较简单,和修改信息唯一不同的就是sql语句。
2.DML:
executeUpdate
3.释放资源只需释放con和stat

    /*
        删除学生信息
     */
    @Override
    public int delete(Integer sid) {
        Connection con = null;
        Statement stat = null;
        int result = 0;
        try {
            con = DriverManager.getConnection("jdbc:mysql://localhost:3306/db9", "root", "root");

            //3.获取执行者对象
            stat = con.createStatement();

            //4.执行sql语句,并且接收返回的结果集
            String sql = "DELETE FROM student WHERE sid='" + sid + "'";
            result = stat.executeUpdate(sql);

        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            //6.释放资源
            if (con != null) {
                try {
                    con.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stat != null) {
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        //将结果返回
        return result;
    }

代码问题

1.代码重复度太高
2.需要修改Java代码
3.会长时间的占用JVM内存,甚至会出现缓存的问题

解决方式

为什么配置信息写在配置文件会好一些?
1.不用去修改Java代码
2.解决代码重复度太高的问题
3.配置文件不会长时间占用jvm,只有在需要的时候才会占用jvm
4.当更改配置文件时,配置文件进入jvm会载入最新的配置文件

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db9
username=root
password=root

工具类的目的

1.去掉重复代码
2.实现步骤
1.编写配置文件
2.加载配置文件
3.编写方法获取连接
4.释放资源

package com.jdbc.demo3.utils;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/*
    JDBC工具类
 */
public class JDBCUtils {
    //1.私有构造方法
    private JDBCUtils(){}

    //2.声明所需要的配置变量
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    private static Connection con;

    //3.提供静态代码块。读取配置文件的信息为变量赋值,注册驱动
    static{
        try {
            //读取配置文件的信息为变量赋值
            InputStream is = JDBCUtils.class.getClassLoader().getResourceAsStream("config.properties");
            Properties prop = new Properties();
            prop.load(is);

            driverClass = prop.getProperty("driverClass");
            url = prop.getProperty("url");
            username = prop.getProperty("username");
            password = prop.getProperty("password");

            //注册驱动
            Class.forName(driverClass);

        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //4.提供获取数据库连接方法
    public static Connection getConnection() {
        try {
            con = DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return con;
    }

    //5.提供释放资源的方法
    public static void close(Connection con, Statement stat, ResultSet rs) {
        if(con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void close(Connection con, Statement stat) {
        if(con != null) {
            try {
                con.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if(stat != null) {
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

优化后的代码

/*
    查询所有学生信息
 */
@Override
public ArrayList<Student> findAll() {
    ArrayList<Student> list = new ArrayList<>();
    Connection con = null;
    Statement stat = null;
    ResultSet rs = null;
    try{

        con = JDBCUtils.getConnection();

       //3.获取执行者对象
       stat = con.createStatement();

       //4.执行sql语句,并且接收返回的结果集
       String sql = "SELECT * FROM student";
       rs = stat.executeQuery(sql);

       //5.处理结果集
       while(rs.next()) {
           Integer sid = rs.getInt("sid");
           String name = rs.getString("name");
           Integer age = rs.getInt("age");
           Date birthday = rs.getDate("birthday");

           //封装Student对象
           Student stu = new Student(sid,name,age,birthday);

           //将student对象保存到集合中
           list.add(stu);
       }

   } catch(Exception e) {
       e.printStackTrace();
   } finally {
       //6.释放资源
       JDBCUtils.close(con,stat,rs);
   }
    //将集合对象返回
    return list;
}
/*
    条件查询,根据id查询学生信息
 */
@Override
public Student findById(Integer id) {
    Student stu = new Student();
    Connection con = null;
    Statement stat = null;
    ResultSet rs = null;
    try{

        con = JDBCUtils.getConnection();

        //3.获取执行者对象
        stat = con.createStatement();

        //4.执行sql语句,并且接收返回的结果集
        String sql = "SELECT * FROM student WHERE sid='"+id+"'";
        rs = stat.executeQuery(sql);

        //5.处理结果集
        while(rs.next()) {
            Integer sid = rs.getInt("sid");
            String name = rs.getString("name");
            Integer age = rs.getInt("age");
            Date birthday = rs.getDate("birthday");

            //封装Student对象
            stu.setSid(sid);
            stu.setName(name);
            stu.setAge(age);
            stu.setBirthday(birthday);
        }

    } catch(Exception e) {
        e.printStackTrace();
    } finally {
        //6.释放资源
        JDBCUtils.close(con,stat,rs);
    }
    //将对象返回
    return stu;
}
/*
    添加学生信息
 */
@Override
public int insert(Student stu) {
    Connection con = null;
    Statement stat = null;
    int result = 0;
    try{
        con = JDBCUtils.getConnection();

        //3.获取执行者对象
        stat = con.createStatement();

        //4.执行sql语句,并且接收返回的结果集
        Date d = stu.getBirthday();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String birthday = sdf.format(d);
        String sql = "INSERT INTO student VALUES ('"+stu.getSid()+"','"+stu.getName()+"','"+stu.getAge()+"','"+birthday+"')";
        result = stat.executeUpdate(sql);

    } catch(Exception e) {
        e.printStackTrace();
    } finally {
        //6.释放资源
        JDBCUtils.close(con,stat);
    }
    //将结果返回
    return result;
}
/*
    修改学生信息
 */
@Override
public int update(Student stu) {
    Connection con = null;
    Statement stat = null;
    int result = 0;
    try{
        con = JDBCUtils.getConnection();

        //3.获取执行者对象
        stat = con.createStatement();

        //4.执行sql语句,并且接收返回的结果集
        Date d = stu.getBirthday();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        String birthday = sdf.format(d);
        String sql = "UPDATE student SET sid='"+stu.getSid()+"',name='"+stu.getName()+"',age='"+stu.getAge()+"',birthday='"+birthday+"' WHERE sid='"+stu.getSid()+"'";
        result = stat.executeUpdate(sql);

    } catch(Exception e) {
        e.printStackTrace();
    } finally {
        //6.释放资源
        JDBCUtils.close(con,stat);
    }
    //将结果返回
    return result;
}
/*
    删除学生信息
 */
@Override
public int delete(Integer id) {
    Connection con = null;
    Statement stat = null;
    int result = 0;
    try{
        con = JDBCUtils.getConnection();

        //3.获取执行者对象
        stat = con.createStatement();

        //4.执行sql语句,并且接收返回的结果集
        String sql = "DELETE FROM student WHERE sid='"+id+"'";
        result = stat.executeUpdate(sql);

    } catch(Exception e) {
        e.printStackTrace();
    } finally {
        //6.释放资源
        JDBCUtils.close(con,stat);
    }
    //将结果返回
    return result;
}

SQL注入攻击

作用:利用sql的注释把后面的内容注释掉,就可以登录用户

SELECT * FROM user WHERE loginname= '' or 1 = 1 -- AND password='" + password + "'

prepareStatement解决SQL注入攻击

作用:预编译SQL语句,以防止SQL注入问题
使用:
创建:

PrepareStatement ps = connection.prepareStatement("select * from student where id = ?");
    ps.setInt(1, 22); 

事务管理

使用对象:Connection对象
事务方法:
开启事务:setAutoCommit(false)
提交事务:commit()
回滚事务:rollback()

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值