前期准备
- mysql下载安装
-
安装成功验证(cmd 命令行输入命令如下图)(登录)
-
远程连接别人的mysql
这里的-h127.0.0.1表示远程连接数据库所在计算机的ip -
启动和关闭mysql服务
JDBC的概念和本质
- 概念:Java DataBase Connectivity 翻译过来就是Java 数据库连接,通俗来说就是Java语言操作数据库。
- 本质:就是官方(sun公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包(接口对应的实现类)。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
JDBC第一个入门案例步骤
1 导入驱动包
2 注册驱动
3 建立和对应数据库的连接
4 定义sql
5 定义执行sql的Statement对象
6 执行sql
7 处理结果
8 释放资源
JDBC第一个案例具体操作
1 建立数据库test,可以使用SQLyog数据库图形管理工具
2 在test数据库下,创建表account,并且在SQLyog中手动添加数据
test数据库下的account表数据
3 下载jdbc驱动(注意,要和MYSQL版本对应)。这里可以参照我的另外一篇博客,专门来介绍数据库和驱动版本的对应关系。MYSQL和驱动的版本兼容关系
4 代码操作部分
5 代码详解
5.1 DriverManager 驱动管理对象
功能一 注册驱动 static void registerDriver(Driver driver)
注册与给定的驱动程序 DriverManager
操作代码: Class.forName ("com.mysql.jdbc.Driver");
这个代码的作用是将com.mysql.jdbc.Driver类加载进内存
在该类中包含了静态代码块static{
java.sql.DriverManager.registerriver(new Driver());
}在加载进内存的同时执行了该代码,完成了驱动的注册
获取数据库连接对象 getConnection(url,user,root)
其中参数url格式为:jdbc:mysql://ip:端口号/数据库名称
细节:当连接的是自己当前电脑的数据库,并且端口号为3306时
可以将url的ip和端口号省略不写,修改成如下
jdbc:mysql:///数据库名称
5.2 Connection 数据库连接对象
功能一 获取执行sql的对象
1* Statement createStatement()
2* PrepareStatement prepareStatement
(String sql)
功能二 管理事务
* 开启事务
setAutoCommit(boolean autoCommit)
调用该方法参数设置为false表示开启事务
* 提交事务 commit()
* 回滚事务 rollback()
* **具体的应用在本文下方事务管理模块中会详细介绍**
5.3 Statement
功能 执行sql
1 boolean execute(String sql) 可以执行任何sql
2 int executeUpdate(String sql)执行
DML语句。
这可能是 INSERT,UPDATE,DELETE语句.
返回值:影响的行数,可以通过这个影响的行数来
判断DMl语句是否执行完成,返回值大于0表示执
行成功,反之失败.
或者不返回任何内容,如SQL DDL语句的SQL语句。
3 ResultSet executeQuery(String sql)
执行DQL语句(select)语句
5.4 ResultSet对象 查询结果集
boolean next() 游标向下移动
对象保持一个光标指向其当前的数据行。
最初,光标位于第一行之前。 next方法将光标
移动到下一行,并且由于在ResultSet对象中
没有更多行时返回false ,因此可以在while
循环中使用循环来遍历结果集。
getxxx(参数)获取数据
* xxx表示数据类型 如getInt getString
* 参数
1 int:表示列的编号,从1开始
2 String 代表列的名称
如getString("name")
ResultSet对象实战代码
上述代码结果输出(这里的数据库和表都是
上面的test数据库和account表)
1---caoying---2000
2---mamingzhi---3000
3---mazhihui---8000
5.5 PrepareStatement类 可以用来解决SQL注入问题
1 SQL注入问题
SQL注入问题:
在拼接sql时,有一些sql的特殊关键字参与字符串拼接,会造成安全性问题。
例如:sql语句 String sql=“select * from user where username=
’”+username+"'and password='"password+"'";
输入用户名随便,输入密码 a' or 'a'='a 就可以完成登录。
这就是由or关键字导致的!
2 PrepareStatement类执行预编译sql
预编译sql 使用占位符?作为参数值的占位符
例如: String sql = "update account set balance=balance-?
where id=?";
占位符的赋值:使用 PrepareStatement对象的方法setxxx(参数1,参数2)
xxx表示参数的类型。
参数1:?占位符的位置编号,从1开始
参数2:?占位符的值
实例: PreparedStatement ps = connection.prepareStatement (sql);
ps.setInt (1,1000);
ps.setInt (2,1);
管理事务
-
事务:一个包含了多个步骤的业务操作,如果这个业务操作被事务管理,则这个步骤要么同时成功,要么同时失败。
-
操作:
1 开启事务
2 提交事务
3 回滚事务 -
使用Connection对象来管理事务
1 开启事务 setAutoCommit(boolean autoCommit)
2 提交事务 commit()
3 回滚事务 rollback() -
管理事务代码效果演示
业务介绍:
给name为caoying对应的balance-1000
给name为mazhihui对应的balance+2000
下面是test数据库下acoount表的初始数据
(1)首先进行没有进行事务管理的业务的代码以及效果
结果:由于语句int i=2/0 导致了业务的中断。该业务中id=caoying所对应的balance-1000操作完成。但是id=mazhihui对应的balance+2000却被中断。
package com.wxxy.mmz.jdbc;
import jdk.nashorn.internal.ir.CallNode;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
public class TransactionManage {
public static void main(String[] args) throws Exception {
//注册驱动
Class.forName ("com.mysql.jdbc.Driver");
//建立连接
Connection connection = DriverManager.getConnection ("jdbc:mysql:///test", "root", "root");
//事务开启
connection.setAutoCommit (false);
//定义sql
String sql = "update account set balance=balance-? where id=?";
String sql1 = "update account set balance=balance+? where id=?";
//获取执行sql的对象
PreparedStatement ps = connection.prepareStatement (sql);
PreparedStatement ps1 = connection.prepareStatement (sql1);
//给sql语句的参数设置值
ps.setInt (1,1000);
ps.setInt (2,1);
ps1.setInt (1,2000);
ps1.setInt (2,2);
//执行sql语句
ps.executeUpdate ();
//这里会出现错误java.lang.ArithmeticException: / by zero,下面的语句不会执行,但是上面的语句以及执行完成。
//导致了该业务各个步骤执行不统一
int i=2/0;
ps1.executeUpdate ();
//事务的提交
connection.commit ();
//事务的回滚.当该业务执行过程中发生了异常时(int i=i/0),会回滚到 connection.setAutoCommit (false);业务所有操作都不会执行
connection.rollback ();
//关闭资源
ps1.close ();
ps.close ();
connection.close ();
}
}
结果:由于设置了事务管理,所以当异常发生时,该业务所有操作不会发生执行。所有id对应的balance均没有发生变化。
JDBC工具类
JDBC工具类用来简化JDBC的书写,在JDBC代码书写中每一次都需要进行注册驱动,获取连接和释放资源等操作。所以为了简化,自定义JDBC工具类来封装这些模块。
- 抽取注册驱动
- 抽取一个方法获取连接对象
1 需求 不想传递参数,还得保证工具类的通用性
2 解决:配置文件(最好将配置文件放在src目录下),可以通过类加载器获取文件
JDBCUtils类代码
package com.wxxy.mmz.jdbc;
import jdk.nashorn.internal.ir.CallNode;
import java.io.FileReader;
import java.io.IOException;
import java.io.Reader;
import java.net.URL;
import java.sql.*;
import java.util.Properties;
public class JDBCUtils {
public static String url;
public static String user=null;
public static String password=null;
public static String driver=null;
//因此用静态代码块来读取配置文件,因为静态代码块只在加载进内存时执行一次,所以只需要读取一次就可以拿到这些值
//注意:静态代码块中对于异常的处理只能进行捕获,不能进行抛出
static {
try {
Properties properties=new Properties ();
//获取类加载器对象
ClassLoader classLoader = JDBCUtils.class.getClassLoader ();
//获取src路径下的文件的方式-->ClassLoader
URL resource = classLoader.getResource ("JDBCUtils.properties");
String path = resource.getPath ();
//加载配置文件
properties.load (new FileReader(path));
url = properties.getProperty ("url");
user = properties.getProperty ("user");
password = properties.getProperty ("password");
driver=properties.getProperty ("driver");
try {
Class.forName (driver);
} catch (ClassNotFoundException e) {
e.printStackTrace ();
}
} catch (IOException e) {
e.printStackTrace ();
}
}
//建立连接
public static Connection getConnection1() throws SQLException {
return DriverManager.getConnection (url, user, password);
}
//释放资源,针对DDL和DML操作
public static void closeALL(Statement statement,Connection connection) throws SQLException {
if(statement!=null){
statement.close ();}
if(connection!=null){
connection.close ();}
}
//释放资源,针对查询操作,返回结果集
public static void closeALL(ResultSet resultSet, Statement statement, Connection connection) throws SQLException {
if(resultSet!=null){
resultSet.close ();}
if(statement!=null){
statement.close ();}
if(connection!=null){
connection.close ();}
}
}
JDBCUtils类应用
package com.wxxy.mmz.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCTest2 {
public static void main(String[] args) throws Exception {
//导入jar包
//获取驱动 建立连接
Connection connection = JDBCUtils.getConnection1 ();
//定义sql
String sql = "update account set balance=10000 where id=1";
String sql1 = "select * from account";
//5 获取执行sql的对象
Statement statement = connection.createStatement ();
//执行sql语句
int i = statement.executeUpdate (sql);
System.out.println (i);
ResultSet resultSet = statement.executeQuery (sql1);
//光标向下移动一行,对象创建开始光标指向的是字段名行,必须向下移动一行才能获取数据
while(resultSet.next()!=false){
//获取数据
int anInt = resultSet.getInt (1);
String string = resultSet.getString ("name");
int anInt1 = resultSet.getInt (3);
System.out.println (anInt+"---"+string+"---"+anInt1);
}
//释放资源
JDBCUtils.closeALL (resultSet,statement,connection);
}
}