


Java程序需要通过数据库驱动才能连接到数据库,因此需要注册驱动

JDBC注册驱动
java.sql.DriverManager类用于注册驱动。提供如下方法注册驱动
static void registerDriver(Driver driver) // 向DriverManager 注册给定驱动程序
示例代码
public class Demo01 {
public static void main(String[] args) throws Exception {
// 注册驱动
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
}
}
提示
Connection 介绍
表示Java程序与数据库之间的连接,只有拿到Connection才能操作数据库
| DriverManager类中的静态方法 | 描述 |
|---|---|
| static Connection getConnection(String url, String user, String password) | 连接到给定数据库URL,并返回连接 |
参数说明
连接数据库的URL地址格式
MySQL写法
如果是本地服务器,端口号是默认的3306,则可以简写
在java.sql.Connection接口中有如下方法获取到Statement对象
Statement createStatement() // 创建一个Statement对象来将SQL语句发送到数据库
代码案例
// 1.注册驱动
// 2.获取连接
Connection conn = DriverManager.getConnection("jdbc:mysql:///day03", "root", "123");
// 3.获取Statement
Statement stmt = conn.createStatement();
我们要对数据库进行增、删、改、查,需要使用Statement对象来执行SQL语句
Statement的API介绍
ResultSet executeQuery(String sql)
// 用于执行查询语句; 返回查询到的结果集
int executeUpdate(String sql)
// 用于执行除查询外的SQL; 返回影响的行数
ResultSet用于保存执行查询SQL语句的结果。我们不能一次性去除所有的数据,需要一行一行的去除
ResultSet内部有一个指针,记录获取到哪行数据
获取查询结果
boolean next():
/*
(1) 将光标从当前位置向前移动一行
(2)判断当前行是否为有效行
返回值:
true:有效行,当前行有数据
false:无效行,当前行没有数据
*/
应用案例
while (rs.next()) {
rs.getXxx(字段名); // 取出数据
}
ResultSet获取数据的API是有规律的get后面加数据类型。我们统称getXXX()
| 方法名 | 说明 |
|---|---|
| boolean getBoolean(String columnLabel) | 获取boolean值 |
| byte getByte(String columnLabel) | 获取byte值 |
| double getDouble(String columnLabel) | 获取double值 |
| int getInt(String columnLabel) | 获取int值 |
| long getLong(String columnLabel) | 获取long值 |
| String getString(String columnLabel) | 获取String值 |

JDBC操作银行转账的事务

使用步骤
demo
package _02MySQL.Day03_JDBC.demo05_事务处理_重点;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* JDBC事务处理
*
* 数据准备:
* CREATE TABLE tb_account (
* id INT PRIMARY KEY AUTO_INCREMENT,
* NAME VARCHAR(10),
* balance DOUBLE
* );
*
*-- 添加数据
* INSERT INTO tb_account (NAME, balance) VALUES ('张三', 1000), ('李四', 1000);
*/
public class Demo05 {
public static void main(String[] args) throws SQLException{
// 1. 注册驱动
Connection connection = null;
try {
// 2. 获取数据库连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "123");
// 3. 开启事务
connection.setAutoCommit(false); // 关闭自动提交
// 4. 获取Statement对象
Statement statement = connection.createStatement();
// 5. 执行SQL
String sql1 = "update tb_account set balance = balance - 500 where name = '张三'";
String sql2 = "update tb_account set balance = balance + 500 where name = '李四'";
statement.executeUpdate(sql1);
statement.executeUpdate(sql2);
// 模拟失败
// ...
// 6. 提交事务
System.out.println("提交事务!");
connection.commit();
} catch (Exception e) {
// 6. 有异常,事务回滚
if (connection != null) {
connection.rollback();
}
}finally {
// 7. 关闭资源
if (connection != null) {
connection.close();
}
}
}
}
模拟用户输出账号和密码登录网站
案例分析
Demo
package com.itheima.demo06_JDBC实现用户登录;
import java.sql.*;
import java.util.Scanner;
/**
* JDBC实现用户登录案例
*/
public class Demo06 {
public static void main(String[] args) throws SQLException {
Scanner scanner = new Scanner(System.in);
String userName = null;
String password = null;
// 1. 接收用户名
while (true) {
System.out.println("请输入用户名:");
String line = scanner.nextLine();
if ("".equals(line)) {
continue;
}
userName = line;
break;
}
// 2.接收用户密码
while (true) {
System.out.println("请输入密码:");
String line = scanner.nextLine();
if ("".equals(line)) {
continue;
}
password = line;
break;
}
// 3.根据用户名和密码,查询用户
String sql = "SELECT * FROM USER WHERE NAME = '" + userName + "' AND PASSWORD = '" + password + "';";
String jdbcUrl = "jdbc:mysql://localhost:3306/day03";
Connection conn = DriverManager.getConnection(jdbcUrl, "root", "root");
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
// 4.根据查询结果,判断是否登录成功
// 4.1 如果查询到数据,显示登录成功
if (rs.next()) {
System.out.println("登录成功!欢迎您," + userName);
} else {
// 4.2 如果查询不到数据,显示登录失败
System.out.println("登录失败!用户名或密码错误...");
}
}
}
在我们前面JDBC实现登录案例中,当我们输入以下密码的时候,可以发现账号和密码都不对竟然登录成功了!
请输入用户名:
hehe
请输入密码:
a'or'1'='1
字符串拼接,把输入的字符串全都将其视为sql语句,导致statement对象查询直接为真,条件不起作用!
问题分析
"SELECT * FROM user WHERE name='" + name + "' AND password='" + password + "';";
// 将用户输入的账号密码拼接后
"SELECT * FROM user WHERE name='hehe' AND password='a'or'1'='1';"
SQL注入攻击的原理
PreparedStatement预编译执行者对象
PreparedStatement使用
设置参数
执行SQL语句
demo
String sql = "SELECT * FROM USER WHERE NAME=? AND PASSWORD=?;";
PreparedStatement pstmt = conn.prepareStatement(sql);
pstmt.setString(1, “zhangsan”);
pstmt.setString(2, “6666”);
package _02MySQL.Day03_JDBC.demo08_PreparedStatement改写登录案例;
import java.sql.*;
import java.util.Scanner;
/**
* PreparedStatement改写登录案例
*/
public class Demo08 {
public static void main(String[] args) throws SQLException {
// 1. 注册驱动
// 2. 获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "123");
// 3. 获取PreparedStatement对象
String sql = "select * from day03.user where phoneNumber = ? and password = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 准备参数
Scanner scanner = new Scanner(System.in);
String phoneNumber = null;
String password = null;
do {
System.out.print("请输入账号:");
phoneNumber = scanner.nextLine();
} while ("".equals(phoneNumber));
do {
System.out.print("请输入密码: ");
password = scanner.nextLine();
} while ("".equals(password));
// 4. 执行SQL语句
preparedStatement.setString(1, phoneNumber);
preparedStatement.setString(2, password);
ResultSet resultSet = preparedStatement.executeQuery();
// 5. 处理结果
if (resultSet.next()) {
System.out.println("欢迎您,尊敬的" + phoneNumber + "用户");
}else {
System.out.println("账号或密码错误!");
}
// 6. 释放资源
connection.close();
}
}
javax.sql.DataSource表示数据库连接池,也是JDK中提供的一个接口,没有具体的实现,它的实现由连接池的厂商去实现。我们只需要学习这个工具如何使用
public interface DataSource{
Connection getConnection();
...
}
常用的连接池实现组件有以下这些
Druid是阿里巴巴开发的号称为监控而生的数据库连接池,Druid是目前最好的数据库连接池。在功能、性能、扩展性方面,都超过了其他数据连接池,同时加入了日志监控,可以很好的监控数据库连接池和SQL的执行情况。
Druid常用的配置参数
| 方法名 | 说明 |
|---|---|
| initialSize | 刚启动连接池时,连接池中包含连接的数量 |
| maxActive | 连接池中最多可以放多少个连接 |
| maxWait | 获取连接时最大等待时间,单位毫秒 |
com.alibaba.druid.pool.DruidDataSourceFactory类创建连接池的方法
public static DataSource createDataSource(Properties properties) // 创建一个连接池,连接池的参数使用properties中的数据
我们可以看到Druid连接池在创建的时候需要一个Properties对象来设置参数,所以我们使用properties文件来保存对应的参数。Druid连接池的配置文件名称随便,放到src目录下面方便加载
druid.properties文件内容
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/day17
username=root
password=root
initialSize=5
maxActive=10
maxWait=3000
Demo类
package _02MySQL.Day03_JDBC.demo10_JDBC增删改查练习;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
/**
* JDBC增删改查练习---- 完成商品品牌数据的增删改查操作
* 查询数据:查询所有数据
* 添加数据:添加品牌
* 修改数据:根据id修改
* 删除数据:根据id删除
*/
public class Demo10 {
/*
数据准备:
创建一个商品品牌的数据库表 tb_brand
创建一个Brand实体类
*/
public static void main(String[] args) throws Exception {
// 1. 增加数据
// addBrand();
// 2. 删除数据
deleteBrand();
// 3. 修改数据
editBrand();
// 4. 查询数据
seekBrand();
}
public static void addBrand() throws SQLException {
// 获取连接
Connection connection = DataSourceUtils.getConnection();
// 获取preparedStatement对象
String sql = "insert into day03.tb_brand (brand, description, headquarters) values" +
"(?, ?, ?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, "格力空调");
preparedStatement.setString(2, "美好生活格力造");
preparedStatement.setString(3, "China");
// 得到statement对象返回的影响行数
int i = preparedStatement.executeUpdate();
System.out.println(i);
// 将连接返回给连接池
connection.close();
}
// 根据id删除数据
public static void deleteBrand() throws SQLException {
// 获取连接
Connection connection = DataSourceUtils.getConnection();
// 编写删除数据的SQL, 并获取preparedStatement对象
String sql = "delete from day03.tb_brand where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 5);
// 执行SQL, 返回影响的行数
int i = preparedStatement.executeUpdate();
System.out.println(i);
// 将连接返回给连接池
connection.close();
}
// 根据id编辑数据
public static void editBrand() throws SQLException {
// 获取连接
Connection connection = DataSourceUtils.getConnection();
// 编写sql,并获取preparedStatement对象
String sql = "update day03.tb_brand set brand = ?, description = ?, headquarters = ? where id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 补全SQL
preparedStatement.setString(1, "华强北");
preparedStatement.setString(2, "天上地下我华强北说第二,谁敢说第一");
preparedStatement.setString(3, "中国深圳");
preparedStatement.setInt(4, 1);
// 执行SQL语句, 返回影响的行数
int i = preparedStatement.executeUpdate();
System.out.println(i);
// 关闭连接,将连接返回给连接池
connection.close();
}
public static void seekBrand() throws SQLException {
// 获取连接
Connection connection = DataSourceUtils.getConnection();
// 获取Statement对象
String sql = "select * from day03.tb_brand";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
// 得到数据集合
ResultSet resultSet = preparedStatement.executeQuery();
// 处理数据
List<Brand> brandList = new ArrayList<>(); // 存储数据
while (resultSet.next()) {
int id = resultSet.getInt("id");
String brand = resultSet.getString("brand");
String description = resultSet.getString("description");
String headquarters = resultSet.getString("headquarters");
brandList.add(new Brand(id, brand, description, headquarters));
}
brandList.forEach((brand) -> System.out.println("data = " + brand));
// 将连接返回给连接池
connection.close();
}
}
DataSourceUtils工具类(获取Datasource)
package _02MySQL.Day03_JDBC.demo10_JDBC增删改查练习;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Properties;
/**
* 工具类
* -- 创建Druid连接池
*/
public class DataSourceUtils {
private static DataSource dataSource;
static { // 利用静态代码块加载创建连接池的操作
try {
// 1. 载入配置文件
// 获取properties配置文件
InputStream inputStream = DataSourceUtils.class.getResourceAsStream("brand.properties");
Properties properties = new Properties();
properties.load(inputStream);
// 2. 创建连接
dataSource = DruidDataSourceFactory.createDataSource(properties);
}catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConnection() throws SQLException {
return dataSource.getConnection();
}
}
Brand实体类
package _02MySQL.Day03_JDBC.demo10_JDBC增删改查练习;
public class Brand {
private int id;
private String brand;
private String description;
private String headquarters;
public Brand(int id, String brand, String description, String headquarters) {
this.id = id;
this.brand = brand;
this.description = description;
this.headquarters = headquarters;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getBrand() {
return brand;
}
public void setBrand(String brand) {
this.brand = brand;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getHeadquarters() {
return headquarters;
}
public void setHeadquarters(String headquarters) {
this.headquarters = headquarters;
}
@Override
public String toString() {
return "Brand{" +
"id=" + id +
", brand='" + brand + '\'' +
", description='" + description + '\'' +
", headquarters='" + headquarters + '\'' +
'}';
}
}
brand.properties配置文件
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/day03
username=root
password=123
initialSize=5
maxActive=10
maxWait=3000
1.什么是JDBC?Java数据库连接,(JavaDatabaseConnectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是SunMicrosystems的商标。我们通常说的JDBC是面向关系型数据库的。简而言之,JDBC就是JDK提供的关于数据库操作的一套接口规范,不同数据库厂商来负责实现这个接口,完成指定的操作。用程序和数据建立连接,分为三步骤:1.连接数据库2.执行SQL语句3.把查询到的结果集转换成JAVA对象2.对于MySQL的JDBC编程的前期准备工作知识拓展:JAR文件(Java归
我遇到了错误“2013-03-06”的未定义方法`strftime':String当尝试使用strftime从字符串2013-03-06正常显示日期(2013年6月3日或类似日期)时。在我的index.html.erb中执行此操作的行看起来像这样我只是在学习Rails,所以我确信这只是一个愚蠢的初学者错误,我们将不胜感激。谢谢 最佳答案 当strftime是时间/日期类的方法时,您的截止日期看起来是一个字符串。你可以试试这个:Date.parse(task.duedate).strftime("%B%e,%Y")
目录1.数据库编程:JDBC2.JDBC工作原理3.JDBC使用3.1驱动包的下载与导入3.2JDBC使用步骤(插入)4.JDBC修改删除查询1.将数据库驱动包,添加到项目依赖中创建目录,拷贝jar包,然后addaslibrary2.创建数据源DataSourse:数据源,描述了数据库服务器在哪里3.和数据库建立连接使用JDBC里的Connection将代码和数据库服务器进行连接一个程序中,通常有一个数据源对象,可以有多个Connection对象4.构造sql语句PreparedStatement:表示一个预处理过的SQL语句对象5.执行sql语句(1)executeUpdate对应插入到删除
这个问题在这里已经有了答案:ParsingRFC-3339/ISO-8601date-timestringinGo(8个答案)关闭3年前。我将如何解析这个时间戳?“2019-09-1904:03:01.770080087+0000UTC”我尝试了以下方法:formatExample:=obj.CreatedOn//obj.CreatedOn="2019-09-1904:03:01.770080087+0000UTC"time,err:=time.Parse(formatExample,obj.CreatedOn)check(err)fmt.Println(time)但我得到的输出是:0
goversiongo1.8.1windows/amd64我正在导入"github.com/mattn/go-oci8""database/sql"用于连接到我的oracle数据库。在这里,当我在连接字符串中提供数据库用户名、密码、端口和表名时funcopenAndConnectToDb(sbconfigConnectorConfig)*sql.DB{logger:=sbgoclient.Loglogger.Println("Openthedatabase")//oraprop:=LoadConfig("oraproperties.yml")fmt.Println("Loadconfi
近日,openEulerRISC-V23.03创新版本正式发布。openEulerRISC-VSIG作为openEuler系统在RISC-V架构上的维护组织,主要致力于openEuler在RISC-V软硬件方面的适配,一直跟随openEuler版本节奏提供openEuler的RISC-V镜像版本。本次更新带来更好的硬件支持,更多的软件适配,包括VisionFive2,SG2042等多款新开发板的默认支持、UKUI,GNOME等多个桌面环境的新增适配、容器及其工具的适配,另外,还默认新增JIT支持以及针对性优化。镜像下载链接https://mirror.iscas.ac.cn/openeuler
我有一个hibernate.cfg.xml,其中配置了JDBCUrl:jdbc:mysql://${server.hostname}:3306/dsm?zeroDateTimeBehavior=convertToNull&jdbcCompliantTruncation=true&autoReconnect=true这些&是必需的(而不仅仅是&)以避免异常:对实体“jdbcCompliantTruncation”的引用必须以“;”结尾分隔符。为了能够通过Maven选择不同的目标数据库,我想将其更改为:${jdbc.url}其中${jdbc.url}是Maven中定义的属性
这是一个网页的来源Da brow#aG�rnicza我需要浏览此页面并复制显示的文本之后,我将此文本粘贴到asp.netmvc应用程序的输入文本框中,以便在数据库中创建一条新记录。布局页面的元字符集是“utf-8”如果我在调试中转到VisualStudio2013,当执行Controller的创建操作时,我可以看到以下字符串此地址已存储到nvarchar(255)类型的列中,从sql管理工具中我看到与之前相同的文本:如果我将数据库列中的地址复制并粘贴到Notepad++,我可以看到之后我必须调用svc服务才能发送地址数据,但我从另一端收到了这个异常ERRORT
有人可以告诉我在我的ApplicationContext中我必须使用beans:bean而不是bean的什么以及如何修复它。 最佳答案 说明。基本上,您在这里处理的是XML命名空间。Spring配置允许您使用来自不同命名空间的配置元素作为一种扩展基本beans命名空间配置的方式,具有方便的特定于域的配置,如上述案例中的安全配置。如果您的配置文件集中在这些扩展命名空间之一——再次,让我们以安全性为例——如果您将默认命名空间声明为扩展命名空间而不是标准beans命名空间。就是这样xmlns="http://www.springframe
我正在寻找从JDBC结果集中获取XML文档的最佳方法。XML的结构不是很重要,但它应该相当快。为了清楚起见,我想要结果集中的数据和足够的元数据来识别数据(本质上是字段名称)。我目前正在使用MySQL、DB2、SQLServer,但解决方案需要与数据库无关(对于SQLServer中的XML不是一个可行的选择)。 最佳答案 通过使用WebRowSet,一次可以将整个ResultSet转换成XML。WebRowSet生成的XML非常清晰和简单,我不确定速度,因为它还取决于驱动程序实现。这里有一篇关于WebRowSetusingOracle