简称
jdbc就是java连接数据库软件的技术,是java提供的jdbc规范。Java技术是典型的面向接口编程。各个数据库厂商提供提供jar包规范。需要下载数据库软件提供的jar包并导入idea
步骤
- 注册驱动
- 创建连接
- 创建发生sql语句的对象
- 发送sql语句获取结果
- 结果解析
- 释放资源
import com.mysql.cj.jdbc.Driver;
import java.sql.*;
public class StatementQueryPart {
public static void main(String[] args) throws SQLException {
//1.注册驱动
DriverManager.registerDriver(new Driver());
//2.获取链接
/**
* java程序链接数据库需要:数据库ip地址;jdbc:数据库厂商://ip地址:port/数据库名 数据库端口号:3306 账号密码 数据库名称
*
*/
Connection connection =
DriverManager.getConnection
("jdbc:mysql://127.0.0.1/powernode", "root", "12345");//接口等于实现类
//3.创建statement
Statement statement = connection.createStatement();
//4.发送sql语句 获取返回结果
String sql = "select * from EMP";
ResultSet resultSet = statement.executeQuery(sql);
//5.进行结果集解析
while(resultSet.next()){
String ename = resultSet.getString("ENAME");
int sal = resultSet.getInt("sal");
System.out.println(ename+"-"+sal);
}
//6.关闭资源
resultSet.close();
statement.close();
connection.close();
}
}
登录案例
import java.sql.*;
import java.util.Scanner;
public class StatementLoginPart {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账号:");
String account = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
//DriverManager.registerDriver(new Driver());//Driver类有一个静态代码块自带register方法,所以有两次驱动注册问题
//所以可以只去出发静态代码块 静态代码块是在类加载的时候加载,加载[class文件=>jvm虚拟机的class文件对象]
//连接:[验证(检查文件类型)->准备(静态变量默认值)->解析(触发静态代码块)]
//初始化(静态属性赋真实值)
//触发类加载:new 调用静态方法 接口 反射 子类触发父类 main方法
//new Driver();//完成一次驱动注册
//反射触发
Class.forName("com.mysql.cj.jdbc.Driver");//触发类加载 可以提取字符串为配置文件
//2.获取数据库连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1/powernode","root","1234");//这是一个重载方法 核心属性:数据库软件主机ip地址,数据库软件所在主机端口号,
Statement statement = connection.createStatement();
String sql = "select * from log_in where account = '"+account+"'and password = '" + password+"';";
ResultSet resultSet = statement.executeQuery(sql);
/**
* java是一种面向对象的思维,将查询结果集封装成为了resultset对象,我们应该理解为内部一定也是有行有列
*
*/
/* while(resultSet.next()){
String account1 = resultSet.getString("account");
String password1 = resultSet.getString("password");
}*/
if(resultSet.next()){//只要移动过resultset的光标就代表有数据匹配
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
resultSet.close();
statement.close();
connection.close();
}
}
以上代码会导致sql注入 使用preparestatement可以防止注入
Scanner scanner = new Scanner(System.in);
System.out.println("请输入账号:");
String account = scanner.nextLine();
System.out.println("请输入密码:");
String password = scanner.nextLine();
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1/powernode","root","1234");//这是一个重载方法 核心属性:数据库软件主机ip地址,数据库软件所在主机端口号,
//编写sql语句结构 使用?
String sql = "select *from log_in where account = ? and password = ?";
//创建预编译preparestatement并且传入动态值
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1,account);
preparedStatement.setObject(2,account);
//发送sql语句
ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
resultSet.close();
preparedStatement.close();
connection.close();
获取连接
@Test
public void testSelect() throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1/powernode","root","1234");
String sql = "select id,account,password from log_in";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
ResultSet resultSet = preparedStatement.executeQuery();
//解析结果集
/**
* 利用next方法移动游标 获取行数据
*/
List<Map> list = new ArrayList<>();
while(resultSet.next()){
HashMap map = new HashMap();
//一行数据就是一个map
/* map.put("account",resultSet.getString("account"));
map.put("password",resultSet.getString("password"));*/
//获取列的信息
ResultSetMetaData metaData = resultSet.getMetaData();
int columnCount = metaData.getColumnCount();
for (int i = 1; i <= columnCount; i++) {
Object value = resultSet.getObject(i);
//获取列名称
map.put(metaData.getColumnLabel(i),value);//获取别名或者列名
}
list.add(map);
}
System.out.println(list);
resultSet.close();
connection.close();
preparedStatement.close();
}
主键回显
...
PreparedStatement statement = connection.prepareStatement(sql,Statement.RETURN_GENERATE_KEYS);
//可以获取回显的主键
ResultSet generateKeys = statement.getGneratedKeys();
批量插入优化
statement.addBathch();//不执行 追加到values后面
statement.execteBatch();//批量执行 批量操作
jdbc开启事务
public class BankService {
public void transfer(String addAccount,String subAccount,int money) throws SQLException, ClassNotFoundException {
//一个事务最基本要求就是必须是同一事务
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://127.0.0.1/powernode","root","1234");
try{
//开启事务
connection.setAutoCommit(false);//关闭事务提交 事务的开启是在业务上开启的
//执行数据库动作
BankDao bankDao = new BankDao();
bankDao.add(addAccount,money,connection);
System.out.println("-----------------");
bankDao.sub(subAccount,money,connection);
//事务提交
connection.commit();
}catch (Exception e){
//如果出现异常 事务回滚
connection.rollback();
throw e;
}finally {
connection.close();
}
}
@Test
public void test() throws SQLException, ClassNotFoundException {
transfer("张三","李四",500);
}
}
连接池
- 链接可以复用 没必要每次建立连接
德鲁伊连接池:
注册驱动
创建链接
获取链接
回收链接