前言
JDBC编程~
事实上,jdbc编程非常简单,但是刚开始接触的时候,会被一堆新的类给整懵了~~(莫慌)
基本编程流程~
1.创建DataSource(表示数据库在哪)对象,这个对象就描述了数据库服务器在哪
//1.创建好数据源(指的是MySQL服务器在哪里),也就是数据库在哪,数据的源头在哪里. DataSource dataSource = new MysqlDataSource();
DataSource:JDBC带的接口
MysqlDataSource:实现DataSource接口的类
描述数据库服务器在哪里
//设置数据库所在的地址 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_106?characterEncoding=utf8&useSSL=false");
URL(Unifrom Resource Location(唯一资源定位符))就是平时说的网址!!!
就是在描述互联网上的一个资源所在的位置的~~类似于你买东西的时候写的收货地址~
mysql作为一个服务器,也是以url这样的风格来提供资源~外面要想访问mysql上的数据库,也同样通过url来进行描述~~
标红的这一串不需要背下来~后面用的时候都是复制粘贴~~
jdbc:mysql:(类型,具体叫法:协议名称)表示这个url是用于jdbc mysql的url~~
127.0.0.1:叫做ip地址(mysql服务器所在的主机的ip地址~)
ip地址就描述了网络上一个主机的位置~~
127.0.0.1这是一个特殊的ip地址,就表示你的本机ip,特殊的名字(环回ip)~
也有localhost的写法~
localhost等价于127.0.0.1(local就是本地的意思,host主机的意思)~
3306:端口号:访问你主机上的哪个程序~对应到主机上的一个具体应用程序~~
一个主机上的应用程序有很多~~收到的数据报到底给谁?得区分清楚~每个服务器程序启动的时候都关联一个端口号(整数)~
3306表示了mysql服务器安装mysql的时候,有个环节就设置了mysql服务器的端口号,默认就是3306~
java_106:数据库名.(create database 出来的那个东西)~
characterEncoding=utf8:字符集~~
注意:此处如果你的服务器字符集是utf8mb4,此处仍然写utf8~
useSSL=false:是否要传输过程中加密~~
//设置登录数据库的用户名 ((MysqlDataSource)dataSource).setUser("root");
root这是MySQL默认自带的管理员用户
也可以手动的创建出一些其他的用户来~~(此处暂时不介绍)
//设置登录数据库的密码 ((MysqlDataSource)dataSource).setPassword("123456");
这个是你在安装MySQL的时候,设置的密码~~(如果密码你忘了,最简单有效的办法,卸载重装)
补充:
2.让代码和数据库服务器建立连接~
//2.让代码和数据库服务器建立连接~ Connection connection = dataSource.getConnection();
get(获取),connection(连接),合在一起就是建立连接~
此处直接getConnertion有一个1错误提示
画红线处表明有一个受查异常,必须显示处理~getConnertion建立连接失败就会抛出这个异常
然后main函数加上这样一个声明就不会抛异常了
3.操作数据库~
以插入为例,关键所在就是构造一个SQL语句~
比如我们先创建好一个表~
现在我们就可以往class表里插入数据
//3.操作数据库,以插入数据为例 // 关键所在就是构造一个sql语句~ // 在JDBC中构造的sql,不必带上分号 // ;号只是在命令行中用来区分不同的语句,现在是直接在代码中进行操作 String sql = "insert into class values (1, 'java106')";
//此处光是一个String类型的sql还不行,需要把这个String包装成一个"语句对象" PreparedStatement statement = connection.prepareStatement(sql);
4.执行SQL~
//4.执行sql //SQL里面如果是insert ,update delete,都是用executeUpdate方法 //SQL里面如果是select ,则使用executteQuery 方法 //返回值就是表示这个操作,影响到了几行,就相当于在控制台里输入sql之后,得到的数字~ int ret = statement.executeUpdate(); System.out.println(ret);
5.释放资源~
//5.此时sql已经执行完毕,然后还需要释放资源. statement.close(); connection.close();
计算机中的很多资源都涉及到"释放操作".释放操作执行了之后就可以把之前占用的资源还回去,供其他人来使用~
当我们创建好相关的连接之后.jvm就会从系统治理申请到一些硬件操作
这些资源,不用了,就得记得释放
释放资源的时候要先释放statement,
后释放connection
(先创建的,后释放)
6.执行结果
完整代码:
public class TestJDBC { public static void main(String[] args) throws SQLException { //1.创建好数据源(指的是MySQL服务器在哪里),也就是数据库在哪,数据的源头在哪里. DataSource dataSource = new MysqlDataSource(); //设置数据库所在的地址 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_106?characterEncoding=utf8&useSSL=false"); //设置登录数据库的用户名 ((MysqlDataSource)dataSource).setUser("root"); //设置登录数据库的密码 ((MysqlDataSource)dataSource).setPassword("123456"); //2.让代码和数据库服务器建立连接~ Connection connection = dataSource.getConnection(); //3.操作数据库,以插入数据为例 // 关键所在就是构造一个sql语句~ // 在JDBC中构造的sql,不必带上分号 // ;号只是在命令行中用来区分不同的语句,现在是直接在代码中进行操作 String sql = "insert into class values (1, 'java106')"; //此处光是一个String类型的sql还不行,需要把这个String包装成一个"语句对象" PreparedStatement statement = connection.prepareStatement(sql); //4.执行sql //SQL里面如果是insert ,update delete,都是用executeUpdate方法 //SQL里面如果是select ,则使用executteQuery 方法 //返回值就是表示这个操作,影响到了几行,就相当于在控制台里输入sql之后,得到的数字~ int ret = statement.executeUpdate(); System.out.println(ret); //5.此时sql已经执行完毕,然后还需要释放资源. statement.close(); connection.close(); } }
我们看一下执行的结果:
1就是ret的值,表示有一行受到影响,我们此时执行的就是在插入一行.
还有一个很重要的问题:
刚才在插入的时候,插入的数据是直接写死的~~
写死并不好,需要灵活的处理要插入的数据~
例如:想让用户通过控制台,输入要插入的id和班级名~
如何来处理让这个用户输入的数据插入~~
此处要进行的操作,就是把id和name给替换到,insert语句的对应位置上~
用户数id替换这里的1~
name替换成这里的java106~
通过字符串拼接这个操作来构造SQL,也是可行的,但是并不科学~~
这么写非常麻烦,容易写错.拼整数还好,要是拼字符串麻烦就大了~
这么写也容易引起"sql注入攻击"黑客攻击服务器的一种手段~
这么直接拼接字符串,属于上个时代(200x的时候)
在这里我们使用一个代替的写法,避免直接拼接字符串~
通过改成问号,相当于告诉Java程序,这两个字段的值,还不确定~`
此时就使用?先占个位置~
在使用PreparedStatement的setxxx系列方法进行替换
这里就是再执行具体的替换操作~~
这边的下标从1开始计算~
第一个操作就是把第一个?给替换成id这样的值~~
第二个操作就是把第二个?给替换成name这样的值~~
PreparedStatement:这个类,除了能用于描述一个SQL之外,还可以辅助程序猿对SQL进行动态的拼接~~
我们来打印一下看看:
通过这个打印操作,就能看到拼接好之后的sql长啥样
如果要插入多条记录:
完整插入代码:
public class TestJDBC { public static void main(String[] args) throws SQLException { Scanner scanner = new Scanner(System.in); //1.创建好数据源(指的是MySQL服务器在哪里),也就是数据库在哪,数据的源头在哪里. DataSource dataSource = new MysqlDataSource(); //设置数据库所在的地址 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_106?characterEncoding=utf8&useSSL=false"); //设置登录数据库的用户名 ((MysqlDataSource)dataSource).setUser("root"); //设置登录数据库的密码 ((MysqlDataSource)dataSource).setPassword("123456"); //2.让代码和数据库服务器建立连接~ Connection connection = dataSource.getConnection(); //2.5 让用户通过控制台输入一下待插入的数据 System.out.println("请输入班级号:"); int id = scanner.nextInt(); System.out.println("请输入班级名字"); String name = scanner.next(); //3.操作数据库,以插入数据为例 // 关键所在就是构造一个sql语句~ // 在JDBC中构造的sql,不必带上分号 // ;号只是在命令行中用来区分不同的语句,现在是直接在代码中进行操作 String sql = "insert into class values (?, ?)"; //此处光是一个String类型的sql还不行,需要把这个String包装成一个"语句对象" PreparedStatement statement = connection.prepareStatement(sql); //进行替换 statement.setInt(1,id); statement.setString(2,name); System.out.println("statement" + statement); //4.执行sql //SQL里面如果是insert ,update delete,都是用executeUpdate方法 //SQL里面如果是select ,则使用executteQuery 方法 //返回值就是表示这个操作,影响到了几行,就相当于在控制台里输入sql之后,得到的数字~ int ret = statement.executeUpdate(); System.out.println(ret); //5.此时sql已经执行完毕,然后还需要释放资源. statement.close(); connection.close(); } }
完整删除代码~
public class TestJDBCDelete { public static void main(String[] args) throws SQLException { //删除数据库中的记录 //让用户输入一个id,根据id来删除 //1.创建数据源 DataSource dataSource = new MysqlDataSource(); //设置数据库所在地址 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_106?characterEncoding=utf8&useSSL=false"); //设置数据库用户名 ((MysqlDataSource)dataSource).setUser("root"); //设置数据库密码 ((MysqlDataSource)dataSource).setPassword("123456"); //2.建立连接 Connection connection = dataSource.getConnection(); //3.用户输入id Scanner scanner = new Scanner(System.in); System.out.println("请输入一个要删除的id:"); int id = scanner.nextInt(); //4.拼装sql语句 String sql = "delete from class where id = ?"; PreparedStatement statement = connection.prepareStatement(sql); //进行替换 statement.setInt(1,id); //5.执行SQL int ret = statement.executeUpdate(); System.out.println("statement:" + statement); //6.回收释放资源 statement.close(); connection.close(); } }
和前面的插入操作代码不能叫做非常相似,只能叫做一模一样~
结果:
就咱们的JDBC这里翻来覆去都是这些东西~
固定的代码,写来写去~~
完整修改代码~
public class TestJDBCUpdate { public static void main(String[] args) throws SQLException { //根据id来修改班级名字,让用户输入要修改的id,以及对应的修改后的名字 //1.创建数据源 DataSource dataSource = new MysqlDataSource(); //设置数据库网址 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_106?characterEncoding=utf8&useSSL=false"); //设置数据库用户名 ((MysqlDataSource)dataSource).setUser("root"); //设置数据库密码 ((MysqlDataSource)dataSource).setPassword("123456"); //2.和数据库建立连接 Connection connection = dataSource.getConnection(); //让用户输入信息 Scanner scanner = new Scanner(System.in); System.out.println("请输入要修改的班级id:"); int id = scanner.nextInt(); System.out.println("请输入要修改的班级名称:"); String name = scanner.next(); //4.拼装SQL String sql = "update class set name = ? where id = ? "; PreparedStatement statement = connection.prepareStatement(sql); //进行替换 statement.setString(1,name); statement.setInt(2,id); System.out.println("statement" + statement); //5.执行sql int ret = statement.executeUpdate(); System.out.println("ret = " + ret); //6.回收释放资源 statement.close(); connection.close(); } }
打印结果
完整查询代码~
public class TestJDBCSlest { public static void main(String[] args) throws SQLException { //1.创建数据源 DataSource dataSource = new MysqlDataSource(); //设置数据库地址 ((MysqlDataSource)dataSource).setURL("jdbc:mysql://127.0.0.1:3306/java_106?characterEncoding=utf8&useSSL=false"); //设置数据库用户名 ((MysqlDataSource)dataSource).setUser("root"); //设置数据库密码 ((MysqlDataSource)dataSource).setPassword("123456"); //2.和数据库建立连接 Connection connection = dataSource.getConnection(); //3.拼装sql String sql = "select * from class"; PreparedStatement statement = connection.prepareStatement(sql); //4.执行sql 对于查询操作,就需要使用 executeQuery了 // 查询操作返回的不是一个int了,而是一个"临时表" //使用 ResultSet 表示这个表 ResultSet resultSet = statement.executeQuery(); //5.遍历结果集合(返回的临时表),先获取到每一行,在获取到这一行的若干列 //next方法表示获取到一行记录,同时把光标往后移动一行 //如果遍历到表的结束位置,此处的next直接返回false了 //+------+---------+ //| id | name | //+------+---------+ //| 2 | java109 | //+------+---------+ while(resultSet.next()){ //针对当前这一行来获取到其中的列 int id = resultSet.getInt("id"); String name = resultSet.getString("name"); System.out.println("id = " + id + ", name = " + name); } //6.释放资源 resultSet.close(); statement.close(); connection.close(); } }
当前表中有一条记录~
每个记录都是一列~
通过while循环,搭配resultSet,next()
就能依次获取到表中的每一行
第一次执行resultSet,next(),就表示获取到了第一行(id = 2)
第二次执行resultSet,next(),由于表已经到达了末尾,next方法返回false
循环就结束了
打印结果:
不管是多复杂的查询,你查询1的结果一定是一个"表"这样的结构.
仍然是 resultSet 先拿到每一行,然后再依次拿到其中的每一列~~