JDBC
1.概念
全称Java Database Connectivity-java数据库连接
它是一个普通的java类,由数据库厂商提供,这些类能够实现sun公司提供的一套"应用程序接口规范"
java.sql.Driver:驱动接口
java.aql.Connection:连接数据库接口
2.导包
3.jdbc原生7大操作步骤 入门Statement
1)注册驱动
2)获取数据库的连接对象
3)准备好的sql语句
4)获取数据库的执行对象---执行sql语句
5)数据库的执行对象 去操作数据库
6)返回结果
7)释放资源
public class JdbcDemo {
public static void main(String[] args) throws Exception {
1)导包并且注册驱动
Class.forName("com.mysql.jdbc.Driver") ; //mysql5.1以上5.7以下 的j包"com.mysql.jdbc.Driver"
//mysql8.0的jar包 "com.mysql.cj.jdbc.Driver"
2)获取数据库的连接对象
//java.sql.DriverManager:里面有静态方法获取数据库连接对象
// public static Connection getConnection(String url, //统一资源定位符
// String user, // 当前mysql的用户名 root 用户
// String password)throws SQLException //当前mysql的登录密码
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/myee_2203_02", //库名
//使用的mysql驱动包5.7以上包括5.7以及8.0的包
//"jdbc:mysql://localhost:3306/myee_2203_02?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true"
"root",
"123456"
);//alt+enter键 :补全代码
3)准备好的sql语句
String sql = "insert into account(name,balance) values('高圆圆',1000)" ;
4)获取数据库的执行对象---执行sql语句
//通过连接对象获取 Connection--- Statement createStatement():创建执行对象,准备将sql发送数据库
Statement stmt = conn.createStatement();
5)数据库的执行对象 去操作数据库
//Statement--->int executeUpdate(String sql)
int count = stmt.executeUpdate(sql);
6)返回结果
System.out.println("影响了"+count+"行") ;
7)释放资源
stmt.close();
conn.close();
}
}
4.JDBC七大操作步骤的关于API的介绍
java.sql.Drvier 驱动接口
java.sql.DriverManager:驱动管理类(管理jdbc的驱动服务)
java.sql.Connection:与特定数据库的一种会话连接
java.sql.Statement:执行静态sql语句 (执行对象,操作数据库)
java.sql.ResultSet:获取数据表的结果集 (接口)
5.ResultSet
概念:表示数据库结果的数据表,通常通过执行查询数据库语句生成
next方法:
在没有调用之前,处在有效数据第一行的前一行
boolean next()结果为true,将光标向前移动一行
ResultSet接口提供通用的操作:
xxx getXXX(列的索引值:(从1开始))
如:第一列是id,int类型
当前结果集对象.getInt(1);
xxx getXXX(String 列的名称);xxx为你当前这列的数据类型
如:第一列id,int类型,通过列的名称
int id = 当前结果集对象.getInt("id");
6.封装JDBC基本操作的工具类的步骤(简要说明代码步骤)
//在src目录下:类路径 xxx.properties
//driverClass=com.mysql.jdbc.Driver
//url=jdbc:mysql://localhost:3306/库名
//username=root
//password=登录的密码
class JdbcUtils{
private static String drierClass = null ;
private static String url = null ;
private static String username = null ;
private static String password = null ;
private JdbcUtils(){}
//提供静态代码块:随着类的加载而加载
static{
//创建属性列表:属性集合类 Properties
Properties prop = new Properties() ;
//读取配置文件 获取配置文件所在的输入流对象
InputStream inputStream = JdbcUtils.class.getClassLoader().getResurcesAsStream("xxx.properties") ;
//将流对象中的加载属性列表中prop
prop.load(inputStream) ;
//通过key获取它里面的value
drierClass = prop.getProperty("driverClass") ;
url = prop.getProperty("url") ;
username = prop.getProperty("username") ;
password = prop.getProperty("password") ;
//注册驱动
Class.forName(drierClass) ;
}
//获取连接对象
public static Connection getConnection(){
Connnection conn = DriverManager.getConnection(url,username,password) ;
return conn ;
}
//释放资源--关闭相关系统资源 (发送sql到数据库Statement执行对象,Connection ,ResultSet)
public static void close(Statement stmt,Connnection conn){
close(null,stmt,conn) ;
}
public static void close(ResultSet rs,Statement stmt,Connnection conn){
if(rs!=null){
try{
rs.close() ;
}catch(SQLException e){
e.printStackTrice() ;
}
}
..
...
}
}
7.单元测试
junit单元测试jar包
@Test:标记方法为单元测试方法,里面包含启动器,可以启动运行
@Before:标记它执行的这个方法是在单元测试方法前先执行,一般:初始化的操作
@After:标记它执行的这个方法是在单元测试方法之后执行,一般:释放系统资源放在这个标记的方法中
语法:
1)导包junit核心包以及hmrecrest-core 依赖包
2)测试某个功能
编写测试用例----编写一个单元测试方法
这个方法没有返回值类型,没有参数
3)需要标记这个方法为单元测试方法,需要在方法上面加入@Test注解
4)在junit包下一个断言Assert里面很多的方法来断言某个功能的结果
是否和预期结果一致,如果一致,说明断言成功;否则失败! (如果测试自己的功能,不用断言,可以直接接口多态测试数据是否存在!)
8.预编译对象PreparedStatement
使用预编译对象PreparedStatement对象作为"数据库的执行对象"
public interface PreparedStatement extends Statement
原生的写法:
0)导包
1)注册驱动
2)获取数据库的连接对象
3)准备sql:参数化的sql语句
4)获取执行对象 并且同时执行更新或者查询
5)返回结果
6)释放资源
* 直接封装JdbcUtils工具类
* 后期都是用参数化的sql语句
public class PreparedStatementDemo {
public static void main(String[] args) throws SQLException {
//添加员工数据
Connection connnection = JdbcUtils.getConnnection();
//sql---参数化的sql语句
//sql语句中的值不是写死的,是在执行sql执行之前,可以多次赋值
String sql = "insert into emploee(name,age,gender,address,salary) values(?,?,?,?,?)" ;
//通过连接对象获取预编译对象PreparedStatement
//Connection---->PreparedStatement prepareStatement(String sql) throws SQLException
//将参数化的sql发送给数据库,并且存储到PreparedStatement对象中
PreparedStatement ps = connnection.prepareStatement(sql);
例1:
//PreparedStatement预编译对象中,需要给 ? (占位符号)进行赋值
//通用方法:void setXxx(int parameterIndex, Xxx x) :给占位符号赋值,
//参数1:第几个占位符号(从1开始)
//参数2:实际参数
ps.setString(1,"亓桑") ; DML语句
ps.setInt(2,20);
ps.setString(3,"男");
ps.setString(4,"西安市") ;
ps.setDouble(5,10000.00) ;
//PreparedStatement预编译对象 :执行sql
//通用方法:int executeUpdate() :DML语句
//ResultSet executeQuery() :DQL语句
int count = ps.executeUpdate();
System.out.println("影响了"+count+"行");
以上;
另:
//给参数赋值
ps.setInt(1,7) ;
//执行查询
//ResultSet executeQuery() :DQL语句
ResultSet rs = ps.executeQuery();
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
String gender = rs.getString("gender");
String address = rs.getString("address");
double salary = rs.getDouble("salary");
System.out.println(id+"\t"+name+"\t"+age+"\t"+gender+"\t"+address+"\t"+salary);
}
以上;
//释放资源
JdbcUtils.close(ps,connnection);
}
}
9.Statement对象和PreparedStatement对象的区别
Statement对象和PreparedStatement对象的区别:
1)执行sql效率区别
Statement每一次需要将静态化的sql进行发送给数据库, 写好一条sql,发送一次,相对于PreparedStatement预编译对象来说,执行sql效率非常低!
PreparedStatement将编译参数化的sql(占位符号?)发送给数据库,数据库会校验它的列索引值以及对应的类型,将sql保存到预编译对象中
预编译对象可以赋值不同的参数,执行对应sql,执行效率相对Statement高很多!
2)是否会造成"SQL注入"
Statement对象发送的sql属于静态sql语句,存在"硬编码",而且还有字符串拼接,就会造成sql注入,非常不安全的一种行为!
PreparedStatement对象发送的sql都是参数化的sql,不存在字符串拼接,不会造成sql注入,相对Statement是一种安全行为!
* 注意事项:
* 后期框架(半成品的东西:一堆通用代码+一堆配置文件)底层对象性jdbc的封装使用的就是PreparedStatement
注
1.代码规范
实际开发中,包的名称:公司域名反写
com.qf.entity/pojo/domain:实体类 (学生类...用户类...)
com.qf.dao:Data Access Object :数据访问对象 --- 接口
com.qf.dao.impl接口实现类 :完成JDBC操作
里面有异常的全是抛出
com.qf.service:业务包 里面代码有异常需要 try...catch...
2.语句名称
SQL语言共分为四大类:
数据查询语言DQL(Data Query Language)
数据操纵语言DML(Data Manipulation Language)
数据定义语言DDL(Data Definition Language)
数据控制语言DCL(Data Control Language)