Java数据库连接(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。JDBC也是Sun Microsystems的商标。我们通常说的JDBC是面向关系型数据库的。
JDBC 开发使用到的包:
JDBC 的核心 API:
1. 数据库驱动
IDEA建立普通的 Java工程
准备jar包 - mysql-connector-java-5.1.27.jar
导入jar包 -Add as Library
2. 第一个JDBC程序
package JDBCdemo; import java.sql.*; public class Demo02 { public static void main(String[] args) throws ClassNotFoundException, SQLException { // 1.加载驱动 固定写法 Class.forName("com.mysql.jdbc.Driver"); // 2.用户信息 String url="jdbc:mysql://localhost:3306/jdbc01?useUnicode=true&characterEncoding=utf8&useSSL=true"; String usename="root"; String password="sm1208"; // 3.连接成功,数据库对象 Connection代表数据库 Connection connection= DriverManager.getConnection(url,usename,password); // 4.执行SQL语句 Statement statement =connection.createStatement(); // 5.执行sql语句 String sql ="SELECT *FROM user"; ResultSet resultSet =statement.executeQuery(sql); while (resultSet.next()){ System.out.println("id="+resultSet.getObject("id")); System.out.println("name="+resultSet.getObject("name")); } // 6.释放资源 resultSet.close(); statement.close(); connection.close(); } }
3. 步骤总结
1.加载驱动
2.连接数据库 DriverManager
3.获取执行sql语句的对象 Statement
4.获取返回的结果集
5.释放资源
4. JDBC中对象解释
Driver Manager 驱动程序管理器
// DriverManager.registerDiver(new com.mysql.jdbc.Driver()); // Class.forName(数据库驱动实现类) Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动 Connection.connection=DriverManager.getConnection(url,username,password); //connection代表数据库 //数据库设置自动提交 //事务提交 事务滚回 connection.rollback(); connection.commit(); connection.setAutocommit();
URL
String url="jdbc:mysql://localhost:3306/jdbc01?useUnicode=true&characterEncoding=utf8&useSSL=true"; //协议://主机地址:端口号/数据库名?参数1&参数2&参数3 //mysql //jdbc:mysql://localhost:3306/数据库名?参数1&参数2&参数3 //oralce //jdbc:oralce:think@hocalhost:1521:sid 复制代码
Statement 执行SQL的对象
// Statement 执行sql的对象 PrepareStatement执行sql的对象 String sql="SELECT *FROM user"//编写sql语句 statement.executeQuery(); //查询操作 statement.execute(); //执行任何sql语句 statement.executeUpdate();//更新、插入、删除 都是这个,返回一个受影响的行数
ResultSet 查询返回的结果集
// 查询结果集:封装了所有的查询结果 获得指定的数据类型 resultSet.getObject(); //在不知道数据类型的情况下使用 resultSet.getString; resultSet.getInt; resultSet.getFloat; resultSet.getDouble;
遍历、指针
resultSet.beforeFirst(); //移动到最前面 resultSet.afterlast(); //移动到最后面 resultSet.next(); //移动到下一个数据 resultSet.previous(); //移动到下一行 resultSet.absolute(row); //移动到指定行
释放资源
resultSet.close(); statement.close(); connection.close(); //耗资源 必须关
5. Statement对象
JDBC的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过对这个对象向数据库发送增删改查语句即可
Statement对象的主要方法
executeUpdate方法,用于向数据库发送增、删、改、查的sql语句,executeUpdata执行完毕后,将会返一个整数(即增删改查语句导致数据库几行数据发生了变化。)
executeQuery方法用于向数据发送查询语句,executeQuery方法返回代表查询结果的Eesult对象。
- Create操作:使用executeUpdate(String sql)方法完成数据库的添加操作,如下
Statement st =conn.createStatement(); String sql ="insert into user(...) value(...)"; int num=st.executeUpdate(sql); if(num>0){ System.out.println("插入成功!"); }
- Delete操作:使用executeUpdate(String sql)方法完成数据库的删除操作,如下
Statement st =conn.createStatement(); String sql ="delete from user where id=? "; int num=st.executeUpdate(sql); if(num>0){ System.out.println("删除成功!"); }
- Update操作:使用executeUpdate(String sql)方法完成数据库的修改操作,如下
Statement st =conn.createStatement(); String sql ="update user set name="" where name="" "; int num=st.executeUpdate(sql); if(num>0){ System.out.println("修改成功!"); }
- Read操作:使用executeQuery(String sql)方法完成数据库的c查询操作,如下
Statement st =conn.createStatement(); String sql ="select *from user where id=1 "; ResultSet rs=st.executeQuery(sql); whlie(rs.next){ //根据获取列的数据类型,分别调用rs的相应方法映射到java对象中 //resultSet.getObject(); //resultSet.getString; //resultSet.getInt; //resultSet.getFloat; //resultSet.getDouble; }
5.1 提取工具类
package utils; import java.io.InputStream; import java.sql.*; import java.util.Properties; public class JdbcUtils { private static String driver = null; private static String url = null; private static String username = null; private static String password = null; static { try { InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties"); Properties properties = new Properties(); properties.load(in); driver = properties.getProperty("driver"); url = properties.getProperty("url"); username = properties.getProperty("username"); password = properties.getProperty("password"); // 1、驱动只用加载一次 Class.forName(driver); } catch (Exception e) { e.printStackTrace(); } } // 获取连接 public static Connection getConnection() throws SQLException { return DriverManager.getConnection(url, username, password); } // 释放资源 public static void release(Connection conn, Statement st, ResultSet rs) throws SQLException { if (rs != null) { rs.close(); } if (st != null) { st.close(); } if (conn != null) { conn.close(); } } }
5.2 编写增删改的方法
- 增
package JDBCdemo.Demo03; import utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TextInsert { public static void main(String[] args) throws SQLException { Connection conn=null; Statement st=null; ResultSet rs=null; try{ conn = JdbcUtils.getConnection(); // 获取数据库连接 st=conn.createStatement(); // 获取 SQL的执行对象 String sql="INSERT INTO user(id,name) VALUES ('3','jumper')"; int i=st.executeUpdate(sql); if(i>0){ System.out.println("插入成功!"); } // 执行SQL语句 } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }
- 删
package JDBCdemo.Demo03; import utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TextDelete { public static void main(String[] args) throws SQLException { Connection conn=null; Statement st=null; ResultSet rs=null; try{ conn = JdbcUtils.getConnection(); // 获取数据库连接 st=conn.createStatement(); // 获取 SQL的执行对象 String sql="DELETE from `user` WHERE id = 2"; int i = st.executeUpdate(sql); if(i>0) System.out.println("删除成功"); // 执行SQL语句 } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }
- 改
package JDBCdemo.Demo03; import utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TextUpdate { public static void main(String[] args) throws SQLException { Connection conn=null; Statement st=null; ResultSet rs=null; try{ conn = JdbcUtils.getConnection(); // 获取数据库连接 st=conn.createStatement(); // 获取 SQL的执行对象 String sql="UPDATE `user` SET `name`='孙不坚' WHERE id=3 "; int i = st.executeUpdate(sql); if(i>0) System.out.println("修改成功"); // 执行SQL语句 } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }
- 查
package JDBCdemo.Demo03; import utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class TextRead { public static void main(String[] args) throws SQLException { Connection conn=null; Statement st=null; ResultSet rs=null; try{ conn = JdbcUtils.getConnection(); // 获取数据库连接 st=conn.createStatement(); // 获取 SQL的执行对象 String sql="select * from user "; // 查询获取返回集合 ResultSet query = st.executeQuery(sql); // 遍历 while (query.next()){ System.out.println(query.getObject("id")); System.out.println(query.getObject("name")); } // 执行SQL语句 } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }
6 SQL注入问题
所谓SQL注入(sql inject),就是通过把SQL命令插入到Web表单提交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的SQL命令。具体来说,它是利用现有应用程序,将(恶意的)SQL命令注入到后台数据库引擎执行的能力,它可以通过在Web表单中输入(恶意)SQL语句得到一个存在安全漏洞的网站上的数据库,而不是按照设计者意图去执行SQL语句。
使用Statement的话,sql 存在漏洞。
package JDBCdemo.Demo03; import JDBCdemo.Demo03.utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; public class SQLinject { public static void main(String[] args) throws SQLException { login("'' or 1=1","'' or 1=1"); } public static void login(String username,String password) throws SQLException { Connection conn=null; Statement st=null; ResultSet rs=null; try { //SELECT * FROM `users` WHERE `NAME`='' or 1=1 AND `PASSWORD`='' or 1=1 ; //获取连接 conn = JdbcUtils.getConnection(); //获取sql对象 st= conn.createStatement(); //sql String sql="SELECT * FROM `user` "; //查询获取返回集合 ResultSet query = st.executeQuery(sql); //遍历 while (query.next()){ System.out.println(query.getObject("id")); System.out.println(query.getObject("name")); } } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }
7 PreparedStatement对象
PreparedStatement可以防止SQL注入,更安全
7.1 编写增删改的方法
- 增
package JDBCdemo.Demo04; import JDBCdemo.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class TextInsert { public static void main(String[] args) throws SQLException { Connection conn=null; PreparedStatement st=null; try { conn = JdbcUtils.getConnection(); //获取数据库链接 String sql="INSERT INTO user(`name`,`id`) VALUES (?,?)"; st= conn.prepareStatement(sql); st.setObject(1,"孙孙孙"); st.setObject(2,"5"); int i = st.executeUpdate(); if(i>0) System.out.println("插入成功"); }catch (Exception e){ e.printStackTrace(); }finally { JdbcUtils.release(conn,st,null); } } }
- 删
package JDBCdemo.Demo04; import JDBCdemo.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class TextDelete { public static void main(String[] args) throws SQLException { Connection conn=null; PreparedStatement st=null; try { conn = JdbcUtils.getConnection(); //获取数据库链接 String sql="DELETE from user WHERE id=?"; st= conn.prepareStatement(sql); st.setObject(1,1); int i = st.executeUpdate(); if(i>0) System.out.println("删除成功"); }catch (Exception e){ e.printStackTrace(); }finally { JdbcUtils.release(conn,st,null); } } }
- 改
package JDBCdemo.Demo04; import JDBCdemo.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.SQLException; public class TextUpdate { public static void main(String[] args) throws SQLException { Connection conn=null; PreparedStatement st=null; try { conn = JdbcUtils.getConnection(); //获取数据库链接 String sql="update `user` set `name` =?, WHERE id=?"; st= conn.prepareStatement(sql); st.setObject(1,"铭铭铭"); st.setObject(2,"1"); int i = st.executeUpdate(); if(i>0) System.out.println("更新成功"); }catch (Exception e){ e.printStackTrace(); }finally { JdbcUtils.release(conn,st,null); } } }
- 查
package JDBCdemo.Demo04; import JDBCdemo.utils.JdbcUtils; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class TextRead { public static void main(String[] args) throws SQLException { Connection conn=null; PreparedStatement st=null; ResultSet rs=null; try { //获取连接 conn = JdbcUtils.getConnection(); //sql String sql="SELECT * from user WHERE id<?"; //预编译sql st= conn.prepareStatement(sql); //设置参数 st.setObject(1,3); //执行sql rs=st.executeQuery(); //遍历结果 while (rs.next()){ System.out.println(rs.getObject("NAME")); } } catch (SQLException e) { e.printStackTrace(); }finally { JdbcUtils.release(conn,st,rs); } } }
7.2 防止sql注入
package JDBCdemo.Demo04; import JDBCdemo.utils.JdbcUtils; import java.sql.Connection; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.PreparedStatement; public class SQLinject { public static void main(String[] args) throws SQLException { login("孙不坚","123456"); } public static void login(String username,String password) throws SQLException { Connection conn=null; PreparedStatement st=null; ResultSet rs=null; try { //SELECT * FROM `users` WHERE `NAME`='' or 1=1 AND `PASSWORD`='' or 1=1 ; //获取连接 conn = JdbcUtils.getConnection(); //获取sql对象 //PreparedStatement 防止sql注入的本质,把传递进来的参数当做字符 // 假设其中存在转义字符,比如说' 会被忽略掉 String sql="SELECT * FROM `user` WHERE `name`=? AND `id`= ?"; st= conn.prepareStatement(sql); st.setObject(1,username); st.setObject(2,password); rs=st.executeQuery(); //sql //查询获取返回集合 //遍历 while (rs.next()){ System.out.println("登陆成功"); } } catch (SQLException e) { e.printStackTrace(); } finally { JdbcUtils.release(conn,st,rs); } } }