目录
JDBC原理
JDBC标准
JDBC是什么
使用JDBC优点
JDBC接 口及数据库厂商实现
JDBC工作原理
Driver ( 驱动程序)接口及驱动类加载
Connection( 连接,关联)接口
Statement( 声明)接口
ResultSet接口
数据库厂商实现
Oracle实现
MySQL实现
JDBC基础
连接管理
通过连接工具类获取连接
读取配置文件
通过属性文件维护连接属性
从类路径中加载属性文件
连接的关闭
数据库连接池DBCP
连接池技术
为什么要使用连接池
Druid数据库连接池
通过DataSource获取连接
Apache DBCP数据库连接池
通过DataSource获取连接
连接池参数
异常处理
SQLException简介
处理SQL Exception
JDBC核心API:
Statement
Statement执行查询
Statement执行新增
Statement执行修改
Statement执行删除
PreparedStatement
PreparedStatement原理
SQL注入问题
预编译的SQL执行对象PreparedStatement
提升性能
SQL Injection简介
防止SQL Injection (注入)
ResultSet (结果集)
结果集遍历
ResultSetMeta Data(结果集元数据)
JDBC高级编程
事务处理
事务简介
JDBC事务API
JDBC标准事务编程模式
批量更新
批量更新的优势
批量更新API
防止OutOfMemory
返回自动主键
获取自增主键值:
关联数据插入
通过自增类型产生主键
JDBC返回自动主键API
DAO
什么是DAO
DAO封装对数据的访问
实体对象
编写DAO
查询方法
更新方法
异常处理机制
Java Database Connectivity : Java访问数据库的解决方案
希望用相同的方式访问不同的数据库,以实现与具体数据库无关的Java操作界面,JDBC定义一套标准接口,即访问数据库的通用API ,不同的数据库厂商根据各自数据库的特点去实现这些接口.
JavaDataBaseConnectivity:Java数据库连接,是Sun公司提供的一套和数据库进行连接的API(Application Program Interface应用程序编程接口), 作用:通过Java语言和数据库软件进行连接
在工作中Java程序员有可能连接多种不同的数据库,为了避免Java程序员每一种数据库都学习一套新的方法,Sun公司定了一套方法的声明(JDBC),把方法名固定,不管连接的是什么数据库方法名是一样的,各个数据库厂商根据方法名写方法的实现类(驱动),这样Java程序员只需要掌握JDBC中方法的调用,即可访问任何数据库,而且安装JDBC规范所写的代码就算是换数据库代码一行都不用改.
JDBC工作过程:
package cn.tedu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
/**
*
* @author Administrator
*
*/
public class Demo01 {
public static void main(String[] args) throws Exception {
//1.注册驱动:高速驱动编译器使用的是什么数据库
Class.forName("com.mysql.cj.jdbc.Driver");
//2.获取在数据库连接 导包:java.sql
//jdbc:mysql://localhost:3306/mysql?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true", "root", "root");
System.out.println(conn);
//3.创建执行SQL 语句的对象
Statement s = conn.createStatement();
//4.执行SQL
String sql = "create table jdbct1(id int,name varchar(10))";
s.execute(sql);
//5.关闭资源
conn.close();
System.out.println("执行完成!");
}
}
Class. forName (" com. mysq1. jdbc . Driver");
Connection conn =
DriverManager . getConnection("jdbc :mysq1 ://1oc alhost :3306/ demo",
root" ,
);
// NOTE:Connection只是接口 !真正的实现是由数据库厂商提供的驱动包完成的
/**根据url连接参数找到与之匹配的
Driver对象,调用其方法获取连接*/
执行SQL语句的对象Statement
- execute(sql) 可以执行任意SQL语句,但是推荐执行数据库和表相关的SQL(DDL数据定义语言)(execute 执行 )
- int row = executeUpdate(sql); 此方法执行增insert删delete改update的SQL ,方法的返回值为生效的行数( executeUpdate 执行更新) (int 类型 )
- ResultSet rs = executeQuery(sql); 此方法执行查询的SQL语句,返回值是结果集对象,里面装着查询回来的结果(executeQuery 执行查询)
执行查询SQL语句后返回的结果集,由ResultSet接口接收,常用处理方式:遍历/判断是否有结果(登录)
String sql =
”
select * from emp";
ResultSet rs = stmt . executeQuery(sq1);
while (rs.next()) {
System . out . println(rs . getInt( " empno")+","
+rs. getstring(" ename"));
}
public static void main(String[] args) throws Exception {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true",
"root", "root");
Statement s = conn.createStatement();
String sql = "select ename,sal from emp";
//执行查询 得到结果及 集对象
ResultSet rs = s.executeQuery(sql);
//遍历结果 集对象 中的查询结果
long t = System.currentTimeMillis();
while(rs.next()) {
//参数为字段名
// String name = rs.getString("ename");
//通过参数为字段位置
String name= rs.getString(1);
// double sal = rs.getDouble("sal");
double sal = rs.getDouble(2);
System.out.println(name+": "+sal);
}
long te = System.currentTimeMillis()-t;
System.out.println(te);
System.out.println("执行完成!");
}
}
下载对应数据库的驱动
一ojdbc6jar / ojdbc14.jar
将驱动类导入到项目中
Maven
加载驱动类
- Class.forName(" orace.jdbc.OracleDriver")
下载对应数据库的驱动
- mysql-connectorjava-5.0.4-bin.jar
将驱动类导入到项目中
一Maven
加载驱动类
- Class.forName(" com.mysql.jdbc.Driver");
将需要改动的数据从代码中移到*.properties配置文件中,好处: 以后便于修改
如何读取配置文件里面的数据:
db.driver=com.mysql.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
db.username=root
db.password=root
db.maxActive=10
db.initialSize=2
/ /属性文件所在的位置
String path =” com/ tarena/ dms/ daodemo/ v2/ db. properties" ;
//获得当前类的路径,加载指定属性文件
properties . load(DBUtility . class. getClassLoader( )
. getResourceAsstream(path));
//在工具类中定义公共的关闭连接的方法
//所有访问数据库的应用,共享此方法
public static void closeConnection(Connection con) {
if(con != nu11) {
try {
con.close();
} catch (SQLException e) {
e. printstackTrace();
}
}
}
自动关闭
package cn.tedu;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo02 {
public static void main(String[] args) {
//获取连接
try (Connection conn = DBUtils.getConn();){
Statement s = conn.createStatement();
String sql = "select ename from emp";
ResultSet rs = s.executeQuery(sql);
while(rs.next()) {
String name = rs.getString(1);
System.out.println(name);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
DataBaseConnectivityPool(数据库连接池)
为什么使用数据库连接池: 如果没有数据库连接池,每一个业务都至少对应一个数据库连接,如果有1万个业务至少有1万次连接的建立和断开,频繁的开关连接非常浪费资源,使用数据库连接池,可以将连接重用,使用完之后的连接并不是断开而是放回连接池中给其它业务使用,这样就避免了频繁开关链接,从而提高了执行效率
连接池中连接的释放与使用原则
创建新的连接
为确保连接池中最小的连接数的策略:
利用Maven导入
com.alibaba
druid
1.1.21
package cn.tedu;
import java.sql.Connection;
import java.sql.SQLException;
import com.alibaba.druid.pool.DruidDataSource;
public class Demo03 {
public static void main(String[] args) throws SQLException {
//创建数据库连接池对象
//如果使用的是DBCPjar包 创建 BasicDataSource
DruidDataSource ds = new DruidDataSource();
//设置数据库连接信息
ds.setDriverClassName("");
ds.setUrl("");
ds.setUsername("");
ds.setPassword("");
//设置初始连接数量
ds.setInitialSize(3);
//设置最大连接数量
ds.setMaxActive(5);
//从连接池中获取连接对象 异常抛出
Connection conn = ds.getConnection();
}
}
需要两个jar包文件
利用Maven导入
commons-dbcp
commons-dbcp
1.4
private static BasicDataSource dataSource
= new BasicDataSource );
dataSource . setDr iverClassName ( dri veClas sName) ;
dataSource . setUrl(ur1);
dataSource . setusername( username) ;
dataSource . setPassword(password);
Connection conn = dataSource . getConnection();
package cn.tedu;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import com.alibaba.druid.pool.DruidDataSource;
public class DBUtils {
private static DruidDataSource ds;
static {
//创建读取*.properties配置文件的对象
Properties p = new Properties();
//获取文件的输入流 通过反射的方式得到文件的输入流
//这种写法会自动去src/main/resources目录下查找文件
InputStream ips =
DBUtils.class.getClassLoader()
.getResourceAsStream("jdbc.properties");
//让文件和读取配置文件的对象关联
try {
p.load(ips);
} catch (IOException e) {
e.printStackTrace();
}
//读取配置文件中的数据
String url = p.getProperty("db.url");
String username = p.getProperty("db.username");
String password = p.getProperty("db.password");
String driver = p.getProperty("db.driver");
//创建数据库连接池对象
//如果使用的是DBCPjar包 创建 BasicDataSource
ds = new DruidDataSource();
//设置数据库连接信息
ds.setDriverClassName(driver);
ds.setUrl(url);
ds.setUsername(username);
ds.setPassword(password);
//设置初始连接数量
ds.setInitialSize(3);
//设置最大连接数量
ds.setMaxActive(5);
}
public static Connection getConn() throws SQLException {
//从连接池中获取连接对象 异常抛出
Connection conn = ds.getConnection();
return conn;
}
}
java.sql.SQL Exception是在处理JDBC时常见的exception对象
用来表示JDBC操作过程中发生的具体错误
SQL Exception属于Checked Exception,必须使用ry..catch或throws明确处理
public static synchronized Connection getConnection() throws
SQLException {
/ /语句
}
try {
//语句
} catch (SQLException e) {
e . printstackTrace();//追踪处理
//throw new Runt imeException(e);//或者抛出
}
用于执行静态 SQL 语句并返回它所生成结果的对象。
创建Statement的方式:
Connection.createStatement( );
执行INSERT, UPDATE和DELETE :
Statement.executeUpdate( )
执行SELECT :
Statement.executeQuery( )
package cn.tedu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo04 {
public static void main(String[] args) throws SQLException {
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root", "root");
Statement s = conn.createStatement();
String sql = "select ename,sal from emp";
//执行查询 得到结果集对象
ResultSet rs = s.executeQuery(sql);
//遍历结果集对象中的查询结果
while(rs.next()) {
//参数为字段名
//String name = rs.getString("ename");
//参数为字段位置
String name = rs.getString(1);
double sal = rs.getDouble(2);
System.out.println(name+":"+sal);
}
conn.close();
}
}
package cn.tedu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo02 {
public static void main(String[] args) throws SQLException {
//2. 获取数据库连接 导包:java.sql
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true",
"root", "root");
Statement s = conn.createStatement();
String sql = "insert into jdbct1 values(1,'刘德华')";
//执行插入数据的SQL
s.executeUpdate(sql);
conn.close();
System.out.println("执行完成!");
}
}
package cn.tedu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo03 {
public static void main(String[] args) throws SQLException {
//2. 获取数据库连接 导包:java.sql
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root", "root");
Statement s = conn.createStatement();
String sql = "update jdbct1 set name='张学友' where id=1";
//执行修改/删除数据的SQL
s.executeUpdate(sql);
conn.close();
System.out.println("执行完成!");
}
}
package cn.tedu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo03 {
public static void main(String[] args) throws SQLException {
//2. 获取数据库连接 导包:java.sql
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/newdb3?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true","root", "root");
Statement s = conn.createStatement();
String sql = "delete from jdbct1 where id=1";
//执行修改/删除数据的SQL
s.executeUpdate(sql);
conn.close();
System.out.println("执行完成!");
}
}
表示预编译的 SQL 语句的对象。
package cn.tedu;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo06 {
public static void main(String[] args) {
//获取数据库连接
try (Connection conn = DBUtils.getConn();) {
// String sql1 = "insert into user values(null,'刘备','123456')";
// String sql2 = "insert into user values(null,'关羽','123123')";
// String sql3 = "insert into user values(null,'张飞','456123')";
// Statement s = conn.createStatement();
// //非批量操作
s.executeUpdate(sql1);
s.executeUpdate(sql2);
s.executeUpdate(sql3);
// //批量操作
// s.addBatch(sql1);
// s.addBatch(sql2);
// s.addBatch(sql3);
// //执行批量操作
// s.executeBatch();
// System.out.println("执行完成!");
//PreparedStatement的批量操作
String sql = "insert into user values(null,?,?)";
PreparedStatement ps = conn.prepareStatement(sql);
for (int i = 1; i <= 100; i++) {
ps.setString(1, "name"+i);
ps.setString(2, "pwd"+i);
//添加到批量操作
ps.addBatch();
//每隔20次执行一次 避免内存溢出
if(i%20==0) {
//执行批量操作
ps.executeBatch();
}
}
//执行批量操作 总次数是20的倍数时 这行代码可删除
ps.executeBatch();
System.out.println("执行完成!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
如果SQL语句中有变量则使用PreparedStatement,没有变量则用Statement
举例:
悲剧:
//场景:
String sql = "select * from t where username= '" + name + "'and password='""+ passwd + "'";
//输入参数后,数据库接受到的完整sq|语句将是:
select * from t where username = 'scott' and password ='tiger';
小练习:注册登录
注册
package cn.tedu;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class Demo04 {
public static void main(String[] args) {
//从控制台获取输入的用户名和密码
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine();
System.out.println("请输入密码");
String password = sc.nextLine();
sc.close();
//获取连接
try (Connection conn = DBUtils.getConn();){
String sql =
"insert into user values(null,'"
+username+"','"+password+"')";
Statement s = conn.createStatement();
s.executeUpdate(sql);
System.out.println("注册成功!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
登录:
package cn.tedu;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class Demo05 {
public static void main(String[] args) {
//从控制台获取输入的用户名和密码
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名");
String username = sc.nextLine();
System.out.println("请输入密码");
String password = sc.nextLine();
sc.close();
//获取数据库连接
try (Connection conn = DBUtils.getConn();) {
//创建登录的SQL语句 把用户输入的内容拼接进去
// String sql =
// "select count(*) from user where username='"
// +username+"' and password='"+password+"'";
// System.out.println(sql);
// Statement s = conn.createStatement();
// ResultSet rs = s.executeQuery(sql);
//解决SQL注入写法
String sql =
"select count(*) from user where username=? and password=?";
//创建预编译的SQL执行对象
//预编译SQL执行对象好处:在创建对象时就将SQL语句业务逻辑锁死
//不会被用户输入的内容导致改变
PreparedStatement ps = conn.prepareStatement(sql);
//替换SQL语句中的? 参数1:第几个问号 参数2:替换的内容
ps.setString(1, username);
ps.setString(2, password);
//执行时切记不能传递SQL语句
ResultSet rs = ps.executeQuery();
//因为查询的结果只有一个数 直接调用next方法
rs.next();
//1代表结果集中第一个字段值
int count = rs.getInt(1);
if(count>0) {//登录成功
System.out.println("登录成功!");
}else {//登录失败
System.out.println("登录失败!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
ResultSet,数据库结果集的数据表,通常通过执行查询数据库的语句生成。
结构化查询语言
ResultSet 对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next 方法将指针移动到下一行;因为该方法在 ResultSet 对象中没有下一行时返回 false,所以可以在 while 循环中使用它来迭代结果集。
默认的 ResultSet 对象不可更新,仅有一个向前移动的指针。因此,只能迭代它一次,并且只能按从第一行到最后一行的顺序进行。可以生成可滚动和/或可更新的 ResultSet 对象。以下代码片段(其中 con 为有效的 Connection 对象)演示了如何生成可滚动且不受其他更新影响的、可更新的结果集。请参阅 ResultSet 字段以了解其他选项。
当生成 ResultSet 对象的 Statement 对象关闭、重新执行或用来从多个结果的序列检索下一个结果时,ResultSet 对象会自动关闭。
//常用的遍历方式:
string sql = "select empno, ename, sal, hiredate from emp" ;
rs = stmt. executeQuery(sq1);
while ( rs.next() ) {
int empno = rs. getInt( "empno") ;
string ename = rs. getstring(" ename") ;
double sal = rs. getDouble("sal");
Date hiredate = rs . getDate( "hiredate" );
}
rs.close( );
package cn.tedu;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Scanner;
public class Demo07 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入查询的页数");
int page = sc.nextInt();
System.out.println("请输入查询的条数");
int count = sc.nextInt();
sc.close();
//获取数据库连接
try (Connection conn = DBUtils.getConn();) {
String sql = "select * from user limit ?,?";
PreparedStatement ps = conn.prepareStatement(sql);
//替换? 跳过的条数=(请求页数-1)*每页条数
ps.setInt(1, (page-1)*count);
ps.setInt(2, count);
ResultSet rs = ps.executeQuery();
//遍历结果集中的多条数据
while(rs.next()) {
//表字段 id,username,password
String name = rs.getString(2);
System.out.println(name);
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
事务特性ACID :
相关API :
try{
autoCommit = con. getAutoCommit(); // 1. 获得自动提交状态
con. setAutoCommit(false); // 2.关闭自动提交
stmt . executeUpdate(sq11); // 3.执行SQL语句
stmt . executeUpdate(sq12);
con. commit(); // 4.提交
con . setAutoCommit( autoCommit); // 5.将自动提交功能恢复到原来的状态
}catch(SQLException e){
conn. rollback();//异常时回滚
}
for(inti=0;i<1000;i++){
sql =“insert into emp( empno, ename)
values(emp_ seq. nextval,' name"+i+"'")";
stmt . addBatch(sq1);将SQL语句加入到Batch中
if(i%500==0){
stmt . executeBatch(); //及时处理
stmt . clearBatch(); //清空列表
}
}
//最后一次列表不足500条,处理
s tmt . executeBatch( );
批量插入练习
package cn.tedu;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo06 {
public static void main(String[] args) {
//获取数据库连接
try (Connection conn = DBUtils.getConn();) {
// String sql1 = "insert into user values(null,'刘备','123456')";
// String sql2 = "insert into user values(null,'关羽','123456')";
// String sql3 = "insert into user values(null,'张飞','123456')";
// //如果SQL 语句中没有变量 用Statement
// Statement s = conn.createStatement();
// //非批量操作
s.executeQuery(sql1);
s.executeQuery(sql2);
s.executeQuery(sql3);
// /*
// * executeUpdate 执行更新
// * executeQuery 执行查询
// * addBatch 添加 批处理
// */
//
// //批量操作
// s.addBatch(sql1);
// s.addBatch(sql2);
// s.addBatch(sql3);
// //执行批量操作
// s.executeBatch();
// System.out.println("执行完成!");
//PreparedStatement 的批量操作
String sql ="insert into user values(null,?,?)";
PreparedStatement ps= conn.prepareStatement(sql);
for (int i = 1; i <= 100; i++) {
ps.setString(1, "name"+i);
ps.setString(2, "pew"+i);
//添加到批量操作
ps.addBatch();
//没隔20次执行一次 避免内存溢出
if(i%20==0) {
ps.executeBatch();
}
}
//执行批量操作 总次数是20的倍数这行代码可以删除
ps.executeBatch();
System.out.println("执行完成!");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
CREATE TABLE animals (
id INT NOT NULL AUTO_ INCREMENT ,
name CHAR(30) NOT NULL ,
PRIMARY KEY (id)
);
INSERT INTO animals (name )
VALUES('dog' ),('cat' ),(' penguin'),('1ax'),( 'whale' ),(' ostrich');
SELECT * FROM animals;
package cn.tedu;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo08 {
public static void main(String[] args) {
//获取数据库连接
try (Connection conn = DBUtils.getConn();) {
String sql = "insert into user values(null,'刘德华','50')";
Statement s = conn.createStatement();
//传递参数 设置获取自增主键值
s.execute(sql,Statement.RETURN_GENERATED_KEYS);
System.out.println("执行完成!");
//获取自增主键值
ResultSet rs = s.getGeneratedKeys();
//移动游标
rs.next();
//因为获取的结果集中只有一个数据所以写1
int id = rs.getInt(1);
System.out.println(id);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
练习:
package cn.tedu;
import java.lang.Thread.State;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
public class Demo10 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入球队名称");
String teamName = sc.nextLine();
System.out.println("请输入球员名称");
String playerName = sc.nextLine();
sc.close();
//获取数据库连接
try (Connection conn = DBUtils.getConn();) {
//先查询 没有插入得到自增teamId 有的话获取出teamId
String sql = "select id from team where name=?";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, teamName);
ResultSet rs = ps.executeQuery();
int teamId;
//判断是否查询到
if(rs.next()) {//查询到了 之前保存过
teamId = rs.getInt(1);
System.out.println("之前保存过球队");
}else {//之前没有存过
String sql1 = "insert into team values(null,?)";
PreparedStatement ps1 = conn.prepareStatement(sql1
,Statement.RETURN_GENERATED_KEYS);
ps1.setString(1, teamName);
ps1.executeUpdate();
//获取自增主键值
ResultSet rs1 = ps1.getGeneratedKeys();
rs1.next();
teamId = rs1.getInt(1);
System.out.println("球队保存完成!");
}
//保存球员
String sql2 = "insert into player values(null,?,?)";
PreparedStatement ps2 = conn.prepareStatement(sql2);
ps2.setString(1, playerName);
ps2.setInt(2, teamId);
ps2.executeUpdate();
System.out.println("保存球员完成");
} catch (SQLException e) {
e.printStackTrace();
}
}
}
public Account findById(Integer id) throws SQLException {
Connection conn = getConnection();
String sql = SELECT BY_ID; //预先定 义好的SQL查询语句
Preparedstatement ps = conn. preparestatement(sq1);
ps.setInt(1, id);//传入参数
ResultSet rs = ps . executeQuery();
Account account = null ;
while(rs .next()){//处理结果集
account=new Account( );
account . setId(rs. getInt( "ACCOUNT_ ID"));
//设置account对象所有的属性,略
}
return ac count ;
}
public boolean update( Account account) throws SQLException {
Connection conn = getConnection();
String sql = UPDATE_STATUS; //预先定义好的SQL语句
Preparedstatement ps = conn.prepareStatement(sq1);
ps.setInt(1, account. getId());//传入参数
ps.setstring(2, account.getstatus() );
int flag= ps.executeUpdate();
return (flag>0 ? true : false);
}
多层系统的异常处理原则: