jdbc入门,API详解,数据库连接池,案例

jdbc(java database connectivity)

jdbc简介:

用java语言来操作关系型数据库的API

注:jdbc(一套标准接口)优点:可以操作不同的关系型数据库的规则。如:一套代码可以操作mysql,oracle,db2。他们自己定义了jdbc的实现类(驱动)

 

JDBC入门

//导入jar包后,需要右键+Add as Library
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
​
        //2.获取连接    ip  用户名  密码
        String url="jdbc:mysql://127.0.0.1:3306/db1";   //ip:端口/数据库名称
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //3.定义sql
        String sql = "update account set money = 2000 where id=1";
​
        //4.获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();   //alt+enter自动补齐
​
        //5.执行sql
        int count = stmt.executeUpdate(sql);  //返回值为受影响的行数
​
        //6.处理结果
        System.out.println(count);
​
        //7.释放资源
        stmt.close();
        conn.close();

 

此时数据库中account表中记录发生变化

 

JDBC API详解

DriverManager

DriverManager(驱动管理类)作用

1.注册驱动 registerDriver(Driver driver)

Class.forName("com.mysql.jdbc.Driver");  //可以省略

2.获取数据库的连接对象 getConnection(String url, String user, String password)

/*
参数:
1.url:连接路径
    url语法:jdbc:mysql://ip地址(或域名):端口号/数据库名称?参数键值对1&参数键值对2...
       实例:jdbc:mysql://127.0.0.1:3306/db1
       注:如果连接本机的mysql,并且mysql服务器默认端口为3306,则url可以简写:jdbc:mysql:///数据库名称?参数键值对1&参数键值对2...
          
2.user:用户名
3.password:密码
*/

 

Connection

Connection(数据库连接对象)作用:

1.获取执行SQL的对象

//获取执行SQL的对象
//1.普通执行sql对象
Statement ? = create Statement()
//2.预编译sql的执行sql对象:防止sql注入
PreparedStatement ? =prepareStatement(sql)
//3.执行存储过程的对象
CallableStatement ? = prepareCall(sql)

2.事务管理

/*mysql事务管理
开启事务:BEGIN;
提交事务:COMMIT;
回滚事务:ROLLBACK;
  注:mysql默认自动提交事务
*/
/*JDBC事务管理:Connection接口中定义了3个对应的方法
开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即开启事务
提交事务:commit()
回滚事务:rollback()
*/

无异常执行

//1.注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //2.获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        String url="jdbc:mysql:///db1?useSSL=false";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //3.定义sql
        String sql1 = "update account set money = 3000 where id=1";
        String sql2 = "update account set money = 3000 where id=2";
        //4.获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();   //alt+enter自动补齐
​
        //选中然后ctrl+alt+t,选择try catch  自动设置异常处理
        try {
            //开启事务
            conn.setAutoCommit(false);
            //5.执行sql
            int count1 = stmt.executeUpdate(sql1);  //返回值为受影响的行数
            int count2 = stmt.executeUpdate(sql2);  //返回值为受影响的行数
​
            //6.处理结果
            System.out.println(count1);
            //设置异常
            //int i=3/0;
            System.out.println(count2);
        } catch (SQLException throwables) {
            //回滚事务
            conn.rollback();
            throwables.printStackTrace();
        }
​
        //提交事务
        conn.commit();
        //7.释放资源
        stmt.close();
        conn.close();

 

 

Statement

Statement作用

执行sql语句

//执行sql语句
int ? = executeUpdate(sql); //执行DML/DDL语句
//返回值:1.DML语句影响的行数 2.DDL语句执行后,执行成功也可能返回0
ResultSet ? = executeQuery(sql);//执行DQL语句(查询)
//返回值:ResultSet结果集对象

ResultSet

ResultSet(结果集对象)作用

1.封装了DQL查询语句的结果

/*用来做查询
封装了DQL查询语句的结果
Result ? = stmt.executeQuery(sql):执行DQL语句,返回ResultSet对象
查询获取结果
boolean next(); 
    1.将光标从当前位置向前移动一行  
    2.判断当前行是否为有效行
返回值:
    true:有效行,当前行有数据。  
    false:无效行,当前位置没有数据。
*/
/*
xxx getXxx(参数):获取数据
xxx:数据类型  如:int getInt(参数); String getString(参数)
参数:
    int:列的编号,从1开始
    String:列的名称
*/
 

使用步骤:

1.游标向下移动一行,判断该行是否有数据:next()

2.获取数据:getXxx(参数)

//循环判断游标是否是最后一行末尾
while(rs.next()){
    //获取数据
    rs.getXxx(参数);
}
//1.注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //2.获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        String url="jdbc:mysql:///db1?useSSL=false";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //3.定义sql
        String sql = "select * from account";    //执行查询语句
        //4.获取statement对象
        Statement stmt = conn.createStatement();
        //5.执行sql
        ResultSet rs = stmt.executeQuery(sql);
        //6.处理结果:遍历rs中的所有数据
        //6.1 光标向下移动一行,并且判断当前行是否存在数据
        while(rs.next()){
            int id = rs.getInt(1);
            String name = rs.getString(2);
            Double money = rs.getDouble(3);
​
            System.out.println(id);
            System.out.println(name);
            System.out.println(money);
            System.out.println("------------");
        }
        //7.释放资源
        rs.close();
        stmt.close();
        conn.close();

 

ResultSet案例

//需求:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
package com.jdbc;
​
import org.junit.Test;
​
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
​
import com.pojo.Account;
​
public class JDBCdemo7_ResultSet_demo {
    /*  需求:查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
    *  1.定义实体类Account
    *  2.查询数据,封装到Account对象中
    *  3.将Account对象存入ArrayList对象中
    */
    @Test
    public  void testDML()throws Exception {
        //1.注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //2.获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        String url="jdbc:mysql:///db1?useSSL=false";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //3.定义sql
        String sql = "select * from account";    //执行查询语句
        //4.获取statement对象
        Statement stmt = conn.createStatement();
        //5.执行sql
        ResultSet rs = stmt.executeQuery(sql);
​
        //创建集合
        List<Account> list = new ArrayList<>();
​
        //6.1光标向下移动一行,且判断当前行是否有数据
        while(rs.next()){
            //创建对象
            Account account = new Account();
            //获取数据
            int id = rs.getInt("id");
            String name = rs.getString("name");
            Double money = rs.getDouble("money");
​
            //赋值
            account.setId(id);
            account.setName(name);
            account.setMoney(money);
​
            //存入集合
            list.add(account);
        }
        //打印集合
        System.out.println(list);
        //7.释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
}
 

 

SQL注入案例

SQL注入 ​ sql注入是通过操作输入来修改事先定义好的sql语句,用以达到执行代码对服务器进行攻击的方法

-- navicate端
​
-- 创建tb_user表
create table tb_user(
    id int,
    username varchar(20),
    password varchar(32)
);
​
-- 添加数据
insert into tb_user values(1,'zhangsan','123'),(2,'lisi','234');
​
select * from tb_user;
​
​
​
-- and比or先执行,所以username= 'kjdkfjd' and password= ''返回false,或true即为true。所以所有的数据都会查询出来。'1' = '1组成恒等式
select * from tb_user where username= 'kjdkfjd' and password= '' or '1' = '1';
sql注入成功,原因:and比or先执行,所以username= 'kjdkfjd' and password= ''返回false,或true即为true。所以所有的数据都会查询出来。'1' = '1组成恒等式select * from tb_user where username= 'kjdkfjd' and password= '' or '1' = '1';

    @Test
    public  void UserLogin() throws Exception {
        //1.注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //2.获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        String url="jdbc:mysql:///test?useSSL=false";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //接收用户输入 用户名和密码
        String name="zhangsan";
        String pwd="123";
        //拼字符串"+name+"
        String sql="select * from tb_user where username= '"+name+"' and password= '"+pwd+"'";
​
        //获取stmt对象
        Statement stmt =conn.createStatement();
​
        //执行sql
        ResultSet rs=stmt.executeQuery(sql);
​
        //判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功");
        }
        else{
            System.out.println("登录失败");
​
        }
​
        //7.释放资源
        rs.close();
        stmt.close();
        conn.close();
    }
    /*演示sql注入*/
    @Test
    public  void UserLogin_Inject() throws Exception {
        //1.注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //2.获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        String url="jdbc:mysql:///test?useSSL=false";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //接收用户输入 用户名和密码
        //用户名随便写
        String name="kjdkfjd";
        String pwd="' or '1' = '1"; //任何数与1或都为1,即为true
        //拼字符串"+name+"
        String sql="select * from tb_user where username= '"+name+"' and password= '"+pwd+"'";
        System.out.println(sql);
        //获取stmt对象
        Statement stmt =conn.createStatement();
​
        //执行sql
        ResultSet rs=stmt.executeQuery(sql);
​
        //判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功");
        }
        else{
            System.out.println("登录失败");
​
        }
​
        //7.释放资源
        rs.close();
        stmt.close();
        conn.close();
    }

PreparedStatement

PreparedStatement
    作用:1.预编译sql语句并执行:预防sql注入问题。
         2.防止SQL注入:==将敏感字符进行转义==

用法:

1.获取 PreparedStatement 对象

// SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?";
// 通过Connection对象获取,并传入对应的sql语句
PreparedStatement pstmt = conn.prepareStatement(sql);
//注:上面的sql语句中参数使用 ? 

2.设置参数值

//进行占位,在之前之前肯定要设置这些 ?  的值。
PreparedStatement对象:setXxx(参数1,参数2):给 ? 赋值
    Xxx:数据类型 ; 如 setInt (参数1,参数2)
参数:
    参数1: ?的位置编号,从1 开始
    参数2: ?的值

3.执行sql语句

executeUpdate();  执行DDL语句和DML语句,即增删改
executeQuery();  执行DQL语句,即查询
//注:调用这两个方法时不需要传递SQL语句,因为获取SQL语句执行对象时已经对SQL语句进行预编译了。

案例:

利用preparestament函数可以防止sql注入,因为对特殊字符进行了转义转义后的sql语句如下:

select * from tb_user where username= 'kjdkfjd' and password= '\' or \'1\' = \'1';
@Test
    public  void PrepareStatement() throws Exception {
        //注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        String url="jdbc:mysql:///test?useSSL=false";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //接收用户输入 用户名和密码
        String name="zhangsan";
        String pwd="' or '1' = '1";//sql注入失败
        //2.定义sql,prepare用?作为占位符来替代你写参数的位置
        String sql="select * from tb_user where username= ? and password= ?";//查询
​
        //1.获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
        //设置?的值     setStrng方法会对字符串进行转义
        //select * from tb_user where username= 'kjdkfjd' and password= '\' or \'1\' = \'1';
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
​
        //3.执行sql,利用prepare定义sql不需要传参
        ResultSet rs=pstmt.executeQuery();
​
        //判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功");
        }
        else{
            System.out.println("登录失败");
​
        }
​
        //7.释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }

好处:

1.预编译SQL,性能更高

2.防止SQL注入:==将敏感字符进行转义==

原理:

 

Java代码操作数据库流程如图所示:

  • 将sql语句发送到MySQL服务器端

  • MySQL服务端会对sql语句进行如下操作

    • 检查SQL语句

      检查SQL语句的语法是否正确。

    • 编译SQL语句。将SQL语句编译成可执行的函数。

      检查SQL和编译SQL花费的时间比执行SQL的时间还要长。如果我们只是重新设置参数,那么检查SQL语句和编译SQL语句将不需要重复执行。这样就提高了性能。

    • 执行SQL语句

接下来我们通过查询日志来看一下原理。

  • 开启预编译功能

    在代码中编写url时需要加上以下参数。而我们之前根本就没有开启预编译功能,只是解决了SQL注入漏洞。

    useServerPrepStmts=true

  • 配置MySQL执行日志(重启mysql服务后生效)

    在mysql配置文件(my.ini)中添加如下配置

    log-output=FILE
    general-log=1
    general_log_file="D:\mysql.log"
    slow-query-log=1
    slow_query_log_file="D:\mysql_slow.log"
    long_query_time=2

  • java测试代码如下:

/*
    * PrepareStatement预编译功能
    *   useServerPrepStmts=true开启预编译功能
    *   好处:1.预编译sql,性能更高。2.防止sql注入:将敏感字符进行转义
    *   PrepareStatement原理:
    *          1.在获取PrepareStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
    *          2.执行时就不用再进行这些步骤了,速度更快。
    *          3.如果sql模板一样,则只需要进行一次检查、编译。
    * */
    @Test
    public  void PrepareStatement_() throws Exception {
        //注册驱动
        //Class.forName("com.mysql.jdbc.Driver");  //可以省略
​
        //获取连接    ip  用户名  密码
        //如果连接本机的mysql,并且mysql服务器默认端口为3306
        //useServerPrepStmts=true 参数开启预编译
        String url="jdbc:mysql:///test?useSSL=false&useServerPrepStmts=true";   //ip:端口/数据库名称       ?后的useSSL=false可以禁用提示
        String username="root";
        String password="1234";
        Connection conn = DriverManager.getConnection(url,username,password);//获取连接
​
        //接收用户输入 用户名和密码
        String name="zhangsan";
        String pwd="' or '1' = '1";//sql注入失败
        //定义sql,prepare用?作为占位符来替代你写参数的位置
        String sql="select * from tb_user where username= ? and password= ?";//查询
​
​
        //预编译2次,执行1次。在sql传递到preparestatement对象才能执行
​
​
        //获取pstmt对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
​
​
        Thread.sleep(10000);
​
        //设置?的值
        pstmt.setString(1,name);
        pstmt.setString(2,pwd);
​
        ResultSet rs=null;
​
        //设置?的值     setStrng方法会对字符串进行转义
        pstmt.setString(1,"aaa");
        pstmt.setString(2,"bbb");
​
        //执行sql,利用prepare定义sql不需要传参
        rs=pstmt.executeQuery();
​
        //判断登录是否成功
        if(rs.next()){
            System.out.println("登录成功");
        }
        else{
            System.out.println("登录失败");
​
        }
​
        //7.释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }
}
  • 执行SQL语句,查看 D:\mysql.log 日志如下:

  • 上图中第三行中的 Prepare 是对SQL语句进行预编译。第四行和第五行是执行了两次SQL语句,而第二次执行前并没有对SQL进行预编译。

==小结:==

  • 在获取PreparedStatement对象时,将sql语句发送给mysql服务器进行检查,编译(这些步骤很耗时)

  • 执行时就不用再进行这些步骤了,速度更快

  • 如果sql模板一样,则只需要进行一次检查、编译

数据库连接池

数据库连接池简介

  • 数据库连接池是个容器,负责分配、管理数据库连接(Connection)

  • 它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;

  • 释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏

  • 好处

    • 资源重用

    • 提升系统响应速度

    • 避免数据库连接遗漏

之前我们代码中使用连接是没有使用都创建一个Connection对象,使用完毕就会将其销毁。这样重复创建销毁的过程是特别耗费计算机的性能的及消耗时间的。

而数据库使用了数据库连接池后,就能达到Connection对象的复用,如下图

 

连接池是在一开始就创建好了一些连接(Connection)对象存储起来。用户需要连接数据库时,不需要自己创建连接,而只需要从连接池中获取一个连接进行使用,使用完毕后再将连接对象归还给连接池;这样就可以起到资源重用,也节省了频繁创建连接销毁连接所花费的时间,从而提升了系统响应的速度。

数据库连接池实现

  • 标准接口:==DataSource==

    官方(SUN) 提供的数据库连接池标准接口,由第三方组织实现此接口。该接口提供了获取连接的功能:

    Connection getConnection()

    那么以后就不需要通过 DriverManager 对象获取 Connection 对象,而是通过连接池(DataSource)获取 Connection 对象。

  • 常见的数据库连接池

    • DBCP

    • C3P0

    • Druid

    我们现在使用更多的是Druid,它的性能比其他两个会好一些。

  • Druid(德鲁伊)

    • Druid连接池是阿里巴巴开源的数据库连接池项目

    • 功能强大,性能优秀,是Java语言最好的数据库连接池之一

Driud使用

  • 导入jar包 druid-1.1.12.jar

  • 定义配置文件

  • 加载配置文件

  • 获取数据库连接池对象

  • 获取连接

现在通过代码实现,首先需要先将druid的jar包放到项目下的lib下并添加为库文件

 

项目结构如下:

 

编写配置文件如下:

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

使用druid的代码如下:

/**
 * Druid数据库连接池演示
 */
public class DruidDemo {
​
    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件
        //3. 加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("jdbc-demo/src/druid.properties"));
        //4. 获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
​
        //5. 获取数据库连接 Connection
        Connection connection = dataSource.getConnection();
        System.out.println(connection); //获取到了连接后就可以继续做其他操作了
​
        //System.out.println(System.getProperty("user.dir"));
    }
}

JDBC练习

需求

完成商品品牌数据的增删改查操作

  • 查询:查询所有数据

  • 添加:添加品牌

  • 修改:根据id修改

  • 删除:根据id删除

案例实现

环境准备

  • 数据库表 tb_brand

    -- 删除tb_brand表
    drop table if exists tb_brand;
    -- 创建tb_brand表
    create table tb_brand (
        -- id 主键
        id int primary key auto_increment,
        -- 品牌名称
        brand_name varchar(20),
        -- 企业名称
        company_name varchar(20),
        -- 排序字段
        ordered int,
        -- 描述信息
        description varchar(100),
        -- 状态:0:禁用  1:启用
        status int
    );
    -- 添加数据
    insert into tb_brand (brand_name, company_name, ordered, description, status)
    values ('三只松鼠', '三只松鼠股份有限公司', 5, '好吃不上火', 0),
           ('华为', '华为技术有限公司', 100, '华为致力于把数字世界带入每个人、每个家庭、每个组织,构建万物互联的智能世界', 1),
           ('小米', '小米科技有限公司', 50, 'are you ok', 1);

  • 在pojo包下实体类 Brand

    package com.pojo;
        /*
        * ctrl+r  替换
        * alt+鼠标左键   整列编辑
        * ctrl+alt+l   格式化代码
        * 在实体类中,基本数据类型建议使用其对应的包装类型
        *set,get方法   快捷键  fn+alt+f12
        * */
    public class Brand {
    
        // id 主键
        private Integer id;
        // 品牌名称
        private String brandName;
        // 企业名称
        private String companyName;
        // 排序字段
        private Integer ordered;
        // 描述信息
        private String description;
        // 状态:0:禁用  1:启用
        private Integer status;//int有默认值为0,不能用int类型,用int的包装类型默认值为null
    
            public Integer getId() {
                return id;
            }
    
            public void setId(Integer id) {
                this.id = id;
            }
    
            public String getBrandName() {
                return brandName;
            }
    
            public void setBrandName(String brandName) {
                this.brandName = brandName;
            }
    
            public String getCompanyName() {
                return companyName;
            }
    
            public void setCompanyName(String companyName) {
                this.companyName = companyName;
            }
    
            public Integer getOrdered() {
                return ordered;
            }
    
            public void setOrdered(Integer ordered) {
                this.ordered = ordered;
            }
    
            public String getDescription() {
                return description;
            }
    
            public void setDescription(String description) {
                this.description = description;
            }
    
            public Integer getStatus() {
                return status;
            }
    
            public void setStatus(Integer status) {
                this.status = status;
            }
    
            @Override
            public String toString() {
                return "Brand{" +
                        "id=" + id +
                        ", brandName='" + brandName + '\'' +
                        ", companyName='" + companyName + '\'' +
                        ", ordered=" + ordered +
                        ", description='" + description + '\'' +
                        ", status=" + status +
                        '}';
            }
        }
    

5.2.2 查询所有

/*
* 完成商品品牌数据的增删改查操作:
*   查询:查询所有数据
*   添加:添加品牌(id不能由用户添加)
*   修改:根据id修改
*   删除:根据id删除
*
*
* 准备环境:
*   数据库表tb_brand
*   实体类 Brand
*   测试用例
*
*
*
*
* 步骤:
*   1.获取Connection
*   2.定义sql:select * from tb_brand;
*   3.获取PrepareStatement对象
*   4.设置参数:不需要
*   5.执行sql
*   6.处理结果:List<Brand>
    7.释放资源
    *
  简化步骤:
        1.sql
        2.参数
        3.结果
* */
@Test
    public void testSelectAll() throws Exception {
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));
        //获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接onnection
        Connection conn = dataSource.getConnection();
​
        //2.定义sql
        String sql="select * from tb_brand";
​
        //3.获取preparestatement对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
​
        //4.设置参数  不需要
​
        //5.执行sql
        ResultSet rs = pstmt.executeQuery();
​
        //6.处理结果List<Brand>,每一行数据封装成Brand对象,装在List集合
        Brand brand=null;
        List<Brand> brands = new ArrayList<>();
        while(rs.next()){
            //获取数据
            int id = rs.getInt("id");
            String brandName = rs.getString("brand_name");
            String companyName = rs.getString("company_name");
            int ordered = rs.getInt("ordered");
            String description = rs.getString("description");
            int status = rs.getInt("status");
            //封装Brand对象
            brand=new Brand();
            brand.setId(id);
            brand.setBrandName(brandName);
            brand.setCompanyName(companyName);
            brand.setOrdered(ordered);
            brand.setDescription(description);
            brand.setStatus(status);
            //封装集合
            brands.add(brand);
        }
        System.out.println(brands);
​
​
        //7.释放资源
        rs.close();
        pstmt.close();
        conn.close();
    }

添加数据

/*
    * 添加:
    *   1.sql:insert into tb_brand(brand_name,company_name,ordered,description,status) values(?,?,?,?,?);
    *   2.参数,需要id以外的所有参数信息
    *   3.结果boolean类型
    *
    * 注:添加不需要id参数,id参数由系统自动生成。
    *
    * */
    @Test
    public void testAdd() throws Exception {
​
        //接受页面提交的参数
        String brandName = "香飘飘";
        String companyName = "香飘飘";
        int order = 1;
        String description = "绕地球一圈";
        int status = 1;
​
        //1.获取connection
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));
        //获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接onnection
        Connection conn = dataSource.getConnection();
​
        //2.定义sql
        String sql="insert into tb_brand(brand_name,company_name,ordered,description,status) values(?,?,?,?,?)";
​
        //3.获取preparestatement对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
​
        //4.设置参数
        pstmt.setString(1,brandName);
        pstmt.setString(2,companyName);
        pstmt.setInt(3,order);
        pstmt.setString(4,description);
        pstmt.setInt(5,status);
​
​
        //5.执行sql
        int count = pstmt.executeUpdate();//增删改用executeupdate(),该函数返回值为影响的行数
​
        //6.处理结果
        System.out.println(count>0);
​
​
        //7.释放资源
        pstmt.close();
        conn.close();
    }

修改数据

/*
    * 修改:按照id进行修改
    *   1.sql:update tb_brand set brand_name=?,company_name=?,ordered=?,description=?,status=? where id=?
    *   2.需要所有的数据
    *   3.结果boolean
    * */
    @Test
    public void testUpdateById() throws Exception {
​
        //接受页面提交的参数
        String brandName = "香飘飘";
        String companyName = "香飘飘";
        int order = 1000;
        String description = "绕地球三圈";
        int status = 1;
        int id = 4;
​
        //1.获取connection
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));
        //获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接onnection
        Connection conn = dataSource.getConnection();
​
        //2.定义sql
        String sql="update tb_brand set brand_name=?,company_name=?,ordered=?,description=?,status=? where id=?";
​
        //3.获取preparestatement对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
​
        //4.设置参数
        pstmt.setString(1,brandName);
        pstmt.setString(2,companyName);
        pstmt.setInt(3,order);
        pstmt.setString(4,description);
        pstmt.setInt(5,status);
        pstmt.setInt(6,id);
​
​
        //5.执行sql
        int count = pstmt.executeUpdate();//增删改用executeupdate(),该函数返回值为影响的行数
​
        //6.处理结果
        System.out.println(count>0);
​
​
        //7.释放资源
        pstmt.close();
        conn.close();
    }

删除数据

 /*
    * 删除:根据id删除
    *   1.sql:delete from tb_brand where id=?
    *   2.参数:需要id
    *   3.结果:boolean类型
    * */
    @Test
    public void testDeleteById() throws Exception {
​
        //接受页面提交的参数
        int id = 4;
​
        //1.获取connection
        //加载配置文件
        Properties prop = new Properties();
        prop.load(new FileInputStream("src/druid.properties"));
        //获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        //获取数据库连接onnection
        Connection conn = dataSource.getConnection();
​
        //2.定义sql
        String sql="delete from tb_brand where id=?";
​
        //3.获取preparestatement对象
        PreparedStatement pstmt = conn.prepareStatement(sql);
​
        //4.设置参数
        pstmt.setInt(1,id);
​
​
        //5.执行sql
        int count = pstmt.executeUpdate();//增删改用executeupdate(),该函数返回值为影响的行数
​
        //6.处理结果
        System.out.println(count>0);
​
​
        //7.释放资源
        pstmt.close();
        conn.close();
    }
​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

自律的光电人

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值