重学JavaWeb(11)JDBC
1. JDBC概念
1. 概念:Java Database Connectivity (Java连接数据库)
2. 本质:JDBC的本质就是Java定义的一套和数据库建立连接的规范(接口),想要用Java去操作数据库就必须实现这套接口
2. JDBC快速入门
1. 步骤
1. 导入驱动jar包
2. 加载驱动
3. 获取连接对象
4. 获取操作对象
5. 发送sql语句执行操作
6. 释放资源
2. 代码示例
public class TestDemo01 {public static void main(String[] args) throws Exception {//2. 加载驱动Class.forName("com.mysql.jdbc.Driver");//3. 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/loler","root","root");//4. 获取操作对象Statement statement = connection.createStatement();//5. 定义,发送sqlString sql = "insert into players values(null,'hi',13)";int i = statement.executeUpdate(sql); //i 返回影响的行数if (i != 0){System.out.println("success");}else {System.out.println("false");}//6. 释放资源connection.close();statement.close();}
}
3. JDBC中的各个对象详解
(1)DriverManager:驱动管理对象
1. 注册驱动:告诉程序该使用那一个数据库驱动jarstatic void registerDriver(Driver driver):注册与给定驱动的程序DriverManager写代码使用:Class.forName("com.mysql.jdbc.Driver")通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块static {try {java.sql.DriverManager.registerDriver(new Driver());} catch (SQLException E) {throw new RuntimeException("Can't register driver!");}}2. 获取数据库链接方法:static Connection(String url,String user,String password)参数:url:指定的连接路径语法:jdbc:mysql://IP地址:端口号/数据库名称例如:jdbc:mysql://localhost:3306/db1简写为:jdbc:mysql:///db1(链接的是本机服务器,并且mysql的端口号为3306)user:用户名password:密码
(2)Connection:数据库连接对象
1. 获取执行sql的对象Statement createStatment()PreparedStatement prepareStatement(String sql)
2. 管理事务开启事务:setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务提交事务:commit()回滚事务:rollback()
(3)Statement:执行sql的对象
1. 执行sql1. boolean execute(String sql):可以执行任意的sql --了解2. int executeUpdate(String sql):执行DML(insert,update,delete)语句DDL(create,alter,drop)语句3. ResultSet executeQuery(String sql):执行DQL(select)语句
(4)ResultSet:结果集对象,封装查询结果
1. boolean next():游标向下移动一行,判断当前行是否到大最后一行末尾。如果是返回false,如果不是返回true
2. getXxx(参数):获取数据1. Xxx:代表数据类型。如getInt,getString2. 参数:1. int:代表列的编号,从1开始,如getInt(1)2. String:代表列名称,如getString("name")
3. 使用步骤1. 游标向下移动一行2. 判断是否有数据3. 获取数据
3. JDBC的两类操作
1. 执行修改语句:executeUpdate
public class TestDemo01 {public static void main(String[] args) throws Exception {//2. 加载驱动Class.forName("com.mysql.jdbc.Driver");//3. 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/loler","root","root");//4. 获取操作对象Statement statement = connection.createStatement();//5. 定义,发送sql(四种sql任选一个)String sql = "insert into players values(null,'hi',13)"; //添加语法String sql = "delete from players where id = 3"; //删除语法String sql = "update players set age = 15 where id = 5"; //修改语法String sql = "create table lol(id int,name varchar)"; //创建表int i = statement.executeUpdate(sql); //i 返回影响的行数if (i != 0){System.out.println("success");}else {System.out.println("false");}//6. 释放资源connection.close();statement.close();}
}
2. 执行查询语句:executeQuery
public class TestDemo02 {public static void main(String[] args) throws Exception {//2. 加载驱动Class.forName("com.mysql.jdbc.Driver");//3. 获取连接对象Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/loler", "root", "root");//4. 获取操作对象Statement statement = connection.createStatement();//5. 定义,发送sqlString sql = "select * from players";ResultSet resultSet = statement.executeQuery(sql);//将查询出来的结果封装到对象中ArrayList<LOL> list = new ArrayList<LOL>();while (resultSet.next()) {//根据列号或者列名获取数据int id = resultSet.getInt(1);String name = resultSet.getString("name");int age = resultSet.getInt("age");System.out.println(id + "==" + name + "==" + age);LOL lol = new LOL(id, name, age);list.add(lol);}for (LOL lol : list) {System.out.println(lol);}connection.close();statement.close();resultSet.close();}
}===============================================================================================public class LOL {private int id;private String name;private int age;public LOL() {}public LOL(int id, String name, int age) {this.id = id;this.name = name;this.age = age;}public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}@Overridepublic String toString() {return "LOL{" +"id=" + id +", name='" + name + '\'' +", age=" + age +'}';}
}
4. 关于SQL注入的一些问题
1. 首先看一下这个原始的登陆案例的代码
public class TestDemo01 {public static void main(String[] args) throws Exception {Scanner scanner = new Scanner(System.in);System.out.println("请输入用户名");String username = scanner.nextLine();System.out.println("请输入密码");String password = scanner.nextLine();Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/loler", "root", "root");Statement statement = connection.createStatement();String sql = "select * from users where username = '" + username + "' and password = '" + password + "'";ResultSet resultSet = statement.executeQuery(sql);if (resultSet.next()){System.out.println("success");}else {System.out.println("false");}connection.close();statement.close();resultSet.close();}
}
2. 但是总有一些骚操作,能破解这个登陆案例,比如
1. 输入用户随便,输入密码:a' or 'a' = 'a
2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a'
3. 所以为了解决这个问题,要使用PreparedStatement对象解决
(1)步骤
1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义sql注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;
5. 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
6. 给?赋值:方法: setXxx(参数1,参数2)参数1:?的位置编号 从1 开始参数2:?的值
7. 执行sql,接受返回结果,不需要传递sql语句
8. 处理结果
9. 释放资源
(2)代码示例
public class TestDemo02 {public static void main(String[] args) throws Exception {Scanner scanner = new Scanner(System.in);System.out.println("请输入用户名");String username = scanner.nextLine();System.out.println("请输入密码");String password = scanner.nextLine();//2. 注册驱动Class.forName("com.mysql.jdbc.Driver");//3. 获取数据库连接对象 ConnectionConnection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/loler", "root", "root");//4. 定义sql//注意:sql的参数使用?作为占位符。 如:select * from user where username = ? and password = ?;String sql = "select * from users where username = ? and password = ?";//5. 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)PreparedStatement preparedStatement = connection.prepareStatement(sql);//6. 给?赋值://方法: setXxx(参数1,参数2)//参数1:?的位置编号 从1 开始//参数2:?的值preparedStatement.setString(1,username);preparedStatement.setString(2,password);//7. 执行sql,接受返回结果,不需要传递sql语句ResultSet resultSet = preparedStatement.executeQuery();//8. 处理结果if (resultSet.next()) {System.out.println("success");}else {System.out.println("false");}//9. 释放资源connection.close();preparedStatement.close();resultSet.close();}
}
5. JDBCUtils类
1. 原始的代码很麻烦
public class TestDemo01 {public static void main(String[] args) throws Exception {Class.forName("com.mysql.jdbc.Driver");Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/loler","root","root");String sql = "select * from users where username = ?";PreparedStatement preparedStatement = connection.prepareStatement(sql);preparedStatement.setString(1,"zhangsan");ResultSet resultSet = preparedStatement.executeQuery();while (resultSet.next()) {String username = resultSet.getString("username");String password = resultSet.getString("password");System.out.println(username + "==" + password);}connection.close();preparedStatement.close();resultSet.close();}
}
2. 创建一个JDBCUtils
public class TestDemo02 {public static void main(String[] args) throws Exception {//获取连接对象Connection connection = JDBCUtils.getConnection();PreparedStatement preparedStatement = connection.prepareStatement("select * from users where id = ?");preparedStatement.setString(1,"1");ResultSet resultSet = preparedStatement.executeQuery();while (resultSet.next()) {String username = resultSet.getString("username");String password = resultSet.getString("password");System.out.println(username + "-->" + password);}JDBCUtils.close(connection,preparedStatement,resultSet);}
}===============================================================================================public class JDBCUtils {private static String url;private static String username;private static String password;//私有构造private JDBCUtils(){}static{try {Properties properties = new Properties();properties.load(new FileInputStream("JdbcConfig.properties"));Class.forName(properties.getProperty("className"));url = properties.getProperty("url");username = properties.getProperty("username");password = properties.getProperty("password");} catch (Exception e) {e.printStackTrace();}}//获取连接对象public static Connection getConnection() throws SQLException {Connection connection = DriverManager.getConnection(url, username, password);return connection;}//释放资源的方法public static void close(Connection connection, Statement statement, ResultSet resultSet) throws SQLException {if (connection != null) {connection.close();}if (statement != null) {statement.close();}if (resultSet != null) {resultSet.close();}}
}===============================================================================================className = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/loler
username = root
password = root
6. PreparedStatment的批处理
public class TestDemo01 {public static void main(String[] args) throws Exception {ArrayList<User> list = new ArrayList<User>();for (int i = 1; i <= 1000; i++) {User user = new User(i, "aaa" + i, "123456");list.add(user);}//插入数据Connection connection = JDBCUtils.getConnection();PreparedStatement preparedStatement = connection.prepareStatement("insert into users values (?,?,?)");for (User user : list) {preparedStatement.setInt(1,user.getId());preparedStatement.setString(2,user.getUsername());preparedStatement.setString(3,user.getPassword());//preparedStatement.executeUpdate(); 一行一行操作,效率较慢//先把数据缓存起来preparedStatement.addBatch(); //添加到批处理}//统一执行批处理preparedStatement.executeBatch();//清空缓存preparedStatement.clearBatch();//释放资源JDBCUtils.close(connection,preparedStatement);}
}
7. JDBC调用函数
1. sql语句的格式
{?=call<procedure -name >[( < arg1 >,<arg2 >, ...)]}?为返回值
2. 代码示例
public class TestDemo01 {public static void main(String[] args) throws Exception {Connection connection = JDBCUtils.getConnection();//{?=call<procedure -name >[( < arg1 >,<arg2 >, ...)]}String sql = "{? = call md5(?)}";CallableStatement callableStatement = connection.prepareCall(sql);//第一个?是返回值,第二个问号是传入的参数callableStatement.setString(2,"123456");//注册输出参数callableStatement.registerOutParameter(1, Types.VARCHAR);//执行callableStatement.execute();//获取函数的返回值String md5Str = callableStatement.getString(1);System.out.println(md5Str); //e10adc3949ba59abbe56e057f20f883econnection.close();callableStatement.close();}
}
8. JDBC获取自增长键的值
public class TestDemo01 {public static void main(String[] args) throws Exception {Connection connection = JDBCUtils.getConnection();//如果你要获取这个自增长键的值,那就再加一个参数 Statement.RETURN_GENERATED_KEYSPreparedStatement preparedStatement = connection.prepareStatement("insert into players(name,age) values (?,?)", Statement.RETURN_GENERATED_KEYS);preparedStatement.setString(1,"格雷福斯");preparedStatement.setInt(2,33);preparedStatement.executeUpdate();//获取自增长键的值ResultSet generatedKeys = preparedStatement.getGeneratedKeys();while (generatedKeys.next()){int keysInt = generatedKeys.getInt(1);System.out.println(keysInt); //6}JDBCUtils.close(connection,preparedStatement,generatedKeys);}
}
9. 事务
1. 事务的概念:一个操作,这个操作可能会包含很多的步骤,那么这些步骤必须看成一个整体来组成这个事务,这些组成事务的步骤,要么同时成功,要么同时失败,不允许成功几个步骤失败几个步骤
2. 事务的特性
(1)原子性:原子性是指事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生
(2)一致性:事务必须使数据库从一个一致性状态变换到另外一个一致性状态
(3)隔离性:事务的隔离性是多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的操作数据所干扰,多个并发事务之间要相互隔离
(4)持久性:持久性是指一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障也不应该对其有任何影响
3. 举例
(1)张三给李四转账,张三的账户 -100,李四的账户 +100
(2)默认情况下,自动开启事务,自动提交事务
(3)我们应该把减钱和加钱放到同一个事务中去操作,一旦发生异常,就回滚整个事务
public class TestDemo01 {public static void main(String[] args) throws Exception {Connection connection = null;try {connection = JDBCUtils.getConnection();connection.setAutoCommit(false); //把事务设置为手动提交String sql1 = "update bank set money = money - 100 where name = '张三'";PreparedStatement preparedStatement = connection.prepareStatement(sql1);int i = preparedStatement.executeUpdate();System.out.println(1/0); //模拟异常String sql2 = "update bank set money = money + 100 where name = '李四'";PreparedStatement preparedStatement2 = connection.prepareStatement(sql2);int i1 = preparedStatement2.executeUpdate();} catch (Exception e) {e.printStackTrace();//一旦遇到异常就回滚事务connection.rollback();} finally {//手动提交事务connection.commit();}System.out.println("转账完成");}
}
重学JavaWeb(11)JDBC相关推荐
- 重学JavaWeb —— JSP,简单全面一发入魂
文章目录 JSP 特点 由来 本质 使用 JSP指令 page include taglib JSP脚本 JSP内置对象 JSP作用域 EL表达式 EL内置对象 EL取值方式 JSP动作元素 JSTL ...
- 重学JavaWeb —— Servlet,简单全面一发入魂
文章目录 Servlet 概述 基本使用 两个重要对象 请求转发 会话技术 Cookie Session 对比小结 其它相关对象 ServletContext ServletConfig 过滤器 概述 ...
- 重学JavaWeb(3)JSON、AJAX
1. JSON 1. 概念:JavaScript Object Notation:JavaScript对象表示法 2. JSON的特点 (1)JSON是一种轻量级的数据交换格式 (2)JSON是一种独 ...
- JavaWeb:JDBC之事务
系列阅读 JavaWeb:用JDBC操作数据库 JavaWeb:JDBC之事务 JavaWeb:JDBC之数据库连接池 使用JDBC实现水果超市管理系统 1. 事务 事务的四大特性:ACID mysq ...
- JavaWeb:JDBC之数据库连接池
JDBC系列阅读 JavaWeb:用JDBC操作数据库 JavaWeb:JDBC之事务 JavaWeb:JDBC之数据库连接池 使用JDBC实现水果超市管理系统 1. 池参数(所有池参数都有默认值) ...
- 判断字符串 正则_(重学前端 - JavaScript(模块一)) 14、引用类型之 RegExp (正则)(详述)...
上一篇文章介绍了 JavaScript 中的 Date 类型,从地理方面的原理知识开始入手,如果大家认真看过上一篇文章,相信 JavaScript 中的 Date 类型已经难不住大家了!!! 但是今天 ...
- 重学python入门知识
为什么重学 基础是保障,不重基础后面真的很难走. 神经网络学习遇到瓶颈了,那些代码真看不下去了,还是学长了解我们,安排了个看基础的任务 哈哈. 还是画上两个小时看看基础吧,找找自信的同时查缺补漏,希望 ...
- 重学数据结构——快速排序,二分法查找
每次提起快排,内心中都有点隐隐作痛. 当时腾讯的那个面试官让我写快排的前两遍排序结果,结果,我当时居然没写上来-- 这个,就是所谓的关键时刻掉链子吧,这么经典的快排都不会,真是丢死人了-- 今天在实验 ...
- 重学JavaScript系列之一_引用类型
重学JavaScript系列之一_引用类型 ECMAScript中,引用数据是一种数据结构,用于将数据和功能组织在一起,有时候被称为类 ES6中使用Class定义一个类 引用类型的值(对象)是引用类型 ...
最新文章
- JasperReports是一个开源的java报表制作引擎
- vue 仿二手交易app_项目vue2.0仿外卖APP(七)
- Java程序设计 图形用户界面 小巫版简易计算器
- 使用了JDK自带的jconsole查看Tomcat运行情况
- Redis 配置文件参数说明
- 计算机硬件系统储存包括那些,硬件系统包括什么
- 源码:Mybatis的LogFactory生成逻辑
- C# 微信JS-SDK之config接口注入权限验证invalid signature签名错误
- 关于blocked by CORS policy的跨域问题
- Pytorch 利用Facenet和Retinaface实现人脸识别
- 移动互联网,政府服务怎么做?
- 用手机打开word图表位置很乱_word排版技巧:论文图表目录制作步骤
- 华清远见上海中心培训感言
- 3、中小企业网络架构-接入层交换机基本配置
- day 1 学习MySQL数据库作业 - 创建员工表思考与表之间的关系
- unity热更- 2 游戏大版本更新和热更新
- Twipstopixels java_Access量度单位缇与像素,厘米等的换算关系
- 概述和HTTP请求与响应处理
- 关于weekendd_
- python 爬虫抓取斗鱼直播间弹幕