JDBC
一、JDBC基础操作
常见连接书写方式:
JDBC的URL=协议名+子协议名+数据源名。
a .协议名总是“jdbc”。
b .子协议名由JDBC驱动程序的编写者决定。
c .数据源名也可能包含用户与口令等信息;这些信息也可单独提供。
几种常见的数据库连接
1 —oracle—
驱动:oracle.jdbc.driver.OracleDriver
URL:jdbc:oracle:thin:@machine_name:port:dbname
注:machine_name:数据库所在的机器的名称;
port:端口号,默认是1521
2 —mysql—
驱动:com.mysql.jdbc.Driver
URL:jdbc:mysql://machine_name:port/dbname
注:machine_name:数据库所在的机器的名称;
port:端口号,默认3306
3 —SQL Server—
驱动:com.microsoft.jdbc.sqlserver.SQLServerDriver
URL:jdbc:microsoft:sqlserver://<machine_name><:port>;DatabaseName=<dbname>
注:machine_name:数据库所在的机器的名称;
port:端口号,默认是1433
4 —DB2—
驱动:com.ibm.db2.jdbc.app.DB2Driver
URL:jdbc:db2://<machine_name><:port>/dbname
注:machine_name:数据库所在的机器的名称;
port:端口号,默认是5000
A、实现增加操作
public class InsertDept {
public static void main(String[] args) throws Exception {
//[0]导入数据库驱动包
//新建lib文件夹,在oracle安装路径下找到ojdbc6.jar拷入lib中,再将jar包导入项目即可。其他数据库同理。
//[1]加载驱动
// Refereced Librariers --> ojdbc6.jar --> oracle.jdbc --> OracleDriver
Class.forName("oracle.jdbc.OracleDriver");
//[2]建立数据库连接
Connection conn= DriverManager.getConnection("jdbc:oracle:thin:127.0.0.1:1521:orcl", "scott", "tiger");
//[3]建立命令发送器(手枪)
Statement stmt = conn.createStatement();
//[4]执行sql语句(子弹),返回结果
int update= stmt.executeUpdate("insert into dept values(70,'IT','BEIJING')");//增
//[5]处理结果
if(update>0){
System.out.println("修改成功");
}else{
System.out.println("修改失败");
}
//[6]关闭资源
stmt.close();
conn.close();
}
}
B、问题分析和处理
/**
* 错误一:java.lang.ClassNotFoundException: oracle.jdbc.OracleDriver
* 原因:ojdbc6.jsr包没有导入
*
* 错误二: java.sql.SQLException: No suitable driver found for jdbc:orcale:thin:@127.0.0.1:1521:orcl
* 原因:路径错误 url
*
* 错误三:java.sql.SQLException: ORA-01017: invalid username/password; logon denied
* 原因:数据库的 账号或者密码错误
*
* 错误四:java.sql.SQLSyntaxErrorException: ORA-00911: 无效字符
* 原因:sql语句不需要分号
*
* 错误五: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: 违反唯一约束条件 (SCOTT.PK_DEPT)
*
* 原因:主键冲突:
* 解决:添加序列 采用自增
* 问题六: oracle.jdbc.OracleDriver和oracle.jdbc.driver.OracleDriver的关系
* 原因: 子父类关系
* 问题七:Class.forName("oracle.jdbc.driver.OracleDriver"); 作用
*
* 执行该类的静态代码块的内容 :注册了驱动
* defaultDriver = new oracle.jdbc.OracleDriver();
DriverManager.registerDriver(defaultDriver);
*
* 问题八: Class.forName("oracle.jdbc.driver.OracleDriver"); 为什么可以省略
* ojdbc14.jar不支持
*
* ojdbc6.jar中提供了META-INF----services---java.sql.Driver
* 已经提供好了驱动,不用自己配置
*
* */
C、代码优化及实现删除、修改操作
public class DeleteDept {
public static void main(String[] args){
//[0]导入数据库驱动包
Connection conn=null;
Statement stmt=null;
int update=0;
try {
//[1]加载驱动
Class.forName("oracle.jdbc.OracleDriver");
//[2]建立数据库连接
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "tiger");
//[3]建立命令发送器(手枪)
stmt = conn.createStatement();
//[4]执行sql语句(子弹),返回结果
update= stmt.executeUpdate("delete from dept where deptno=60");//删
update= stmt.executeUpdate("update dept set dname='IT' where deptno=60");//更新修改
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//[6]关闭资源
try {
if(stmt!=null){
stmt.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
//[5]处理结果
if(update>0){
System.out.println("删除成功");
}else{
System.out.println("删除失败");
}
}
}
D、实现查询操作
public class SelectDept {
public static void main(String[] args){
//[0]导入数据库驱动包
Connection conn=null;
Statement stmt=null;
try {
//[1]加载驱动
Class.forName("oracle.jdbc.OracleDriver");
//[2]建立数据库连接
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "tiger");
//[3]建立命令发送器(手枪)
stmt = conn.createStatement();
//[4]执行sql语句(子弹),返回结果
//resultset
//ResultSet中保存的是若干行若干列的数据,每一行有多个字段,并且还有一个指针
//如果想要实现操作需要移动指针判断是否有下一个数据,利用方法.next()
//方法返回true证明可以输出下一个返回false证明没有
ResultSet rs= stmt.executeQuery("select * from dept");
//[5]处理结果
while(rs.next()){
//A 方式一:从集合中取数据 1,2,3代表的是第1列 、第2列、第3列数据
/*int dno= rs.getInt(1);
String dname=rs.getString(2);
String loc =rs.getString(3);*/
// 方式二: 可读性比较好 "deptno":是数据库的列名 是不区分大小写的
int dno= rs.getInt("deptno");
String dname=rs.getString("DNAME");
String loc =rs.getString("Loc");
//B、输出数据
System.out.println(dno+"----"+dname+"---"+loc);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//[6]关闭资源
try {
if(stmt!=null){
stmt.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
二、JDBC完善查询操作
A、User类(相当于前台)
public class User {
//相当于用户的前台
/**
* 用户访问的时候应该是有前后台的数据传递, 用户查询的数据应该是在前台遍历输出
* 不是在后台
*
* [1]直接返回ResultSet结果集
*
* 缺点:数据库的所有的资源全部无法关闭
*
* [2]把ResultSet里面的数据取出来存到list集合里面
* 直接返回list即可
*
* 如何返回后台的数据
* 第一步:
* 把数据库中表对应的实体类建立完成
*
* 第二步:
* [A]把数据从rs集合中取出来
* [B]把取出来的数据放到对象里面(构造方法、set/get)
* [c]把对象存到集合中即可
*
* */
public static void main(String[] args) throws SQLException {
FindDept dapt=new FindDept();
//调用后台返回的数据
List<Dept> list = dapt.findAll();
//把数据输出到前台
for (Dept de : list) {
System.out.println(de);
}
}
}
B、FindDept(相当于后台)
public class FindDept {
//后台操作
public List<Dept> findAll(){
//[0]导入数据库驱动包
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
List<Dept> list=new ArrayList<Dept>();
try {
//[1]加载驱动
Class.forName("oracle.jdbc.OracleDriver");
//[2]建立数据库连接
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "scott");
//[3]建立命令发送器(手枪)
stmt = conn.createStatement();
//[4]执行sql语句(子弹),返回结果---resultset
rs= stmt.executeQuery("select * from dept");
//[5]处理结果
while(rs.next()){
//A 方式一:从集合中取数据 1,2,3代表的是第1列 、第2列、第3列数据
// 方式二: 可读性比较好 "deptno":是数据库的列名 是不区分大小写的
int dno= rs.getInt("deptno");
String dname=rs.getString("DNAME");
String loc =rs.getString("Loc");
//B、把数据存放到 对象里面 Dept
Dept dept=new Dept(dno, dname, loc);
//C、把dpet对象存到list集合里面
list.add(dept);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//[6]关闭资源
try {
if(rs!=null){
rs.close();
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
if(stmt!=null){
stmt.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return list;
}
}
C、数据库实体类
public class Dept {
private int deptno;
private String dName;
private String loc;
public int getDeptno() {
return deptno;
}
public void setDeptno(int deptno) {
this.deptno = deptno;
}
public String getdName() {
return dName;
}
public void setdName(String dName) {
this.dName = dName;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public Dept(int deptno, String dName, String loc) {
super();
this.deptno = deptno;
this.dName = dName;
this.loc = loc;
}
public Dept() {
super();
}
@Override
public String toString() {
return "Dept [deptno=" + deptno + ", dName=" + dName + ", loc=" + loc
+ "]";
}
}
三、JDBC完成登陆
A、UserLogin(前台)
public class UserLogin {
/**
* 需求:实现用户的登录 ,用户登录成功 ---欢迎zs登录 登录失败---账号和密码不匹配
*
* 实现步骤:
* [1]创建数据库表 t_users (userid username pwd )
* [2]创建数据库表的实体对象
* [3]前台代码:在控制台可以输入 用户名和密码 , 对于返回的结果做处理
* [4]后台代码:连接数据库的操作
* 用户登录--对应数据库的查询 查询单个----true/false / 对象(√) /集合
*
* Statement:存在的问题(sql注入)
*
* PreparedStatement(预编译 )防止sql注入的问题(推荐使用这种方式)
* 【1】PreparedStatement使用的时候更加的安全
* 【2】PreparedStatement使用的时候效率比较高
*
* */
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("请输入用户名");
String uname = sc.next();
System.out.println("请输入密码:");
String pwd =sc.next();
JDBCUtil util=new JDBCUtil();
User user = util.selectOne(uname, pwd);
if(user==null){
System.out.println("用户名和密码不匹配");
}else{
System.out.println("欢迎"+user.getUserName()+"登录");
}
}
}
B、JDBCUtil(后台)
public User selectOne(String uname,String pwd){
//[0]导入数据库驱动包
Connection conn=null;
PreparedStatement pstmt=null;
ResultSet rs=null;
User user=null;
try {
//[1]加载驱动
Class.forName("oracle.jdbc.OracleDriver");
//[2]建立数据库连接
conn=DriverManager.getConnection("jdbc:oracle:thin:@127.0.0.1:1521:orcl", "scott", "scott");
//[3]建立命令发送器(手枪)
// ?占位符
String sql="select * from t_users where username=? and pwd=?";
pstmt = conn.prepareStatement(sql);
//[4]执行sql语句(子弹),返回结果
//给占位符赋值
pstmt.setString(1, uname);
pstmt.setString(2, pwd);
rs= pstmt.executeQuery();
//System.out.println("select * from t_users where username='"+uname+"' and pwd='"+pwd+"'");
//[5]处理结果
while(rs.next()){
//[A]从rs中把查询的数据取出来
int uid = rs.getInt("userID");
String uname2=rs.getString("username");
String pwd2=rs.getString("pwd");
//[B]把取出来的数据存入到对象中
user=new User(uid, uname2, pwd2);
}
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally{
//[6]关闭资源
try {
if(rs!=null){
rs.close();
}
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
try {
if(pstmt!=null){
pstmt.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null){
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
return user;
}
}
Cã 数据库实体类
public class LoginUsers {
private int userId;
private String userName;
private String pwd;
public LoginUsers() {
super();
}
public LoginUsers(int userId, String userName, String pwd) {
super();
this.userId = userId;
this.userName = userName;
this.pwd = pwd;
}
public int getUserId() {
return userId;
}
public void setUserId(int userId) {
this.userId = userId;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "LoginUsers [userId=" + userId + ", userName=" + userName
+ ", pwd=" + pwd + "]";
}
}
t_user表: