目录
JDBC简介
-
JDBC 概念:
-
JDBC 就是使用Iava 语言操作关系型数据库的一套API
-
全称(java DataBase Connectify)java数据库连接
-
-
JDBC本质:
-
官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口
-
各个数据库厂商区实现这套接口,提供数据库驱动的jar包
-
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
-
-
JDBC 好处:
-
各数据库厂商使用相同接口,java代码不需要针对不同数据库分别开发
-
可随时替换底层数据库,访问数据库的java代码基本不变
-
JDBC快速入门
-
步骤:
创建工程,导入驱动jar包
-
注册驱动
Class.forname("com.mysql.jdbc.Driver");
-
获取连接
Connection conn = DriverManager.getConnection(url,username,passworld);
-
定义SQL语句
String sql = "update ...";
-
获取执行SQL语句
Statement stmt = conn.createStatement();
-
执行SQL
stmt.executeUpdate(sql);
-
处理返回结果
-
释放资源
-
//1、注册驱动
Class.forName( "com.mysql.jdbc.Driver" );
//2、获取连接
String url = "jdbc:mysql://127.0.0.1:3308/itheima";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection( url, username, password );
//3.定义语句
String sql = "update account set money =2000 where id =2";
//4、执行sql的对象
Statement stmt = conn.createStatement();
//5、执行sql
int count = stmt.executeUpdate( sql );//受影响的行数
//6、处理结果
System.out.println(count);
//7、释放资源
stmt.close();
conn.close();
JDBC API 详解
DriverManager
-
DriverManager(驱动管理类)作用:
-
注册驱动
提示:
-
MySQL 5之后的驱动包,可以省略注册驱动的步骤。
-
自动加载jar包中META_INF/services/java.sql.Driver 文件中的驱动类
-
-
获取数据库连接
getConnection(String url, String user, String password)
参数:
-
url:连接路径
-
语法:jdbc:mysql://ip地址(域名):端口号/数据库名称?参数键值对1 &参数键值对2 ...
-
实例:jdbc:mysql://127.0.0.1:3308/db1
-
细节
-
如果连接的是本机mysql服务器,并且mysql服务器默认端口是3306,则url可以简写为:jdbc:mysql:///数据库名称?参数键值对
-
配置useSSL = false 参数,禁用安全连接方式,解决警告提示
-
-
-
user:用户名
-
password:密码
-
-
Connection
-
Connection (数据库连接对象)作用:
-
获取执行SQL的对象
-
普通执行SQL对象
Statement createStatement()
-
预编译SQL的执行SQL对象:防止SQL注入
PreparedStatement preparedStatement(sql)
-
执行存储过程的对象
CallableStatement prepareCall(sql)
-
-
管理事务;
-
MySQL事务管理
-
开启事务:BEGIN;/START TRANSACTION
-
提交事务:COMMIT;
-
回滚事务:ROLLBACK;
MySQL默认自动提交事务
-
-
JDBC事务管理:Connection 接口中定义了3个对应的方法
-
开启事务:setAutoCommit(boolean autoCommit):true为自动提交事务;false为手动提交事务,即为开启事务。
-
提交事务:commit();
-
回滚事务:rollback();
-
-
-
//1、注册驱动
//Class.forName( "com.mysql.jdbc.Driver" );
//2、获取连接
String url = "jdbc:mysql://127.0.0.1:3308/itheima";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection( url, username, password );
//3.定义语句
String sql1 = "update account set money =2000 where id =1";
String sql2 = "update account set money =2000 where id =2";
//4、执行sql的对象
Statement stmt = conn.createStatement();
try {
//开启事务
conn.setAutoCommit( false );
//5、执行sql
int count1 = stmt.executeUpdate( sql1 );//受影响的行数
//6、处理结果
System.out.println(count1);
int count2 = stmt.executeUpdate( sql2 );//受影响的行数
System.out.println(count2);
//提交事务
conn.commit();
} catch (Exception e) {
conn.rollback();
e.printStackTrace();
}
//7、释放资源
stmt.close();
conn.close();
Statement
-
Statement
-
执行SQL语句
-
-
执行SQL语句
int executeUpdate(sql):执行DMl、DDL语句
返回值:(1)DML语句影响的行数
(2)DDL语句执行后,执行成功也可能返回0
-
ResultSet executeQuery(sql):执行DQL语句
返回值:ResultSet 结果集对象
@Test
public void testDML() throws Exception {
//1、注册驱动
Class.forName( "com.mysql.jdbc.Driver" );
//2、获取连接
String url = "jdbc:mysql://127.0.0.1:3308/itheima?useSSL = false";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection( url, username, password );
//3.定义语句
String sql = "create database db2";
//4、执行sql的对象
Statement stmt = conn.createStatement();
//5、执行sql
int count = stmt.executeUpdate( sql );//受影响的行数
//6、处理结果
System.out.println(count);
// if(count>0){
// System.out.println("执行成功~");
// }else{
// System.out.println("执行失败~");
// }
//7、释放资源
stmt.close();
conn.close();
}
/**
* 执行DDL语句
* @throws Exception
*/
@Test
public void testDDL() throws Exception {
//1、注册驱动
Class.forName( "com.mysql.jdbc.Driver" );
//2、获取连接
String url = "jdbc:mysql://127.0.0.1:3308/itheima?useSSL = false";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection( url, username, password );
//3.定义语句
String sql = "update account set money =2000 where id =2";
//4、执行sql的对象
Statement stmt = conn.createStatement();
//5、执行sql
int count = stmt.executeUpdate( sql );//受影响的行数
//6、处理结果
//System.out.println(count);
if(count>0){
System.out.println("执行成功~");
}else{
System.out.println("执行失败~");
}
//7、释放资源
stmt.close();
conn.close();
}
ResultSet
-
ResultSet(结果集对象)作用:
-
封装DDL查询语句的结果
ResultSet stml.executeQuery(sql); 执行DQL语句,返回ResultSet对象
-
-
获取查询结果:
boolean next();
(1) 将光标从当前位置向前移动一行
(2)判断当前行是否为有效行
-
返回值:
-
true:有效行,当前行有数据
-
false:无效行,当前行没有数据
xxx getXxx(参数) :获取数据
-
xxx:数据类型;如:int getInt(参数), String getString(参数)
-
参数:
-
int :列的编号,从1开始
-
String:列的名称
-
-
使用步骤:
-
游标向下移动一行,并判断该行是否有数据:next()
-
获取数据:getXxx(参数)
//循坏判断游标是否是最后一行末尾
while(rs.next()){
//获取数据
rs.getXxx(参数);
}
-
public void testResultSet() throws Exception {
//1、注册驱动
Class.forName( "com.mysql.jdbc.Driver" );
//2、获取连接
String url = "jdbc:mysql://127.0.0.1:3308/itheima?useSSL = false";
String username = "root";
String password = "root";
Connection conn = DriverManager.getConnection( url, username, password );
//3.定义语句
String sql = "select * from account";
//4、获取Statement对象
Statement stml = conn.createStatement();
//5、执行sql语句
ResultSet rs = stml.executeQuery( sql );
/**
* 查询account账户表数据,封装为Account对象中,并且存储到ArrayList集合中
* 1、定义实体类Account
* 2、查询数据,封装到Account对象中
* 3、将Account对象存入Arraylist集合中
*/
//6.2 获取数组存储数据
ArrayList<Account> arrayList=new ArrayList<>();
//6、处理结果,遍历rs中的所有数据
//6.1 光标向下移动一行,并且判断当前行是否有数据
// while (rs.next()){
// int id = rs.getInt( 1 );
// String name = rs.getString( 2 );
// double money = rs.getInt( 3 );
//
// System.out.println(id);
// System.out.println(name);
// System.out.println(money);
//
// System.out.println("-------------");
//
// }
while (rs.next()){
//创建对象
Account account = new Account();
//6.2 获取数据 getXxx()
int id = rs.getInt( "id" );
String name = rs.getString( "name" );
double money = rs.getInt( "money");
//赋值
account.setId( id );
account.setName( name );
account.setMoney( money );
//存入数据
arrayList.add( account );
}
//输出集合数据
System.out.println(arrayList);
//7、释资源
rs.close();
stml.close();
conn.close();
PreparedStatement
-
PreparedStatement作用
-
预编译SQL语句并执行,预防SQL注入问题
-
获取PreparedStatement 对象
//SQL语句中的参数值,使用?占位符替代
String sql = "select * from user where username = ? and password = ?"
//通过Connection 对象获取,并传入对应的SQL语句
PreparedStatement pstmt = conn.prepareStatement(sql);
-
设置参数值
PreparedStatement 对象:setXxx(参数1,参数2):给?赋值
-
Xxx:数据类型:如setInt(参数1,参数2)、
-
参数:
-
参数1:?的位置编号,从1开始
-
参数2:?的值
-
-
执行SQL
executeUqdate();/executeQuery(); 不需要再传递sql
-
-
-
SQL注入:
-
SQL注入是通过操作输入来修改事先定义好的SQL语句,用以达成执行代码对服务器进行
攻击
的方法
-
String sql = "select * from user where username = ? and passwd = ?"; PreparedStatement pstml = conn.prepareStatement(sql); //设置?的值 pstml.setString (1,name); pstml.setString(2,passwd);
-
PreparedStatement 原理
-
PrepareStatement好处:
-
预编译SQL,性能更好
-
防止SQL注入:将敏感字符进行转义
-
-
PrepareStatement原理:
-
在获取PreparedStatement对象时,将SQL语句发送给mysql服务器进行检查,编译(这些步骤很耗时)
-
执行时就不再进行这些步骤,速度更快
-
如果sql模板一样,则只需要进行一次检查,编译
-
-
数据库连接池
-
数据库连接池简介
-
数据库连接池
是个容器,负责分配,管理数据库连接(Connection) -
它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个
-
释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏
-
好处:
-
资源重用
-
提升系统响应速度
-
避免数据库连接遗漏
-
-
-
数据库连接池实现
-
标准接口:DataSource
-
官方(SUN)提供的数据库连接池标准接口,由第三方组织实现此接口。
-
功能:
Connection getConnection()
-
-
常见的数据库连接池
-
DBCP
-
C3PO
-
Druid
-
-
Druid(德鲁伊)
-
Druid连接池是阿里巴巴开源的数据库连接池项目
-
功能强大,性能优秀,是Java语言最好的数据库连接池之一
-
-
Druid 使用步骤
1、导入jar包 Druid-1.1.12.jar
2、定义配置条件
3、加载配置条件
4、获取数据库连接池对象
5、获取连接
//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" ));
案例:数据增删改查
public class BrandTest {
/**
* 查询所有
* 1、SQL:select * from tb_brand
* 2、参数:不需要
* 3、结果:List<Brand>
*/
@Test
public void testSelectAll() throws Exception {
// 1、获取Connection
// 3、加载配置文件
Properties prop = new Properties();
prop.load( new FileInputStream( "src/druid.properties" ));
// 4、获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5、获取数据库连接Connection
Connection conn = dataSource.getConnection();
//2、定义SQL
String sql = "select * from tb_brand";
//3、获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement( sql );
//4、设置参数
//5、执行sql
ResultSet rs = pstmt.executeQuery();
//封装Brand对象
Brand brand = null;
//创建存储集合
ArrayList<Brand> brands = new ArrayList<>();
//6、处理结果,List<brand>
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=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();
}
System.out.println(brands);
//7、释放资源
rs.close();
pstmt.close();
conn.close();
//System.out.println(System.getProperty( "user.dir" ));
}
/**
* 增加:
* 1、SQL:insert into tb_brand (brand_name, company_name, ordered, description, status)valuses();
* 2、参数:需要
* 3、结果:boolean
*
*/
@Test
public void testAdd() throws Exception {
//接收页面提交的参数
String brandName = "香飘飘";
String companyName = "香飘飘";
int ordered = 1;
String description = "绕地球一圈";
int status = 1;
// 1、获取Connection
// 3、加载配置文件
Properties prop = new Properties();
prop.load( new FileInputStream( "src/druid.properties" ));
// 4、获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5、获取数据库连接Connection
Connection conn = dataSource.getConnection();
//2、定义SQL
String sql = "insert into tb_brand (brand_name, company_name, ordered, description, status) values(?,?,?,?,?);";
//3、获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement( sql );
//4、设置参数
pstmt.setString( 1,brandName );
pstmt.setString( 2,companyName );
pstmt.setInt( 3,ordered );
pstmt.setString( 4,description );
pstmt.setInt( 5,status );
//5、执行sql
int count = pstmt.executeUpdate();//影响行数
//6、处理结果,boolean
System.out.println(count > 0);
//7、释放资源
pstmt.close();
conn.close();
}
/**
* 修改
* 1、sql:
* uqdate tb_brand
* set brand_name = ?,
* company_name = ?,
* ordered = ?,
* description = ?,
* status = ?
* where id = ?
* 2、参数:需要
* 3、结果:boolean
* @throws Exception
*/
@Test
public void testUpdate() throws Exception {
//接收页面提交的参数
String brandName = "香飘飘";
String companyName = "香飘飘";
int ordered = 52;
String description = "绕地球san圈";
int status = 1;
int id = 4;
// 1、获取Connection
// 3、加载配置文件
Properties prop = new Properties();
prop.load( new FileInputStream( "src/druid.properties" ));
// 4、获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5、获取数据库连接Connection
Connection conn = dataSource.getConnection();
//2、定义SQL
String sql = "update tb_brand \n" +
"set brand_name = ?,\n" +
" company_name = ?,\n" +
" ordered = ?,\n" +
" description = ?,\n" +
" status = ?\n" +
"where id =?;";
//3、获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement( sql );
//4、设置参数
pstmt.setString( 1,brandName );
pstmt.setString( 2,companyName );
pstmt.setInt( 3,ordered );
pstmt.setString( 4,description );
pstmt.setInt( 5,status );
pstmt.setInt( 6,id );
//5、执行sql
int count = pstmt.executeUpdate();//影响行数
//6、处理结果,boolean
System.out.println(count > 0);
//7、释放资源
pstmt.close();
conn.close();
}
/**
* 删除
* 1、sql:delete from tb_brand where id = ?;
* 2、参数:需要
* 3、结果:boolean
* @throws Exception
*/
@Test
public void testDelete() throws Exception {
//接收页面提交的参数
int id = 4;
// 1、获取Connection
// 3、加载配置文件
Properties prop = new Properties();
prop.load( new FileInputStream( "src/druid.properties" ));
// 4、获取连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
//5、获取数据库连接Connection
Connection conn = dataSource.getConnection();
//2、定义SQL
String sql = "delete from tb_brand where id = ?";
//3、获取pstmt对象
PreparedStatement pstmt = conn.prepareStatement( sql );
//4、设置参数
pstmt.setInt( 1,id );
//5、执行sql
int count = pstmt.executeUpdate();//影响行数
//6、处理结果,boolean
System.out.println(count > 0);
//7、释放资源
pstmt.close();
conn.close();
}
}