MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement

时间:2020-12-01 11:55:49

这里补一下,java连接到数据库的模板。

有四个步骤:1.加载连接器

                      2.声明连接哪台主机的数据库,同时指定编码

                      3.建立连接

                      4.对数据库中的内容进行操作

DBHelloWorld.java

package cn.hncu;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;

//import com.mysql.jdbc.Driver; Driver类补全即可得到完成类名,用于下面的类反射


public class DBHelloWorld {
public static void main(String[] args) throws Exception {

//1.加载连接器
Class.forName("com.mysql.jdbc.Driver");//驱动

//2.声明连接哪台主机的数据库,同时指定编码
String url="jdbc:mysql://127.0.0.1:3306/abc?useUnicode=true&characterEncoding=utf-8";

//3.建立连接
Connection con= DriverManager .getConnection(url, "hncu", "1234");

//4.对数据库中的内容进行操作
Statement st=con.createStatement();//创建语句对象Statement

String sql="insert into stud values(13,'Eclipse',60,91.2);";//增
//sql="update stud set sname='MyEclipse' where sid=13";改
//sql="delete from stud where sid=13";//删

//boolean boo=st.execute(sql);
//System.out.println(boo);

//查询
sql="select * from stud;";
ResultSet rs=st.executeQuery(sql);
while(rs.next()){//第一个在数据项之上,要移下来一个。表示下一项是不是数据项,若不是则返回false
int id=rs.getInt("sid");
int id2=rs.getInt(1);//两种方法都行,一个用字段名,一个用字段序号(从1开始)
String name=rs.getString(2);
int age=rs.getInt("sage");
double score=rs.getDouble(4);
System.out.println("id="+id+",id2="+id2+",name="+name+",age="+age+",score="+score);
}
}

}

 

为了以后写代码的简洁性,和减少内存开销这里对连接数据库做了工厂类,模仿Hibernate做了配置文件

 

jdbc.properties

 

MySQL
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8
username=hncu
password=1234

##Oracle
#driver=oracle.jdbc.driver.OracleDriver
#url=jdbc:oracle:thin:@127.0.0.1:1521:orcl
#username=scott
#password=tiger


ConnFactory.java

 

package cn.hncu.pubs;

import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.util.Properties;

public class ConnFactory {
private static Connection con;
private ConnFactory(){
}
static{
//为了确保每次拿的connection都一样,采用单例
try {
Properties p=new Properties();//放在src目录下 p.load(ConnFactory.class.getClassLoader().getResourceAsStream("jdbc.properties"));//读取classpath下的资源文件

String driver=p.getProperty("driver");
String url=p.getProperty("url");
String username=p.getProperty("username");
String password=p.getProperty("password");

Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection(url, username, password);

} catch (Exception e) {
e.printStackTrace();
}
}
public static Connection getConn(){
return con;
}

}

 


JdbcDemo.java

 

package cn.hncu;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;
import java.util.UUID;

import org.junit.Test;
import org.junit.runners.ParentRunner;

import cn.hncu.pubs.ConnFactory;

 

public class JdbcDemo {

 //查
 @Test
 public void readDemo(){
  Connection con=null;
  try {
   Class.forName("com.mysql.jdbc.Driver");//驱动----jdbc4.0开始可省略
   //hibernate框架不能省
   
   String url="jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8";//建数据库的时候指定编码,java连接的时候也指定编码,两者一致,只要不是mysql故意改动编码,都不会乱码
   con=DriverManager.getConnection(url,"hncu","1234");
   Statement st=con.createStatement();
   ResultSet rs=st.executeQuery("select * from person2");//该方法专用于查询
   while(rs.next()){
    Object id0=rs.getObject("id");//若不知字段类型是什么,可用Object类型去接
    String id=rs.getString(1);
    
    String name=rs.getString("name");
    String sex=rs.getString(3);
    /*
     * 为考虑兼容性,数据库中男女用字符0或1表示,到java中进行读取时,
     * 再来修补不足,提高了数据库的可移植性,便于以后的开发和维护
     */
    if(sex.equals("1")){
     sex="男";
    }else if(sex.equals("0")){
     sex="女";
    }else{
     sex="不详";
    }
    System.out.println("id0-"+id0+",id-"+id+",name-"+name+",sex-"+sex);
   }
   
  } catch (Exception e) {
   e.printStackTrace();
  }finally{
   if(con!=null){
    try {
     con.close();
    } catch (SQLException e) {
     e.printStackTrace();
    }
   }
  }
 }
 //增
 @Test
 public void saveDemo(){
  try {
   Class.forName("com.mysql.jdbc.Driver");
   String url="jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8";//建数据库的时候指定编码,java连接的时候也指定编码,两者一致,只要不是mysql故意改动编码,都不会乱码
   Connection con=DriverManager.getConnection(url,"hncu","1234");
   Statement st=con.createStatement();
   
   //增
   //String sql="insert into person2 values('P03','王晓明','0')";
//   String id=UUID.randomUUID().toString().replace("-", "");
//   Scanner sc=new Scanner(System.in);
//   System.out.println("请输入姓名:");
//   String name=sc.nextLine();
//   String sql="insert into person2 values('"+id+"','"+name+"','0')";
   
   //改    UPDATE person2 SET NAME=CONCAT(NAME,'x');
   //String sql="update person2 set name=concat(name,'y')";
   
   //删
   String sex="1";
   String sql="delete from person2 where sex='"+sex+"'";
   
   
   int rows=st.executeUpdate(sql);
   System.out.println(rows+"  row(s) affected");
   
   con.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
  
 }
 @Test
 public void saveDemo2(){
  try {
   Class.forName("com.mysql.jdbc.Driver");
   String url="jdbc:mysql://127.0.0.1:3306/hncu?useUnicode=true&characterEncoding=utf-8";//建数据库的时候指定编码,java连接的时候也指定编码,两者一致,只要不是mysql故意改动编码,都不会乱码
   Connection con=DriverManager.getConnection(url,"hncu","1234");
   Statement st=con.createStatement();
   
   //增
   //String sql="insert into person2 values('P03','王晓明','0')";
  String id=UUID.randomUUID().toString().replace("-", "");
   Scanner sc=new Scanner(System.in);
   System.out.println("请输入姓名:");
     String name=sc.nextLine();
     String sql="insert into person2 values('"+id+"','"+name+"','1')";
   
   //改    UPDATE person2 SET NAME=CONCAT(NAME,'x');
   //String sql="update person2 set name=concat(name,'y')";
   MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement
   //删
//   String sex="1";
//   String sql="delete from person2 where sex='"+sex+"'";

MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement
   
   int rows=st.executeUpdate(sql);
   System.out.println(rows+"  row(s) affected");
   
   con.close();
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 /*
  * Statement中的三个方法:
  * execute();select,insert,update,delete都可以。返回值:当select时有ResultSet为true,其它操作没有ResultSet返回为false
  * executeUpdate();专用于select操作的,返回是一个查询结果集(ResultSet对象)
  * executeQuery();专用于insert,update,delete,返回一个int值:影响的行数
  */
 
 /*
  * CREATE TABLE book(
    id INT AUTO_INCREMENT PRIMARY KEY,
    NAME VARCHAR(30),
    price NUMERIC(5,2),
    birth DATETIME
  );
  INSERT INTO book VALUES(1,'MySQL',39.8,'2015-11-04 18:42:30');
  INSERT INTO book VALUES(2,'Oracle',59.8,'2015-11-04 17:45:30');
  INSERT INTO book(NAME,price,birth) VALUES('JavaEE',80.55,'2014-08-03 11:15:10');
  //DROP TABLE book;
 */
 @Test
 public void resultSetDemo(){
  Connection con=ConnFactory.getConn();
  try {
   Statement st=con.createStatement();
   String sql="select * from book";
   ResultSet rs=st.executeQuery(sql);
   while(rs.next()){
    Integer id=rs.getInt(1);
    String name=rs.getString(2);
    Double price=rs.getDouble(3);
    String birth=rs.getDate(4)+" "+rs.getTime(4);//数据库中,birth的类型是DateTime,在java中读取时日期和时间字段是分开读的,从同一个字段用两种方法分别读取日期和时间
    System.out.println(id+","+name+","+price+","+birth);
   }
   
  } catch (SQLException e) {
   e.printStackTrace();
  }finally{
   try {
    con.close();
   } catch (SQLException e) {
    e.printStackTrace();
   }
  }
 }

MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement

 


 //Statement缺陷1:----当用户输入特殊字符,如name为li'ming时会挂掉
 //    解决办法:用SQL转义字符  单引号 ' 或者斜杠 \  加在特殊字符前面----用java遍历用户信息,在特殊字符前面加转义字符
 @Test
 public void reg(){
  Connection con=ConnFactory.getConn();
  Scanner sc=new Scanner(System.in);
  System.out.println("请输入id: ");
  String id=sc.nextLine();
  System.out.println("请输入用户名: ");
  String name=sc.nextLine();
  
  try {
   Statement st=con.createStatement();
   //insert into stud(id,name) values('5','Rose');
   String sql="insert into stud(id,name) values('"+id+"','"+name+"') ";
   System.out.println("sql---->"+sql);
   int rs=st.executeUpdate(sql);
   System.out.println(rs+"  row(s) affected");
   con.close();
   
  } catch (Exception e) {
   e.printStackTrace();
  }
  
  
 }
 //Statement缺陷2:----黑客登录,在输入name时,输:    aa'  or  'a'='a'   就是把那个where字句判断真假给破坏掉
 @Test
 public void login(){
  Connection con=ConnFactory.getConn();
  Scanner sc=new Scanner(System.in);
   System.out.println("请输入id: ");
   String id = sc.nextLine();
   System.out.println("请输入用户名: ");
   String name = sc.nextLine();
   try {
    Statement st = con.createStatement();
    //假定id和name在数据库中存在就代表登录成功
    //insert into stud(id,name) values('5','Rose');
    String sql = "select count(*) from stud where id='" + id
      + "' and name='" + name + "' ";
    System.out.println("sql---->" + sql);
    ResultSet rs = st.executeQuery(sql);
    rs.next();
    int a = rs.getInt(1);
    System.out.println("count值为:"+a);
    if (a <= 0) {
     System.out.println("登录失败!");
     return;
    }
    System.out.println("登录成功!");
    //con.close();

   } catch (Exception e) {
    e.printStackTrace();
   }
  }
 
 //学习PreparedStatement:它是Statement的子类,帮助Statement在执行前先处理用户的信息
 @Test
 public void login2(){
  Connection con=ConnFactory.getConn();
  Scanner sc=new Scanner(System.in);
   System.out.println("请输入id: ");
   String id = sc.nextLine();
   System.out.println("请输入用户名: ");
   String name = sc.nextLine();
   try {
    
    //利用PreparedStatement进行预处理sql语句
    String sql = "select count(*) from stud where id=? and name=? ";//构造sql语句时,在需要插入用户输入的地方用占位符  ?号
    PreparedStatement pst = con.prepareStatement(sql);
    
    //为各个占位符设置参数值
    pst.setString(1, id);//第一个占位符
    pst.setString(2, name);
    
    ResultSet rs = pst.executeQuery();//注意:此处不要带参数(sql)
    rs.next();
    int a = rs.getInt(1);
    System.out.println("count值为:"+a);
    if (a <= 0) {
     System.out.println("登录失败!");
     return;
    }
    System.out.println("登录成功!");
    //con.close();

   } catch (Exception e) {
    e.printStackTrace();
   }
 }
 //学习PreparedStatement
 @Test
 public void reg2(){
  Connection con=ConnFactory.getConn();
  Scanner sc=new Scanner(System.in);
  System.out.println("请输入id: ");
  String id=sc.nextLine();
  System.out.println("请输入用户名: ");
  String name=sc.nextLine();
  
  try {
   //insert into stud(id,name) values('5','Rose');
   String sql="insert into stud(id,name) values(?,?) ";
   PreparedStatement pst=con.prepareStatement(sql);
   pst.setString(1, id);
   pst.setString(2, name);
   
   int rs=pst.executeUpdate();
   System.out.println(rs+"  row(s) affected");
   con.close();
   
  } catch (Exception e) {
   e.printStackTrace();
  }
 }
 
 //综上 ,为考虑系统健壮性,我们以后开发时,如果sql语句需要用用户输入构造时,要用PreparedStatement来实现。如果不需要,即sql语句是写死的,用Statement即可
 
}

 

 

 


Statement缺陷:1.遇到特殊字符挂掉了

 

MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement

 

2.容易被黑掉

我这里的id和name并没有和数据库中的匹配,但是依然登录

MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement

 

用PreparedStatement修补后就可以了

MySQL第六天---Java与数据库的连接(简单的增、删、改、查)Statement缺陷和子类PreparedStatement