JDBC——连接数据库
JDBC的基本介绍
1、概述:jdbc是使用Java访问各种数据库的一种技术
(1)jdbc工作原理
2、jdbc核心Java类(API)
(1)DriverManager类
作用:管理各种数据库的驱动(JDBC的驱动),可以用它来获取数据库连接。根据所给的驱动去获取对应数据库的链接
(2)Connection接口
负责连接数据库,并担任传输数据的任务
(3)Statement接口
由Connection产生,负责执行SQL语句
(4)ResultSet接口
负责保存Statement执行后所产生的查询结果(数据库中查询出来的数据保存在ResultSet中)
3、使用JDBC的步骤
(1)建立Java与数据库之间的链接,将数据库的驱动包,复制到项目的lib目录中,复制完毕以后鼠标右键jar包,选择build path ,再选择 add to build path
(2)新建一个专门负责连接数据库的工具类DBUtil,并准备连接数据库的数据
连接数据库需要知道数据库的地址url,用户名 user,密码 password,以及数据库对应的驱动。如果需要连接数据库需要先将这些数据准备好。参考代码如下:
/** * 连接数据库的工具类 */ public class DBUtil { //1.准备连接数据库的数据 // 数据库服务器的地址 // jdbc:mysql://数据服务器ip地址:端口号/需要访问的数据库 // localhost: 本机的ip地址 可以写成 127.0.0.1 // 3306 : mysql 的默认端口号 static String url = "jdbc:mysql://localhost:3306/myschool"; // 数据库的用户名 :mysql的默认用户名是root static String user = "root"; // 数据库的密码: 填写自己的mysql 密码 static String password = "root"; // 数据库的驱动 static String driver = "com.mysql.jdbc.Driver"; }
(3)在DBUtil类中,添加获取数据库的工具方法
在一个项目中,会频繁使用,所以将它封装成一个工具方法,参考代码如下:
/** * 负责获取数据库连接的工具方法 * @return Connection :数据库连接的对象 (桥梁,可以通过此对象访问数据库) */ public static Connection getCon(){ //1.安装数据库驱动(加载驱动类) try { Class.forName(driver); //2.根据url,user,password获取数据库连接 Connection con = DriverManager.getConnection(url, user, password); return con; } catch (Exception e) { e.printStackTrace(); } return null; }
(4)添加main方法测连接,参考代码如下:
public static void main(String[] args) { System.out.println(getCon()); }
运行结果:
(5)DBUtil完整代码
package jdbc; import java.sql.Connection; import java.sql.DriverManager; /** * 连接数据库的工具类 */ public class DBUtil { //1.准备连接数据库的数据 // 数据库服务器的地址 // jdbc:mysql://数据服务器ip地址:端口号/需要访问的数据库 // localhost: 本机的ip地址 可以写成 127.0.0.1 // 3306 : mysql 的默认端口号 static String url = "jdbc:mysql://localhost:3306/myschool"; // 数据库的用户名 :mysql的默认用户名是root static String user = "root"; // 数据库的密码: 填写自己的mysql 密码 static String password = "root"; // 数据库的驱动 static String driver = "com.mysql.jdbc.Driver"; /** * 负责获取数据库连接的工具方法 * @return Connection :数据库连接的对象 (桥梁,可以通过此对象访问数据库) */ public static Connection getCon(){ //1.安装数据库驱动(加载驱动类) try { Class.forName(driver); //2.根据url,user,password获取数据库连接 Connection con = DriverManager.getConnection(url, user, password); return con; } catch (Exception e) { e.printStackTrace(); } return null; } public static void main(String[] args) { System.out.println(getCon()); } }
3、使用JDBC实现对数据库表的增删改查
(1)向指定数据库表中插入数据
案例:使用jdbc向subject表中插入数据,参考代码如下:
① 创建一个实体类与数据库中中的表对应起来
package jdbc; /** * 创建一个实体类 与数据库中中的表对应起来 * 实体类:Subjet 对应 数据库表 subject * 实体类的属性 对应 数据库表中的字段 * @author xp * */ public class Subject { private int subjectNo;// 对应subject表中的subjectNo 字段 private String subjectName;//对应subject表中的subjectName字段 private int classHour;//对应subject表中的classHour字段 private int gradeId;//对应subject表中的gradeId字段 public int getSubjectNo() { return subjectNo; } public void setSubjectNo(int subjectNo) { this.subjectNo = subjectNo; } public String getSubjectName() { return subjectName; } public void setSubjectName(String subjectName) { this.subjectName = subjectName; } public int getClassHour() { return classHour; } public void setClassHour(int classHour) { this.classHour = classHour; } public int getGradeId() { return gradeId; } public void setGradeId(int gradeId) { this.gradeId = gradeId; } }
② 新建一个Dao类,来操作数据库表,参考代码如下:
package jdbc; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; /** * 操作数据库表 subject * */ public class SubjectDao { /** *向数据库表subject中插入数据的方法 */ public static void insert(Subject sub){ //获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 // id是自增涨的,所以这里不需要插入id,插入数据时会自动生成id String sql = "insert into subject(" + "subjectName,classHour,gradeId)" + " values('"+sub.getSubjectName() + "',"+sub.getClassHour() + ","+sub.getGradeId()+")"; System.out.println(sql); //3.构建sql语句 Statement st = null; try { st = con.createStatement(); //4.执行sql语句 st.execute(sql); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally { //5.关闭连接 try { st.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } } public static void main(String[] args) { //测试插入方法 Subject sub = new Subject(); //只设置课程名称,表示只向数据库表中插入课程名称 sub.setSubjectName("布丁制作"); insert(sub); } }
(2)查询指定表中的数据
例如:查询某一个表中的所有数据, 在dao中添加查询所有数据的方法
public static List<Subject> findAll(){ //1.获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 String sql = "select * from subject"; //3.构建sql语句 Statement st = null; try { st = con.createStatement(); //4.执行sql语句 //ResultSet 用来封装查询出的结果集 类似于集合中的iterator迭代器 ResultSet rs = st.executeQuery(sql); List<Subject> subs = new ArrayList<Subject>(); // rs.next()判断结果集中是否有下一个元素,如果有就取出 while(rs.next()){ //创建课程对象 Subject sb = new Subject(); //取出结果中subjectNo,并存入到课程中 // rs.get字段类型(字段名) 获取字段中对应的值 sb.setSubjectNo(rs.getInt("subjectNo")); sb.setSubjectName(rs.getString("subjectName")); sb.setClassHour(rs.getInt("classHour")); sb.setGradeId(rs.getInt("gradeID")); //将封装好的课程对象加入到集合中 subs.add(sb); } //将封装好的课程集合返回 return subs; } catch (SQLException e) { e.printStackTrace(); }finally{ try { st.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } return null; }
(3)execute,executeUpdate,executeQuery的区别
4、修改数据表中的数据
(1)根据subjectNo查询出数据,参考代码如下:
/** *根据subjectNo查询出数据 */ public static Subject findSubjectByNo(int subjectNo){ //1.获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 String sql = "select * from subject where subjectNo="+subjectNo; //3.构建sql语句 Statement st = null; try { st = con.createStatement(); //4.执行sql语句 ResultSet rs = st.executeQuery(sql); //Subject sb = new Subject(); Subject sb = null; while(rs.next()){ sb = new Subject(); sb.setSubjectNo(rs.getInt("subjectNo")); sb.setSubjectName(rs.getString("subjectName")); sb.setClassHour(rs.getInt("classHour")); sb.setGradeId(rs.getInt("gradeID")); } return sb; } catch (SQLException e) { e.printStackTrace(); }finally{ try { st.close(); con.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } return null; }
(2)修改数据的方法
/** * 修改数据 **/ public static void update(Subject sub){ //1.获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 String sql = "update subject set " + " subjectName='"+sub.getSubjectName()+"' ," + " classHour="+sub.getClassHour()+" ," + " gradeID="+sub.getGradeId() + " where subjectNo="+sub.getSubjectNo(); System.out.println(sql); //3.构建sql语句 Statement st = null; try { st = con.createStatement(); st.executeUpdate(sql); } catch (SQLException e) { e.printStackTrace(); }finally{ try { st.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } }
(3)测试方法
//根据subjectNO 修改数据 //1. 根据subjectNO 查询出数据 Subject sub = findSubjectByNo(10); //sub.setSubjectNo(10); //2. 设置想要修改的数据 sub.setSubjectName("如何养生"); update(sub);
5、sql注入:使用拼接字符串的形式,向
public static Master findMasterByNameAndPwd(String name ,String pwd ){ //1.获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 String sql = "select * from master where name='"+name+"' and password='"+pwd+"'"; //3.构建sql语句 Statement st = null; try { st = con.createStatement(); ResultSet rs = st.executeQuery(sql); Master master = null; while(rs.next()){ master = new Master(); master.setId(rs.getInt("id")); master.setName(rs.getString("name")); master.setPassword(rs.getString("password")); master.setMoney(rs.getInt("money")); } return master; } catch (SQLException e) { e.printStackTrace(); } finally { try { st.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } return null; }
注意:Statement 构建sql语句需要用+拼接值,容易造成SQL。
(1)避免sql注入,使用PreparedStatement
概述:预编译的sql语句,继承Statement接口,比Statement更加灵活,效率更高,提高了sql语句的可读性,提高了sql语句的执行性能,提高了安全性
例如:
public static void insert(Dog dog){ //1.获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 // ? 问号,占位符,表示此处需要设置一个值 String sql = "insert into dog (name,health,love,strain) values (?,?,?,?)"; //3.编译sql语句 PreparedStatement pst = null; try { pst = con.prepareStatement(sql); //4.如果sql语句中有? ,就需要给?设置值 //pst.set类型(第几个问号,要设置给?号的值) pst.setString(1, dog.getName()); pst.setInt(2, dog.getHealth()); pst.setInt(3, dog.getLove()); pst.setString(4, dog.getStrain()); //5.执行sql语句 int num = pst.executeUpdate(); if(num!=0){ System.out.println("数据插入成功"); } } catch (SQLException e) { e.printStackTrace(); } }
注意:使用PreparedStatement时在sql语句中需要设置值时,用?,有几个?,就设置几个值
例如:setString(1,name);
表示给第一个?,设置name值
(2)将Statement替换成PrepareStatemen
public static Master findMasterByNameAndPwd(String name ,String pwd ){ //1.获取数据库连接 Connection con = DBUtil.getCon(); //2.编写sql语句 //String sql = "select * from master where name='"+name+"' and password='"+pwd+"'"; String sql = "select * from master where name=? and password=? "; System.out.println(sql); //3.构建sql语句 //Statement st = null; PreparedStatement pst = null; try { //st = con.createStatement(); pst = con.prepareStatement(sql); pst.setString(1, name); pst.setString(2, pwd); //ResultSet rs = st.executeQuery(sql); ResultSet rs = pst.executeQuery(); Master master = null; while(rs.next()){ master = new Master(); } return master; } catch (SQLException e) { e.printStackTrace(); } finally { try { pst.close(); con.close(); } catch (SQLException e) { e.printStackTrace(); } } return null; }
运行结果: