MySQL之JDBC
一、JDBC是什么
Java DatabaseConnectivity (java语言连接数据库)
二、JDBC的本质
JDBC是SUN公司制定的一套接口(interface)。
接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。
三、为什么要面向接口编程
解耦合:降低程序的耦合度,提高程序的扩展力。解耦合可以理解为淘宝的两个页面,你在将商品加入订单的时候出现错误,但是不会影响你在主页浏览商品,就是两个模块之间的联系不那么紧密,说明两个模块内聚就高。
四、为什么SUN制定一套JDBC接口
因为每一个数据库产品都有自己独特的实现原理
五、JDBC编程六步
1、注册驱动(告诉Java程序要连接哪个品牌的数据库)
2、获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
3、获取数据库操作对象(专门执行sql语句的对象)
4、执行SQL语句(DQL,DML...)
5、处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
6、释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
六、IDEA编写JDBC连接MySQL
第一种方法:
1.进入mysql官网
2.点击下载downloads
3.点击下载社区版[MySQL Community (GPL) Downloads »]
4.选择jdbc连接器Connector/J
5.选择Archives下载5.1版本的(支持的数据库版本更多)
两个都可以下载,自己选一个
6.解压后拿到一个mysql-connector-java-5.1.49.jar的包
7.在idea创建一个工程,点击file
8.点击Java,选择你解压后的jar包,不要选择带bin的,是二进制的意思。点击ok就行。
第二种方法
先检查jar包位置:在目录里新建一个文件夹 libs,把jar包复制进去
然后右键选择新建文件夹libs转成library
然后就可以写代码啦!
七、jdbc连接mysql程序编写
7.1 第一种注册驱动方式
public class JDBCTest1 { private static Statement stat; private static Connection conn; public static void main(String[] args) { //1.注册驱动 try { DriverManager.registerDriver(new Driver()); //2.获取连接 // DriverManager.getConnection("jdbc:mysql://192.168.137.150:3306?" + // "useUnicode=true&characterEncoding=utf8&useSSL=false","root","123456"); /* url: 统一资源定位系统 * http/https: 通过网络请求去访问网络上的资源 * jdbc:mysql: 是驱动提供的请求头 * 请求的地址: 指定mysql的服务器地址:192.168.254.150 * 端口号: 3306 * useUnicode=true&characterCharset=utf8 */ String url ="jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false"; String user = "root"; String password = "123456"; conn = DriverManager.getConnection(url, user, password); System.out.println("与mysql连接成功"+conn); //获取数据库操作对象 stat = conn.createStatement(); //DQL //ResultSet executeQuery(String sql) //执行给定的SQL语句,该语句返回单个 ResultSet对象。 //DML(数据库操作语言,增删改) //int executeUpdate(String sql) //执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。 // 方法的返回值指的是受影响的行数: Affected rows: 1 int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(50,'教学部','合肥')"); System.out.println(count==1?"数据保存成功":"数据保存失败"); } catch (SQLException e) { e.printStackTrace(); }finally { //释放资源 if (stat!=null){ try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
7.2第二种注册驱动方式
public class JDBCTest2 { public static void main(String[] args) { //注册驱动的第二种方式 //注册驱动底层实际上就是用驱动包中对应的类,而驱动包中的类都是class后缀的编译好的文件 // 要想直接使用编译好的类,使用反射来实现。 // 想一想,反射是如何获取一个类的class文件对象呢?3种方式 // 1、getClass // 2、.class // 3、Class.forName() Connection conn = null; Statement stat = null; try { //加载驱动 Class.forName("com.mysql.jdbc.Driver"); //创建与数据库连接的对象 String url = "jdbc:mysql://192.168.137.150:3306/bigdata19?useUnicode=true&characterEncoding=utf8&useSSL=false"; String user="root"; String password="123456"; conn = DriverManager.getConnection(url, user, password); //获取与操作数据库的对象 stat = conn.createStatement(); //编写sql语句并执行 //增 String sql="insert into dept(deptno,dname,loc) values(60,'行政部','合肥')"; int count2 = stat.executeUpdate(sql); System.out.println(count2==1?"数据增加成功":"数据增加失败"); //改 String sql1 ="update dept set dname='研发部'where deptno=60"; int count3 = stat.executeUpdate(sql1); System.out.println(count3==1?"数据修改成功":"数据修改失败"); //删 String sql2 = "delete from dept where deptno=50"; int count4 = stat.executeUpdate(sql2); System.out.println(count4==1?"数据删除成功":"数据删除失败"); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); }finally{ if (stat!=null){ try { stat.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn!=null){ try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
7.3将连接数据库的所有信息配置到配置文件中
public class JDBCTest3 { /* 使用配置文件将连接数据库的相关参数进行保存,然后在代码中使用 使用jdk自身提供的Properties类来加载配置文件 */ public static void main(String[] args) throws IOException, ClassNotFoundException, SQLException { //使用无参构造方法创建Properties类的对象 Properties prop = new Properties(); //使用字符流读取配置文件 BufferedReader br = new BufferedReader(new FileReader("F:\software\IdeaProjects\bigdata19_mysql\resource\jdbc.properties")); prop.load(br); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String user = prop.getProperty("user"); String password = prop.getProperty("password"); //加载驱动 Class.forName(driver); //获取连接对象 Connection conn = DriverManager.getConnection(url, user, password); //获取数据库操作对象 Statement stat = conn.createStatement(); //执行sql语句 int count = stat.executeUpdate("insert into dept(deptno,dname,loc) values(70,'教学部','合肥')"); System.out.println(count==1?"数据插入成功":"数据插入失败"); //释放资源 if (stat!=null){ stat.close(); } if (conn!=null){ conn.close(); } } }
7.4处理查询
工具类封装
public class MySqlTool { /* 工具类 1.不能让外界实例化(构造方法私有化) 2.方法必须是静态 */ private static Connection conn; private MySqlTool(){} public static Connection init(){ try { Properties prop = new Properties(); //使用字符流读取配置文件 BufferedReader br = new BufferedReader(new FileReader("F:\software\IdeaProjects\bigdata19_mysql\resource\jdbc.properties")); prop.load(br); String driver = prop.getProperty("driver"); String url = prop.getProperty("url"); String user = prop.getProperty("user"); String password = prop.getProperty("password"); //加载驱动 Class.forName(driver); //获取连接对象 conn = DriverManager.getConnection(url, user, password); }catch (Exception e){ e.printStackTrace(); } return conn; } }
public class JDBCTest4 { public static void main(String[] args) throws SQLException { //通过工具类获取数据库连接对象 Connection conn = MySqlTool.init(); //获取数据库操作对象 Statement stat = conn.createStatement(); //执行sql语句 ResultSet result = stat.executeQuery("select deptno,dname,loc from dept"); //处理查询结果集 boolean b = result.next(); //将光标从当前位置向前移动一行。 //如果光标移动的位置有值,这里的返回值是true // if (b){ // //获取一行中每一列的数值,第一种方式 // String deptno = result.getString(1); // String dname = result.getString(2); // String loc = result.getString(3); // System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); // // } //正常情况下,一张结果表的行数我们不确定,但是我们知道,当next的结果是false的时候,表示读取到末尾 while(result.next()){ //获取一行中每一列的数值,第一种方式 // String deptno = result.getString(1); // String dname = result.getString(2); // String loc = result.getString(3); // System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); //第二种方式,根据列名获取对应的列值 //注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名 String deptno = result.getString("deptno"); String dname = result.getString("dname"); String loc = result.getString("loc"); System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); } //注意事项2:同一个结果resultSet对象,只能遍历一次 System.out.println("========================="); //再次遍历,结果不显示 while(result.next()){ //获取一行中每一列的数值,第一种方式 // String deptno = result.getString(1); // String dname = result.getString(2); // String loc = result.getString(3); // System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); //第二种方式,根据列名获取对应的列值 //注意事项:当查询sql语句中存在起别名的情况时,通过列名获取列值的时候,使用名字是别名 String deptno = result.getString("deptno"); String dname = result.getString("dname"); String loc = result.getString("loc"); System.out.println("部门编号:"+deptno+",部门名称:"+dname+",部门地址:"+loc); } //释放资源 if (stat!=null){ stat.close(); } if (conn!=null){ conn.close(); } } }
7.5登录注册案例
public class JDBCTest5 { public static void main(String[] args) throws SQLException { /* 使用jdbc模拟登录注册案例 1、注册账号:往数据库插入一条数据 2、登录账号:查询数据库 */ //1.建表user //创建键盘录入对象 System.out.println("欢迎来到提瓦特大陆,准备好开始冒险了吗?"); Scanner scanner = new Scanner(System.in); System.out.println("请输入旅行者的名字:"); String username = scanner.next(); System.out.println("请输入密码:"); String password = scanner.next(); //创建数据库驱动 // try { // DriverManager.registerDriver(new Driver()); // } catch (SQLException e) { // e.printStackTrace(); // } // // Connection conn = DriverManager.getConnection(); //直接采用工具类获取与数据库的连接对象 Connection conn = MySqlTool.init(); //获取数据库操作对象 Statement stat = conn.createStatement(); //编写sql语句 String sql= "select username,password from user where username='"+username+"'and password='"+password+"'"; //执行sql语句 ResultSet rs = stat.executeQuery(sql); //处理查询结果集 boolean b = rs.next(); if (b){ System.out.println("旅行者"+username+",欢迎来到提瓦特大陆!"); }else{ System.out.println("您还未注册成为旅行者,是否注册(Y/N)"); String choice = scanner.next(); if ("Y".equals(choice)){ while (true){ System.out.println("请输入旅行者的名字:"); String new_username = scanner.next(); System.out.println("请输入密码:"); String new_password = scanner.next(); System.out.println("请确认密码:"); String again_password = scanner.next(); if (again_password.equals(new_password)) { UUID uuid = UUID.randomUUID();//随机生成uuid String new_uuid = uuid + "-" + System.currentTimeMillis(); String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')"; int count = stat.executeUpdate(sql2); if (count == 1) { System.out.println("注册成功"); } else { System.out.println("注册失败"); } break; }else { System.out.println("两次密码输入不一致,请重新输入:"); } } } } stat.close(); conn.close(); } }
7.6解决sql注入问题
public class JDBCTest6 { public static void main(String[] args) throws SQLException { /* 我们写完程序后发现,当我们将密码输入成1234' or '1'='1这个样子的时候,发现登录成功 原因:sql在编译的时候,会将我们输入的内容存在关键字or,会把or当作sql语法关键字进行执行 如何解决呢? 这样的问题,称之为sql注入的问题 解决的思路就是在sql编译完后再传入数据 获取数据库操作对象另外一种方式,预编译的方式 */ /* 使用jdbc模拟登录注册案例 1、注册账号:往数据库插入一条数据 2、登录账号:查询数据库 */ //1.建表user //创建键盘录入对象 System.out.println("欢迎来到提瓦特大陆,准备好开始冒险了吗?"); Scanner scanner = new Scanner(System.in); System.out.println("请输入旅行者的名字:"); String username = scanner.nextLine(); System.out.println("请输入密码:"); String password = scanner.nextLine(); //创建数据库驱动 // try { // DriverManager.registerDriver(new Driver()); // } catch (SQLException e) { // e.printStackTrace(); // } // // Connection conn = DriverManager.getConnection(); //直接采用工具类获取与数据库的连接对象 Connection conn = MySqlTool.init(); // //获取数据库操作对象 // Statement stat = conn.createStatement(); // // //编写sql语句 // String sql= "select username,password from user where username='"+username+"'and password='"+password+"'"; // //执行sql语句 // ResultSet rs = stat.executeQuery(sql); //这里的问号相当于一个占位符,为了后面传值 String sql = "select username,password from user where username=? and password=?"; //创建预编译数据库操作对象 PreparedStatement pps = conn.prepareStatement(sql); //将sql中的占位符附上值 //第一个参数表示给第几个问号传值,第二个参数表示具体的值,序号从1开始 pps.setString(1,username); pps.setString(2,password); //执行sql语句 ResultSet rs = pps.executeQuery(); //处理查询结果集 boolean b = rs.next(); if (b){ System.out.println("旅行者"+username+",欢迎来到提瓦特大陆!"); }else{ System.out.println("您还未注册成为旅行者,是否注册(Y/N)"); String choice = scanner.next(); if ("Y".equals(choice)){ while (true){ System.out.println("请输入旅行者的名字:"); String new_username = scanner.next(); System.out.println("请输入密码:"); String new_password = scanner.next(); System.out.println("请确认密码:"); String again_password = scanner.next(); if (again_password.equals(new_password)) { UUID uuid = UUID.randomUUID();//随机生成uuid String new_uuid = uuid + "-" + System.currentTimeMillis(); String sql2 = "insert into user(uid,username,password) values('" + new_uuid + "','" + new_username +"','"+ new_password +"')"; int count = pps.executeUpdate(sql2); if (count == 1) { System.out.println("注册成功"); } else { System.out.println("注册失败"); } break; }else { System.out.println("两次密码输入不一致,请重新输入:"); } } } } pps.close(); conn.close(); } }
7.7JDBC实现模糊查询
public class JDBCTest7 { public static void main(String[] args) throws SQLException { //获取数据库连接对象 Connection conn = MySqlTool.init(); //获取预编译数据库操作对象 String sql="select uid,username,password from user where username like ?"; PreparedStatement pps = conn.prepareStatement(sql); pps.setString(1,"%bfy%"); //执行sql语句 ResultSet rs = pps.executeQuery(); //处理查询结果集 while (rs.next()){ String uid=rs.getString(1); String username=rs.getString(2); String password=rs.getString(3); System.out.println(uid+','+username+','+password); } pps.close(); conn.close(); } }