JDBC总结
jdbc概念快速理解
什么是JDBC:java database Connection ,在Java语言中编写sql语句,对MySQL等数据库进行增删改查等sql语言的操作,就是一套接口,为了降低耦合度,Java和数据库的耦合度,写一套JDBC就可以调用任何数据库
JDBC本质:由JDBC公司创建的一堆接口,再由MYSQL,oracle 实现getConnection接口,程序员写具体操作。
分为三拨人:
**第一波:**SUN公司,负责制定JDBC接口,在Java.sql.*;
**第二波:**厂家实现了jdbc 的接口,MySQL,orcael等待厂家,厂家的实现类都在各自的Jar包里:mysql-connection-java5.1.23.jar jar包中有很多.class字节码文件,这是由厂家实现的
**第三波:**Java程序员面向接口写代码,来凝结数据库写增删改查
**配置:**classpath= .;D\当前路径jar包
JDBC连接数据库基础步骤
-
注册驱动
import.com.mysql.Driver; import.com.mysql.DriverManager; public class test1{ public static void main(String [] args){ //注册驱动 Driver driver = new com.mysql.jdbc.Driver(); DriverManager.registerDriver(driver); } }
-
获取数据库连接
public class test1{ public static void main(String [] args){ //获取数据库连接 String url = "jdbc:mysql:/localhost:3306/数据库名称"; String user = "root"; String password = "123456"; Connection conn = DriverManager.getConnection(url,user,password); } }
URL:统一资源定位符。任何一个url都包括 协议+IP地址+端口号port+资源名
协议:是一个提前规定好的数据传输格式,会按照协议解析得到对应的数据。通信协议很多:http,https…
- jdbc:mysql:// 这是Java与MySQL通信的协议
IP地址:网络当中定位某台计算机
- local host 是本机的IP地址,也可以写成:127.0.0.1
port端口号:定位某台计算机的服务/软件的
- 数据库端口号 3306
资源名:这个服务下的某个资源
-
数据库名称
oracle数据库url路径
oracle:jdbc:thin:@localhost:1521:数据库名称
-
获取数据库操作对象
public class test1{ public static void main(String [] args){ //获取数据库对象 Statement stat = conn.createStatement(); } }
Statement:是将sql语句传输到数据库中的
-
执行sql语句
public class test1{ public static void main(String [] args){ //执行sql 语句 String sql = "insert into dept(deptsno,dname,dage)"; int count = stat.executeUpdate(sql); } }
Statement中的executeUpdate();方法是专门用来解析语句的 ,返回的Count 值影响了数据库表中的记录数,或者使用executeQuery()方法,查询sql语句,只是结果会自动封装在ResuletSet结果集中
-
返回结果集并处理数据库中其他字段
ResultSet rs = null; if(rs.next()){ user = new User(); user.setId(rs.getInt("id")); user.setUserCode(rs.getString("userCode")); user.setUserName(rs.getString("userName")); user.setUserPassword(rs.getString("userPassword")); user.setGender(rs.getInt("gender")); user.setBirthday(rs.getDate("birthday")); user.setPhone(rs.getString("phone")); user.setAddress(rs.getString("address")); user.setUserRole(rs.getInt("userRole")); user.setCreatedBy(rs.getInt("createdBy")); user.setCreationDate(rs.getDate("creationDate")); user.setModifyBy(rs.getInt("modifyBy")); user.setModifyDate(rs.getDate("modifyDate")); }
Resultset 有一个next()方法:将光标向前移一位,有数据返回true,反之亦然
-
释放资源
try{ }catch(){ }finally{ //显示放statement,在释放connection, if(stat != null){ try{ stat.close(); }catch(SQLException e){ e.printStackTrace(); } } if(conn != null){ try{ conn.close(); }catch(SQLException e){ e.printStackTrace(); } } }
注册驱动两种方式
注册驱动第一种方式
//注册驱动 DriverManager.registerDriver(new com.mysql.jdbc.Driver());
**注册驱动的第二种方式:**静态代码块,随着类加载注册
-
//Driver已经帮你做好了驱动方法,你只需要调用forName() static{ try{ java.sql.DriverManager.registerDriver(new Driver()); }catch(SQLExption e){ throw new RuntimeException("can`t register driver!") } }
-
调用如下
try{
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取链接
conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test","root","123456");
//获取数据库操作对象
stat = conn.createStatement();
//执行SQL
String sql = "select * from emp";
//返回结果集
rs = stat.executeQuery(sql);
//处理查询结果集
while(rs.next()){
int tid = resultSet.getInt("tid");
String tuname = resultSet.getString("tuname");
String tupass = resultSet.getString("tupass");
System.out.println(tid +" "+tuname+" "+tupass);
}
}catch(SQLExption e){
e.printStackTrace();
}finally{
if(rs != null){
try{
rs.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(stat != null){
try{
stat.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(conn != null){
try{
conn.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
资源绑定器:连接其他数据库(Oracle)只需要改配置的资源文件即可
配置好驱动资源文件
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/smbms?useSSL=true&Unicode=true&characterEncoding=utf-8
username=root
password=123456
//静态代码块,类加载的时候就初始化,读文件
static{
Properties properties = new Properties();
//通过类加载器读取对应的资源,设为流
InputStream is = BaseDao.class.getClassLoader().getResourceAsStream("db.properties");
try {
properties.load(is);
} catch (IOException e) {
e.printStackTrace();
}
//类一加载,即赋值了
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
}
//简易资源加载方式
ResourceBundle bundle = ResourceBundle.getBundle("resource/db");
driver = properties.getProperty("driver");
url = properties.getProperty("url");
username = properties.getProperty("username");
password = properties.getProperty("password");
**SQL注入:**随便输入用户名和密码登陆成功被称为SQL注入。eg:fdsa fdsa or ‘1’=‘1’
-
根本原因:输入的信息中含有sql语句的关键字,该关键字和底层的SQL语句进行拼接,用户提供的SQL语句参与了编译,该程序先进行拼接字符串后编译sql语句java.aql.Statement接口的特点就是先进行字符串拼接后进行编译
sql语句与变量拼接eg:
String sql = "select * from student where name = '" + loginName + "' and login_pwd = '" + login_pwd + "' "
-
解决办法:使用 java.sql.PreparedStatement:先编译后sql拼接 缺点:没有办法进行sql语句拼接只能给sql语句进行传值
//省略了一部分代码 //获取预编译的数据库对象 String sql = "select * from student where name = ? and pwd = ?"; //获取数据库连接时,就已经将sql语句传给了数据库操作对象stat stat = connection.prepareStatement(sql); stat.setString(1,2); stat.setString(2,"田径"); //当执行exectueQuery()方法时,不用将sql语句传入 rs = stat.exectueQuery();//结果集整合
-
prepareStatement做模糊查询时
String sql = select * from student where like ?; // stat = conn.prepareStatement(sql); //模糊查询时,查询必须是占位符,传的值是一个整体 stat.setString(1,"%O%")
-
map集合:存放数据集
public class test1{
public static void main(String [] args){
Map<String,String> userLoginInfo = initUI;
boolean ok =checkNameAndPwd(userLoginInfo.get("loginName"),userLoginInfo.get("loginPwd"));
System.out.println(ok ? "登陆成功":"登陆失败")
}
public Map<String,String> initUI(){
//将数据存放到map结果集中
}
public static boolean checkNameAndPwd(String loginName ,String loginPwd){}
}
JDBC事务
//关闭自动提交,一获取数据库链接就关闭
conn.setAutoCommit(false);
//手动提交事务,所以事务处理完提交
conn.commit();
//手动回滚,当出现异常时回滚
conn.rollback();
工具类的封装:
package com.pan.jdbc.util;
import java.sql.*;
import java.util.ResourceBundle;
import static java.lang.Class.forName;
public class DButils {
//工具类中的方法一般都是私有化的,防止new处对象,直接类调用,工具类中的方法都是静态的
private DButils(){}
//类加载时绑定属性文件
private static ResourceBundle bundle = ResourceBundle.getBundle("resource/db");
//类加载,注册驱动
static{
try{
//从db资源文件中拿到驱动driver
Class.forName(bundle.getString("driver"));
}catch(ClassNotFoundException e){
e.printStackTrace();
}
}
//获取数据库连接对象,返回新的连接对象
private static Connection getConnection() throws SQLException {
String url = bundle.getString("url");
String name = bundle.getString("name");
String password = bundle.getString("password");
Connection conn = DriverManager.getConnection(url,name,password);
return conn;
}
public static void close(Connection conn, Statement stat, ResultSet rs){
if(rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stat != null){
try {
stat.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn != null){
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
工具类测试
package com.pan.jdbc.util;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCTest01 {
public static void main(String[] args) {
Connection connection =null;
ResultSet rs = null;
PreparedStatement preparedStatement =null;
//获取链接
try {
connection = DButils.getConnection();
//获取预编译的数据库对象
String sql = "select * from student where tuname like ?";
preparedStatement = connection.prepareStatement(sql);
//传值
preparedStatement.setString(1,"%x%");
//处理结果
rs = preparedStatement.executeQuery();
//查询光标下移
while (rs.next()){
System.out.println(rs.getString("tuname")+","+rs.getInt("tid")+","+rs.getString("tupass"));
}
System.out.println(rs);
} catch (SQLException e) {
e.printStackTrace();
}finally {
DButils.close(connection,preparedStatement,rs);
}
}
}