1.基本用法
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://localhost:3306/db1?useSSL=false";
String username = "root";
String password = "123456";
Connection connection = DriverManager.getConnection(url,username,password);
//3.写sql语句
String sql = "update user set name = 'Y' where id = 1;";
//4.获取执行sql的对象
Statement statement = connection.createStatement();
//5.执行SQL,可返回改变的行数,也可以不返回,直接 statement.executeUpdate(sql);
int count = statement.executeUpdate(sql);
System.out.println(count);
//6.释放对象资源
statement.close();
connection.close();
2.DriverManager(驱动管理类)
(1)注册驱动:DriverManager 类中的 静态方法 registerDriver 用于注册驱动,上边的 Class 类的 forName 方法本质也是 registerDriver 方法。
(2)获取数据库链接:DriverManager 类中的 静态方法 getConnection(String url,String user, String password) 尝试建立与给定数据库URL的连接。
3.Connection(数据库链接对象)类
(1)获取执行SQL对象:
普通执行SQL对象:createStatement() 创建一个 Statement对象,用于将SQL语句发送到数据库。
预编译执行SQL对象,防止SQL注入:prepareStatement(String sql) 创建一个 PreparedStatement 对象,用于将参数化的SQL语句发送到数据库。
执行存储过程对象:prepareCall(String sql) 创建一个调用数据库存储过程的 CallableStatement 对象。
(2)事务管理:
回忆MySQL 中使用 SQL语句 来开启/关闭事务:
开启(BEGIN; / START TRANSACTION;),
提交(COMMIT;),回滚(ROLLBACK;)
自动/手动提交(set autocommit = 0 关闭自动提交, 1 开启自动提交)
注:MySQL默认为自动提交。
Connection中事务管理的三个方法:
开启:setAutoCommit(boolean autoCommit) 参数 true 则自动提交(就是关闭事务),参数 false 则手动提交(就是开启事务)。
提交:commit()方法 使自上次提交/回滚以来所做的所有更改都将永久性,并释放此 Connection对象当前持有的任何数据库锁。
回滚:rollback()方法 撤消在当前事务中所做的所有更改,并释放此 Connection对象当前持有的任何数据库锁。
注:可以使用java中的 try/catch 来配合事务进行使用,具体实现例子如下。
//1.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取连接
String url = "jdbc:mysql://localhost:3306/db1?useSSL=false";
String username = "root";
String password = "12345678";
Connection connection = DriverManager.getConnection(url,username,password);
//3.写sql语句
String sql1 = "update user set name = 'Y' where id = 1;";
String sql2 = "update user set name = 'Y' where id = 2;";
//4.获取执行sql的对象
Statement statement = connection.createStatement();
//5.执行SQL,可返回改变的行数,也可以不返回,直接 statement.executeUpdate(sql);
try {
//开启事务
connection.setAutoCommit(false);
int count1 = statement.executeUpdate(sql1);
System.out.println(count1);
//故意报错
int i = 9/0;
int count2 = statement.executeUpdate(sql2);
System.out.println(count2);
//提交事务
connection.commit();
} catch (SQLException e) {
//回滚事务
connection.rollback();
} finally {
//6.释放对象资源
statement.close();
connection.close();
}
当出错时,可以回滚,然后两条sql语句就绑定了,要么都成功,要么都不成功,牛逼,哈哈哈。
4.Statement类(用于执行静态SQL语句并返回其生成的结果的对象。)
(1)执行SQL语句:
executeUpdate(String sql) 方法,执行给定的SQL语句(DML、DDL),这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。
executeQuery(String sql) 方法,执行给定的SQL语句(DQL),该语句返回单个 ResultSet对象。
注:执行DML可以通过返回值是否为0(受影响行数为0),看是否执行了,但是DDL不行(例如删库,受影响行数还是0)。
5.ResultSet(结果集对象)类
(1)封装DQL查询结果, Statement 类的对象执行 executeQuery(String sql) 方法会把查询结果作为返回值,返回到 ResultSet 类型的对象中。
具体例子实现如下:
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/db1?useSSL=false","root","12345678");
String sql1 = "select * from user";
Statement statement = connection.createStatement();
java.sql.ResultSet resultSet = statement.executeQuery(sql1);
//指针从标题行,移动到下一行,next()函数返回值为布尔值 ,有值为ture 没值为false
while (resultSet.next()){
//获取值getXxx();
int id = resultSet.getInt(1);//这里参数可以是序号,第几列,也可以是列名
String name = resultSet.getString("name");//这里参数为类名
double pid = resultSet.getDouble(3);
System.out.println("id="+id+",name="+name+",pid="+pid);
}
resultSet.close();
statement.close();
connection.close();
6.PreparedStatement(继承了Statement类)类
(1)预编译SQL,防止SQL的注入问题(太可怕了ヽ(*。>Д<)o゜)。详情百度搜索SQL注入。
(2)通过使用占位符 ? 来解决注入问题,本质就是先写SQL字符串,其中的账号密码等数值用 ?占位符先替代,然后再用之后的参数把占位符替掉,在此过程中,参数会被视作一个整体(本质应该是转义符/,但是可以理解为一个整体),避免了和SQL语句产生作用。从而解决SQL注入。
测试代码如下:
@Test
public void PrepareStatement_Test() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/db1?useSSL=false","root","12345678");
String name = "I";
int id = 1;
String sql1 = "update user set name = ? where id = ?;"; //两个占位符
PreparedStatement statement = connection.prepareStatement(sql1);
statement.setString(1,name); //第1个占位符的类型为string 值为 name
statement.setInt(2,id); //第2个占位符的类型为int 值为 name
int connet = statement.executeUpdate();
System.out.println("成功行数="+connet);
}
这种方式,相当于提前把模板放入服务器 ,只需要修改参数就行了,效率比普通的也高
(前提是要开启预编译功能:在URL中:
jdbc:mysql://127.0.0.1:3306/db1?useSSL=false&useServerPrepStmts=true","root","123456" )
7.数据库连接池(管理Connection对象)
数据库连接池的本质:不必每次都申请一个Connection对象,可以复用,提高效率。
数据库连接池实现:由SUN公司官方提供接口,第三方去实现,常用连接池DBCP,C3P0,Druid。
例Druid的使用步骤:
(1)导入jar包,复制到项目下,右键选择最下面的add library,选择添加jar包。
(2)定义配置文件
配置代码:
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/db1?useSSL=false&useServerPrepStmts=true
username=root
password=12345678
#初始化连接数
initialSize=5
#最大连接数
maxActive=10
#最大时间
maxWait=3000
(3)加载配置文件
Properties prpo = new Properties(); prpo.load(new FileInputStream("src/druid_peizhi.properties"));
注意:如果不知道配置路径,可以用 System.out.println(System.getProperty("user.dir")); 来查看已经有的路径,然后在FileInputStream()中写上直到配置文件的路径。两个路径拼接起来应该是绝对路径。
(4)获取数据库连接池对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prpo);
(5)获取连接
Connection connection = dataSource.getConnection(); System.out.println(connection);
此时就获取到了connection,再按照之前内容写就行了。
测试代码:
@Test
public void druidtest1() throws Exception {
// 1.导入jar包
// 2.定义配置文件
// 3.加载配置文件
Properties prpo = new Properties();
prpo.load(new FileInputStream("src/druid_peizhi.properties"));
// 4.连接数据库对象
DataSource dataSource = DruidDataSourceFactory.createDataSource(prpo);
// 5.获取数据库链接
Connection connection = dataSource.getConnection();
System.out.println(connection);
// System.out.println(System.getProperty("user.dir")); //可以用于查看第三步的路径