JDBC1. Jdbc概述问题:实际开发中,不可能用工具或者命令行操作数据库,数据库表中的数据最终要使用Java程序来操作,那么Java中如何操作数据库中的数据呢?答 : 在Java语言中,有一个专门连接数据库的规范(JDBC),专门负责连接数据库进行数据操作的规范JDBC只是SUN编写的一堆接口(规范的体现),SUN公司自己并没有实现问题 : 为什么SUN只定义一个JDBC规范,而不实现呢?答 : 因为市面上的数据库很多,每个数据库内部接口不会向外暴露,而且即便是暴露让SUN去实现,市面上很多数据库全部要SUN来实现不现实实际中哪个数据库需要支持JAVA语言,就需要自己实现Java的JDBC规范,因为实现了JDBC很多接口,那么就会有很多实现类,而很多实现类在java中会使用一个专门的包封装起来,叫做jar包(在JDBC中叫做驱动包),各大数据库产商实现JDBC规范以后都会把他们jar包放在官网上以供开发者下载使用1.1. JDBCJDBC(Java DataBase Connectivity):是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基JDBC规范对应的api包2. 入门案例2.1. 连接数据库案例使用JDBC操作MySQL数据库2.2. 创建普通java项目2.3. 在项目下面新建一个lib目录2.4. 将MySQL驱动包拷贝到项目中并添加依赖2.5. 获取数据库连接对象准备:1.拷贝MySQL的驱动包到项目中去:mysql-connector-java-5.1.x-bin.jar2.build path,告速项目去哪里去找字节码文件.--------------------------------------------------------------------------------操作JDBC的第一步,获取JDBC的连接对象.:Connection.步骤: 1.加载注册驱动. 就是把驱动中的Driver字节码加载到JVM中.Class.forName("com.mysql.jdbc.Driver"); 为什么这句话就可以加载注册驱动? 第一步:把com.mysql.jdbc.Driver.class这份字节码加载到JVM中. 第二步:当一份字节码被加载进JVM,马上就会执行该字节码中的静态代码块. 第三步:该静态代码中,就在完成,先创建驱动对象,再注册. 2.通过DriverManager获取连接对象. public static Connection getConnection(String url,String user,String password)Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/dbName","root","admin");jdbc:mysql://localhost:3306/dbNamejdbc:mysql:// :连接MySQL数据库的协议,不同数据库协议不一样localhost:3306 :数据库软件的主机和端口dbName : 具体要连接数据库 若数据库安装在本机,并且端口是默认的3306,则可以简写: Connection conn = DriverManager.getConnection("jdbc:mysql:///dbName","root","admin");验证已经获取连接:可以在MySQL控制台,使用命令:show processlist; 查看MySQL运行进程.public class GetConnectionDemo {
public static void main(String[] args) throws Exception {
//1.加载注册驱动 : 把当前类对应的字节码加载到JVM中
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
System.out.println(conn);
}
}3. 创建表-DDL操作在其他操作之间先要把数据库表要创建出来/贾琏欲执事创建一张t_student表:
id:
name:
age:
/*
*
* 创建表操作
* SQL : create table t_student (id int primary key auto_increment,name varchar(50),age int)
*/
public static void main(String[] args) throws Exception {
String sql = "create table t_student (id int primary key auto_increment,name varchar(50),age int)";
//贾琏欲执事
//1,加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取数据库连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
//3,创建语句对象(用于执行SQL语句的对象)
Statement st = conn.createStatement();
//4, 执行SQL语句
//int rows = st.executeUpdate(String sql);执行DDL和DML语句,放回的是受影响的行数
//ResultSet res = st.executeQuery(String sql);执行DQL查询语句,返回的结果集对象
st.executeUpdate(sql);
//5,释放资源(先开后关)
st.close();
conn.close();
}4. DML操作-表数据的增删改//DML : 对表数据的增删改操作
public class DMLDemo {
/*
* 向 t_student表中插入一条数据
* sql : insert into t_student(name,age) values ('乔峰',30)
*/
@Test
public void testInsert() throws Exception {
String sql = "insert into t_student(name,age) values ('乔峰',30)";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建语句对象
Statement st = conn.createStatement();
// 4.执行SQL语句
// int rows = st.executeUpdate(String sql);执行DDL和DML语句,放回的是受影响的行数
// ResultSet res = st.executeQuery(String sql);执行DQL查询语句,返回的结果集对象
int rows = st.executeUpdate(sql);
System.out.println(rows);
//5.释放资源(先开后关)
st.close();
conn.close();
}
/*
* 删除操作: 删除t_student表中的某一条数据
* SQL :delete from t_student where id = 2
*/
@Test
public void testDelete() throws Exception {
String sql = "delete from t_student where id = 2";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建语句对象
Statement st = conn.createStatement();
// 4.执行SQL语句
// int rows = st.executeUpdate(String sql);执行DDL和DML语句,放回的是受影响的行数
// ResultSet res = st.executeQuery(String sql);执行DQL查询语句,返回的结果集对象
int rows = st.executeUpdate(sql);
System.out.println(rows);
//5.释放资源(先开后关)
st.close();
conn.close();
}
/*
* 修改操作 : 修改t_student表中的某一条数据
* SQL : update t_student set name = '虚竹',age = 50 where id = 3
*/
@Test
public void testUpdate() throws Exception {
String sql = "update t_student set name = '虚竹',age = 50 where id = 3";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建语句对象
Statement st = conn.createStatement();
// 4.执行SQL语句
// int rows = st.executeUpdate(String sql);执行DDL和DML语句,放回的是受影响的行数
// ResultSet res = st.executeQuery(String sql);执行DQL查询语句,返回的结果集对象
int rows = st.executeUpdate(sql);
System.out.println(rows);
//5.释放资源(先开后关)
st.close();
conn.close();
}
}5. DQL操作-查询操作5.1. 查询操作的分析5.2. 查询具体操作结果集的列的位置1. 使用 rs.next() 偏移光标,循环指定具体的某一行获取数据的具体方法ObjectgetObject(int columnIndex) columnIndex : 通过结果集的位置(1开始)获取对应的数据ObjectgetObject(String columnLabel) columnLabel : 通过结果集的 列名获取对应的数据package cn.sxt.jdbc._01connection;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
//DQL :查询操作
public class D_DQLDemo {
/*
* 多行查询 :查询t_student表中的所有数据
* SQL : select * from t_student
*/
@Test
public void testList() throws Exception {
String sql = "select * from t_student";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建语句对象
Statement st = conn.createStatement();
// 4.执行SQL语句
// int rows = st.executeUpdate(String sql);执行DDL和DML语句,放回的是受影响的行数
// ResultSet res = st.executeQuery(String sql);执行DQL查询语句,返回的结果集对象
ResultSet rs = st.executeQuery(sql);
//创建list集合用于封装Student对象
List<Student> stus = new ArrayList<>();
while(rs.next()) {
//1.通过结果集的位置获取对应的数
/*Object id = rs.getObject(1);
Object name = rs.getObject(2);
Object age = rs.getObject(3);*/
//2.通过结果集的 列名获取对应的数据
/*Object id = rs.getObject("id");
Object name = rs.getObject("name");
Object age = rs.getObject("age");*/
//3.通过数据库数据和Java对应的数据类型获取对应的只
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
//System.out.println(id+","+name+","+age);
//将获取的数据封装成对应的Student对象
Student stu = new Student(id, name, age);
//将一个个Student对象添加到list集合中
stus.add(stu);
}
for (Student student : stus) {
System.out.println(student);
}
//5.释放资源(先开后关)
rs.close();
st.close();
conn.close();
}
/*
* 单行查询: 查询出t_student 指定id的信息
* SQL : select * from t_student where id = 1;
*/
@Test
public void testGetOne() throws Exception {
String sql = "select * from t_student where id = 2";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建语句对象
Statement st = conn.createStatement();
// 4.执行SQL语句
// int rows = st.executeUpdate(String sql);执行DDL和DML语句,放回的是受影响的行数
// ResultSet res = st.executeQuery(String sql);执行DQL查询语句,返回的结果集对象
ResultSet rs = st.executeQuery(sql);
if(rs.next()) {
//1.通过结果集的位置获取对应的数
/*Object id = rs.getObject(1);
Object name = rs.getObject(2);
Object age = rs.getObject(3);*/
//2.通过结果集的 列名获取对应的数据
/*Object id = rs.getObject("id");
Object name = rs.getObject("name");
Object age = rs.getObject("age");*/
//3.通过数据库数据和Java对应的数据类型获取对应的只
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
//System.out.println(id+","+name+","+age);
//将获取的数据封装成对应的Student对象
Student stu = new Student(id, name, age);
System.out.println(stu);
}
//5.释放资源(先开后关)
rs.close();
st.close();
conn.close();
}
}6. 预编译语句对象PreparedStatment问题 : 我们有了Statment对象可以执行SQL,为什么还要使用PreparedStatment?优势1. SQL语句结构清晰,参数的设置和SQL语句分离2. 性能更高3. 防止SQL注入Statement: 表示静态SQL语句对象.PreparedStatement:Statement的子接口,表示预编译SQL语句对象. 通过占位符(?)来拼SQL. 6.1. 创建PreparedStatement创建语句对象 StatmentStatementcreateStatement() 创建一个 Statement 对象来将 SQL 语句发送到数据库。创建预编译语句对象PreparedStatementPreparedStatementprepareStatement(String sql) 创建预编译语句对象,SQL是带有占位符的SQL模板.6.2. 执行SQL语句的方法6.2.1. Statment在执行SQL语句的时候回带上SQL语句ResultSetexecuteQuery(String sql) 执行给定的 SQL 语句,该语句返回单个 ResultSet 对象。 intexecuteUpdate(String sql) 执行给定 SQL 语句,该语句可能为 INSERT、UPDATE 或 DELETE 语句,或者不返回任何内容的 SQL 语句(如 SQL DDL 语句)。6.2.2. PreparedStatement 在执行SQL语句的方法中不需要设置SQL语句ResultSetexecuteQuery() 在此 PreparedStatement 对象中执行 SQL 查询,并返回该查询生成的 ResultSet 对象。 intexecuteUpdate() 在此 PreparedStatement 对象中执行 SQL 语句,该语句必须是一个 SQL 数据操作语言(Data Manipulation Language,DML)语句,比如 INSERT、UPDATE 或 DELETE 语句;或者是无返回内容的 SQL 语句,比如 DDL 语句。6.3. 设置站位参数的值void setXxx(int parameterIndex,Xxx value):用于设置占位符参数, parameterIndex:第几个问号. 注意:从1开始. value:设置的真实值.Xxx:表示数据类型.String/int/long/Double6.4. 代码package cn.sxt.jdbc._01connection;
import static org.junit.Assert.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import org.junit.Test;
//DML : 对表数据的增删改操作,使用预编译语句对象
public class E_DMLByPreparedStatmentDemo {
/*
* 向 t_student表中插入一条数据
* sql : insert into t_student(name,age) values ('乔峰',30)
*/
@Test
public void testInsert() throws Exception {
String sql = "insert into t_student(name,age) values (?,?)";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建预编译语句对象
PreparedStatement ps = conn.prepareStatement(sql);
//3.1设置占位符参数
ps.setString(1, "东方姑娘");
ps.setInt(2, 18);
// 4.执行SQL语句:注意不要带SQL参数
ps.executeUpdate();
//5.释放资源(先开后关)
ps.close();
conn.close();
}
/*
* 删除操作: 删除t_student表中的某一条数据
* SQL :delete from t_student where id = 2
*/
@Test
public void testDelete() throws Exception {
String sql = "delete from t_student where id = ?";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建预编译语句对象
PreparedStatement ps = conn.prepareStatement(sql);
//3.1设置占位符对应的参数值
ps.setInt(1, 1);
// 4.执行SQL语句
int rows = ps.executeUpdate();
System.out.println(rows);
//5.释放资源(先开后关)
ps.close();
conn.close();
}
/*
* 修改操作 : 修改t_student表中的某一条数据
* SQL : update t_student set name = '虚竹',age = 50 where id = 3
*/
@Test
public void testUpdate() throws Exception {
String sql = "update t_student set name = ?,age = ? where id = ?";
// 1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
// 2.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcdemo", "root", "root");
// 3.创建预编译语句对象
PreparedStatement ps = conn.prepareStatement(sql);
//3.1设置占位符参数对应的值
ps.setString(1, "西方失败");
ps.setInt(2, 40);
ps.setInt(3, 4);
// 4.执行SQL语句
int rows = ps.executeUpdate();
System.out.println(rows);
//5.释放资源(先开后关)
ps.close();
conn.close();
}
}
当上家打出一张6万,吃牌时将9、7、5万一并翻倒棋牌资讯,吃进嵌6万,打出9万。由于上家的6万被自己吃进,其余各家即视6万没有放铳的危险,往往当成安全牌打出。不料,正好上了迷魂大当。这也就是不打5万听6万棋牌资讯,拟打9万不听8万的战术要诀所在。 |