JavaWeb、JDBC

目录

一、JDBC简介

二、JDBC快速入门

三、JDBC API详解

1、DriverManager

 2、Connection

       2.1、获取执行SQL的对象

                SQL注入

                preparedStatement 防止SQL注入

                PreparedStatement原理

      2.2、 事务管理

3、Statement

4、ResultSet

四、数据库连接池

1、数据库连接池简介​编辑

2、Druid数据库连接池

五、JDBC增删改查练习

1、JDBC查询

2、JDBC添加

3、JDBC修改

4、JDBC删除


一、JDBC简介

面向接口编程

二、JDBC快速入门

public class JdbcDemo1 {
    public static void main(String[] args) throws Exception {

        //1、注册驱动
        //将Driver加载进程序中,mysql驱动5之后可以不写这段代码
        //Class.forName("com.mysql.jdbc.Driver");

        //2、获取连接
        /**
         * jdbc:mysql: 固定格式
         * localhost:3306  mysql服务器所在的主机ip和端口号
         * student 数据库名称
         * characterEncoding=utf8  字符集使用utf-8
         * useSSL=false  是否加密
         */
        String url = "jdbc:mysql://localhost:3306/student?/characterEncoding=utf8&useSSL=false";
        String username = "root";    //数据库用户名
        String password = "123456";  //数据库密码
        Connection con = DriverManager.getConnection(url,username,password);

        //3、定义sql语句
        String sql = "update account set money = money + 500 where name = \"李四\"";

        //4、获取执行sql的对象 Statement
        Statement stmt = con.createStatement();

        //5、执行sql,返回受影响的行
        int i = stmt.executeUpdate(sql);

        //6、输出结果
        System.out.println(i);

        //7、释放资源
        con.close();
        stmt.close();
    }
}

三、JDBC API详解

1、DriverManager

 

 2、Connection

       2.1、获取执行SQL的对象

SQL注入

String name = "张三";
        //模拟SQL注入
        //原理:select * from user where username='张三' and password='' or '1' = '1'
        //不论这个输入的用户名或者密码是否正确,他都会成功登录系统后台,因为通过拼接or使得左右两边只要有一个为真值就为真
        //而1=1为真,所以会被系统判断为真
         String pwd = "'or '1' = '1";

        //3、定义sql语句
        //通过字符串拼接查询输入的信息
        String sql = "select * from user where username='"+name+"' and password='"+pwd+"'";

        Statement stmt = con.createStatement();

        ResultSet rs = stmt.executeQuery(sql);

        if (rs.next()){
            System.out.println("登陆成功!");
            System.out.println(rs.getString("username"));
            System.out.println(rs.getString("password"));
            System.out.println(rs.getString("product"));
        }else {
            System.out.println("登陆失败!");
        }
        
        //7、释放资源
        con.close();
        stmt.close();

preparedStatement 防止SQL注入

 //3、定义sql语句
        String name = "张三";
        String pwd = "12345";
        String sql = "select * from user where username = ? and password = ?";

        //4、创建PreparedStatement防止sql注入
        PreparedStatement psmt = con.prepareStatement(sql);

        //5、设置问号参数
        //防止SQL注入 会将输入的敏感字符进行转义,会将注入语句'or '1' = '1 变成 \'or \'1\' = \'1 使它只能是一个符号而不参与运算
        psmt.setString(1,name);
        psmt.setString(2,pwd);

        //6、执行sql语句
        ResultSet rs = psmt.executeQuery();

        //7、处理结果
        if (rs.next()){
            System.out.println("登陆成功");
        }else {
            System.out.println("登陆失败");
        }

        //8、释放资源
        psmt.close();
        con.close();

PreparedStatement原理

直接将SQL语句写死,select * from tb_user where name = '张三';这样每次写一条语句都要经过检查、编译、执行会降低系统性能,而使用预编译SQL,参数采用符号代替,它只需要预编译这个带占位符?的语句一次,接收参数值后进行执行,使系统性能更高。

开启预编译

url中添加:useServerPrepStmts=true
//2、获取连接
        //useServerPrepStmts=true 开启预编译
        String url = "jdbc:mysql://localhost:3306/student?/characterEncoding=utf8&useSSL=false&useServerPrepStmts=true";
        String username = "root";    //数据库用户名
        String password = "123456";  //数据库密码
        Connection con = DriverManager.getConnection(url,username,password);

        //3、定义sql语句
        String name = "张三";
        String pwd = "'or '1' = '1";
        String sql = "select * from user where username = ? and password = ?";

        //4、创建PreparedStatement防止sql注入
        //创建的时候写入sql,执行时不添加
        PreparedStatement psmt = con.prepareStatement(sql);

        //5、设置问号参数
        //防止SQL注入 会自动将输入的字符进行转义,会将注入语句'or '1' = '1 变成 \'or \'1\' = \'1 使它只能是一个符号而不参与运算
        psmt.setString(1,name);
        psmt.setString(2,pwd);

        //6、执行sql语句
        //执行时不能加sql
        ResultSet rs = psmt.executeQuery();

在使用preparedStatement时在创建时导入sql语句就可以了,在执行的时候不能再加入sql否则会报语法错误,如果是使用字符串拼接要加单引号

 //插入数据 加单引号
//拼接变量accountId
String sql ="select username,sex,money from bank where accountid = '" +accountId + "'";

  2.2、 事务管理

try {
            //开启事务
            con.setAutoCommit(false);

            //执行sql,返回受影响的行
            int i1 = stmt.executeUpdate(sql1);
            //输出结果
            System.out.println(i1);

            //中间出错,事务回滚
            int i = 4/0;

            //执行sql,返回受影响的行
            int i2 = stmt.executeUpdate(sql2);
            //输出结果
            System.out.println(i2);

            //没有出错提交事务
            con.commit();
        } catch (Exception e) {
            //出错了回滚事务
            con.rollback();
        }finally {
            //7、释放资源
            con.close();
            stmt.close();
        }
    }

3、Statement

//3、定义sql语句
        String sql = "INSERT INTO account VALUES(NULL,'王五',2000); ";

        //4、获取执行sql的对象 Statement
        Statement stmt = con.createStatement();

        //5、执行sql语句,返回受影响的行
        int i = stmt.executeUpdate(sql);

        //6、处理结果,执行DML的sql语句,可以通过判断结果是否大于0判断是否执行成功
        //处理DDL的sql语句不可以,执行成功也可能返回0,比如删除数据库
        if(i > 0){
            System.out.println("执行成功");
        }else {
            System.out.println("执行失败");
        }

4、ResultSet

它是用来封装Statement查询的结果再通过方法调用输出查询的结果。

ResultSet会将表的查询结果封装起来,其内部有一个游标,默认位置在当前数据的上一行,获取数据时,它会判断当前行是否是有效行。

//新建sql语句
        String sql = "select * from account";

        //获取statement对象
        Statement stmt = con.createStatement();

        //执行sql
        ResultSet rs = stmt.executeQuery(sql);

        //打印查询结果
        //光标向下移动一行,并判断是否有数据
        while(rs.next()){
            //获取该行的字段
            //通过id获取字段
            System.out.println(rs.getInt(1));
            //System.out.println(rs.getString(2));
            //也可以通过对应列的名称获取
            System.out.println(rs.getString("name"));
            System.out.println(rs.getDouble(3));

            System.out.println("-----------------------");
        }

        //释放资源
        //后启动先释放
        stmt.close();
        con.close();
    }

注意在获取数据封装对象时,要先对对象进行初始化,在创建对象,否则对象无法被返回

public class JdbcTest {
    //创建一个静态容器
    public static final List<Account> accounts = new ArrayList<>();

    public static void main(String[] args) throws Exception {
        //将数据库中的数据查询到java容器中

        Class.forName("com.mysql.jdbc.Driver");
        //1、获取数据库连接
        String url = "jdbc:mysql://localhost:3306/student?/charaterEncoding=utf-8&useSSL=false";
        String usernamme = "root";
        String password = "123456";
        Connection con = DriverManager.getConnection(url,usernamme,password);

        //2、创建sql语句
        String sql = "select * from account";

        //3、创建Statement
        Statement stmt = con.createStatement();

        //4、执行sql语句
        ResultSet rs = stmt.executeQuery(sql);

        //如果要读取数据封装成对象要在循环外对对象初始化
        //Account accout = null

        //5、处理查询结果
        while (rs.next()){
            //然后在内部创建对象
            //account = new Account()


            int id = rs.getInt("id");
            String name = rs.getString("name");
            double money = rs.getDouble("money");
            //将获取到的数据封装成账户对象
            Account account = new Account(id,name,money);
            //将账户对象放入容器
            accounts.add(account);
        }

        //6、对集合容器进行遍历输出
        System.out.println(accounts);

    }
}

四、数据库连接池

1、数据库连接池简介

 在不使用数据库连接池与数据库交互时,每来一个用户请求,就需要创建一个数据库连接,用户使用完后关闭连接,由于开启数据库连接是个非常耗时的工作,而关闭连接也需要消耗资源,无法进行资源复用,就相当于招聘一个饭店服务员,服务员将客户带到空余座位后就将这个服务员开除,因此非常消耗资源,所以引入数据库连接池,处理一个用户的请求后再回到连接池中,不会关闭这个连接,继续等待下一个客户请求,如果数据库连接池中的所有连接都被占用了,再来一个客户会进行等待,并且连接池中会对当前正在进行的连接进行筛查,一旦发现某一个连接处于静止或者睡眠(后台)状态,就会强制断开这个连接,并归还到连接池,处理下一个请求的客户,避免数据库连接遗漏。

2、Druid数据库连接池

public class DruidDemo1 {
    //使用数据库连接池
    public static void main(String[] args) throws Exception {
        //1、导入jar包

        //2、修改配置文件

        //3、加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
        //4、获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(prop);
        //5、获取数据库连接
        Connection conn = ds.getConnection();
        System.out.println(conn);
    }
}
#配置文件

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/student?useSSL=false&useServerPrepStmts=true
username=root
password=12345
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000

五、JDBC增删改查练习

/**
 * 由于使用int类型默认为0会对结果造成影响,改用包装类Integer默认为null
 * 在实体类中建议基本信息类型使用包装类
 */
public class Brand {
    //主键
    private Integer id;
    //品牌名称
    private String brandName;
    //公司名称
    private String companyName;
    //排名
    private Integer ordered;
    //公司口号
    private String description ;
    //状态  0表示禁用 1表示启用
    private Integer status;

1、JDBC查询

public class JdbcSelectAll {
    private List<Brand> brandList = new ArrayList<>();
    //查询数据库中的所有用户
    @Test
    public void BrandTest()  {
        try {
            Properties pop = new Properties();
            //修改配置文件
            pop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
            //创建连接池
            DataSource dataSource = DruidDataSourceFactory.createDataSource(pop);
            //获取数据库连接
            Connection con = dataSource.getConnection();

            //定义sql语句
            String sql ="select * from tb_brand";

            //防止SQL注入获取PreparedStatement
            PreparedStatement pstmt = con.prepareStatement(sql);

            //执行sql,返回结果集集合
            ResultSet resultSet = pstmt.executeQuery(sql);

            while (resultSet.next()){
                //获取遍历到每一行的数据
                int id = resultSet.getInt("id");
                String brandName = resultSet.getString("brand_name");
                String companyName = resultSet.getString("company_name");
                int ordered = resultSet.getInt("ordered");
                String description = resultSet.getString("description");
                int status = resultSet.getInt("status");
                //封装成 品牌对象
                Brand brand = new Brand(id,brandName,companyName,ordered,description,status);
                //添加到品牌集合中
                brandList.add(brand);
            }

            for (Brand brand : brandList) {
                System.out.println("主键\t品牌名称\t企业名称\t企业排名\t公司描述\t状态");
                System.out.println(brand.getId() + "\t" + brand.getBrandName() + "\t" + brand.getCompanyName() + "\t"
                        + brand.getOrdered() + "\t" + brand.getDescription() + "\t" + brand.getStatus());
                System.out.println("------------------------------------");
            }

            resultSet.close();
            pstmt.close();
            con.close();

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

2、JDBC添加

public class JdbcAddBrand {
    //品牌数据的增加
    @Test
    public void testAdd() throws Exception {
        //1、修改配置文件
        Properties pro = new Properties();
        pro.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
        //2、创建数据库连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(pro);
        //3、创建连接
        Connection conn = dataSource.getConnection();

        //4、创建sql语句
        String sql = "insert into tb_brand(brand_name,company_name,ordered,description,status)" +
                "values(?,?,?,?,?)";

        //5、创建PrepareStatement
        PreparedStatement psmt = conn.prepareStatement(sql);

        //6、设置参数
        psmt.setString(1,"微软");
        psmt.setString(2,"美国微软国际公司");
        psmt.setInt(3,10);
        psmt.setString(4,"微软微软微软");
        psmt.setInt(5,1);

        //7、执行sql
        int i = psmt.executeUpdate();

        //8、判断是否添加成功
        if (i > 0){
            System.out.println("添加成功!");
        }else {
            System.out.println("添加失败!");
        }

        //9、释放资源
        psmt.close();
        conn.close();

    }
}

3、JDBC修改

public class JdbcUpdate {
    //根据id修改数据
    @Test
    public void testUpdate() throws Exception {
        //1、获取配置文件
        Properties pop = new Properties();
        pop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
        //2、创建数据库连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(pop);

        //3、创建数据库连接
        Connection conn = dataSource.getConnection();

        //4、创建sql语句
        String sql = "update tb_brand set brand_name=?,company_name=?,ordered=?,description=?,status=?  " +
                "where id=?";

        //5、创建PrepareStatement
        PreparedStatement pstmt = conn.prepareStatement(sql);

        //6、设置参数
        pstmt.setInt(6,4);
        pstmt.setString(1,"谷歌");
        pstmt.setString(2,"微软");
        pstmt.setInt(3,34);
        pstmt.setString(4,"谷歌公司谷歌谷歌");
        pstmt.setInt(5,0);

        //7、执行sql
        int i = pstmt.executeUpdate();

        //8、处理结果
        if (i>0){
            System.out.println("修改成功!");
        }else {
            System.out.println("修改失败!");
        }

        //9、释放资源
        pstmt.close();
        conn.close();

    }
}

4、JDBC删除

public class JdbcDelete {
    //根据id删除
    @Test
    public void testDelete() throws Exception {
        //1、获取配置文件
        Properties pop = new Properties();
        pop.load(new FileInputStream("D:\\2ProgramTool\\JavaWebTest\\jdbc\\jdbc-demo\\src\\druid.properties"));
        //2、创建数据库连接池
        DataSource dataSource = DruidDataSourceFactory.createDataSource(pop);
        //3、创建数据库连接
        Connection conn = dataSource.getConnection();
        //4、创建sql语句
        String sql = "delete from tb_brand where id=?";

        //5、创建PrepareStatement
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //6、设置参数
        pstmt.setInt(1,5);
        //7、执行sql
        int i = pstmt.executeUpdate();
        if (i>0){
            System.out.println("删除成功!");
        }else {
            System.out.println("删除失败!");
        }


    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值