• JDBC的基本用法


        JDBC(Java Database Connection)是Java提供的数据库连接标准,具体的标准实现由各个数据库厂商提供。

        下面以MySQL为例来简单演示JDBC接口的基本用法。

         JDBC连接数据库的基本步骤如下:

         1.加载要连接的数据库驱动,运用了反射机制。

            加载MySQL驱动的代码为:Class.forName("com.mysql.jdbc.Driver");

         2.通过DriverManager来获取与要连接的数据库的一个连接。

            代码格式为:DriverManager.getConnection(c, "root", "1234");

            其中字符串c为"jdbc:mysql://localhost:3306/databaseName?useUnicode=true&characterEncoding=utf8";

            后面的字符串指定有可能对解决中文乱码问题有帮助,如果数据库默认编码支持中文也可以不设置。

         以上两个步骤完成后就完成了数据库的连接,如果想要进一步对数据库操作,要根据不同的应用情景来实现。

         1)通过Statement来获取并执行SQL语句。

              缺点:容易造成SQL注入,对数据库造成安全隐患。但是在执行SQL批处理时可以很方便的使用。

              下面代码可以体现其用法。

         

    package com.wxisme.jdbc01;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    /**
     * 连接MySQL基本流程
     * @author wxisme
     *
     */
    public class Demo02 {
    
    	public static void main(String[] args) {
    		Connection con = null;
    		Statement stmt = null;
    		ResultSet rs = null;
    		try {
    			//先加载数据库驱动
    			Class.forName("com.mysql.jdbc.Driver");
    			//通过驱动管理来建立连接
    			String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
    			con = DriverManager.getConnection(c, "root", "1234");
    			//创建statement  
    			String sql = "select * from student where b='张三'";
    			stmt = con.createStatement();
    			//创建结果集  不能预编译SQL  只能在执行时传入SQL
    			rs = stmt.executeQuery(sql);
    			//next()指针指向下一条记录,如果有返回true,否则返回false
    			while(rs.next()) {
    				for(int i=1; i<10; i++) {
    					//getString()可以传入字段名,也可以传入字段的Index
    					System.out.print(rs.getString(i)+"    ");
    				}
    				System.out.println();
    			}
    			
    		} catch (ClassNotFoundException | SQLException e) {
    			e.printStackTrace();
    		}finally {
    			
    			try {
    				con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    				
    			try {
    				stmt.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
                try {
    				rs.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    
    }
    

         2)通过prepareStatement预编译SQL,防止SQL注入。

              优点:可以防止SQL注入并预编译SQL可以提高效率,可以使用?占位符,写SQL语句时不用拼字符串,不容易出错。但是在批量处理时不方便使用。

             

    public class Demo01 {
    
    	public static void main(String[] args) {
    		Connection con = null;
    		PreparedStatement stmt = null;
    		ResultSet rs = null;
    		try {
    			//先加载数据库驱动
    			Class.forName("com.mysql.jdbc.Driver");
    			//通过驱动管理来建立连接
    			String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
    			con = DriverManager.getConnection(c, "root", "1234");
    			//创建statement  
    			String sql = "select * from student where b=?";
    			stmt = con.prepareStatement(sql);
    			
    			stmt.setString(1, "张三");
    			
    			//创建结果集
    			rs = stmt.executeQuery();
    			
    			while(rs.next()) {
    				for(int i=1; i<10; i++) {
    					System.out.print(rs.getString(i)+"    ");
    				}
    				System.out.println();
    			}
    			
    		} catch (ClassNotFoundException | SQLException e) {
    			e.printStackTrace();
    		}finally {
    			
    			try {
    				con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    				
    			try {
    				stmt.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
                try {
    				rs.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    
    }
    

         3)使用批处理一次提交执行批量SQL语句。

          

    public class Demo03 {
    
    	public static void main(String[] args) {
    		Connection con = null;
    		Statement stmt = null;
    		try {
    			//先加载数据库驱动
    			Class.forName("com.mysql.jdbc.Driver");
    			//通过驱动管理来建立连接
    			String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
    			con = DriverManager.getConnection(c, "root", "1234");
    			con.setAutoCommit(false);//将连接的事务设为手动提交
    			//创建statement  
    			stmt = con.createStatement();
    			for(int i=0; i<900000; i++) {
    				String sql = "insert into student (a,b,c) values('中文','刘琦','2013010')";
    				stmt.addBatch(sql);
    			}
    			stmt.executeBatch();
    			con.commit();//提交事务
    		} catch (ClassNotFoundException | SQLException e) {
    			e.printStackTrace();
    		}finally {
    			
    			try {
    				con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    				
    			try {
    				stmt.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    		
    	}
    
    }
    

        4)数据库事务的提交和回滚,在默认情况下,数据库事务是自动提交的,但是如果手动提交,在最后调用数据库连接的回滚方法,在一个SQL语句有了错误抛出异常后,其他的SQL语句都不再执行,已经执行的SQL语句回滚到以前的状态,就是如果有异常抛出则数据库中的数据不会发生变化。

           

    package com.wxisme.jdbc01;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.PreparedStatement;
    /**
     * 事务的手动提交和回滚
     * @author wxisme
     *
     */
    public class Demo04 {
    
    	public static void main(String[] args) {
    		Connection con = null;
    		PreparedStatement stmt = null;
    		
    		try {
    			//先加载数据库驱动
    			Class.forName("com.mysql.jdbc.Driver");
    			//通过驱动管理来建立连接
    			String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
    			con = DriverManager.getConnection(c, "root", "1234");
    			//创建statement  
    			con.setAutoCommit(false);//设置为手动提交事务
    			String sql = "insert into student (?) values(?)";
    			stmt = con.prepareStatement(sql);
    			
    			stmt.setString(1, "a");
    			stmt.setString(2, "刘琦");
    			con.commit();//手动提交事务
    			
    		} catch (ClassNotFoundException | SQLException e) {
    			e.printStackTrace();
    			try {
    				con.rollback();//如果出现异常则回滚事务
    			} catch (SQLException e1) {
    				e1.printStackTrace();
    			}
    		}finally {
    			
    			try {
    				con.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    				
    			try {
    				stmt.close();
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
               
    		}
    		
    	}
    
    }
    

         5)对日期的支持,在java.sql包中有Date,Time,Timestamp类来支持时间和日期的处理。

            

    package com.wxisme.jdbc01;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.sql.Timestamp;
    import java.util.Random;
    
    
    /**
     * 时间处理java.sql.Date,Time,Timestamp
     * 插入带有日期和时间戳类型字段的记录
     * @author wxisme
     *
     */
    public class Demo05 {
    	public static void main(String[] args) {
    		Connection conn = null;
    		PreparedStatement ps = null;
    		try {
    			//加载驱动类
    			Class.forName("com.mysql.jdbc.Driver");
    			String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
    			conn = DriverManager.getConnection(c, "root", "1234");
    			
    			for(int i=0;i<1000;i++){
    				
    				ps = conn.prepareStatement("insert into student (name,pswd,time,stime) values (?,?,?,?)");
    				ps.setObject(1, "流苏款"+i);
    				ps.setObject(2, "123456");
    
    				int rand =  100000000+new Random().nextInt(1000000000);
    				
    				java.sql.Date date = new java.sql.Date(System.currentTimeMillis()-rand);
    				Timestamp stamp = new Timestamp(System.currentTimeMillis()-rand);  //如果需要插入指定日期,可以使用Calendar、DateFormat
    				
    				ps.setDate(3, date);
    				ps.setTimestamp(4, stamp);
    				ps.execute();
    				
    			}
    			
    			
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}finally{
    			try {
    				if(ps!=null){
    					ps.close();
    				}
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			try {
    				if(conn!=null){
    					conn.close();
    				}
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    
    package com.wxisme.jdbc01;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Timestamp;
    import java.text.DateFormat;
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    
    
    /**
     * 时间处理java.sql.Date,Time,Timestamp
     * 查找某个时间段的记录
     * @author wxisme
     *
     */
    
    public class Demo06 {
    	
    	/**
    	 * 将字符串代表的日期转为long数字(格式:yyyy-MM-dd hh:mm:ss)
    	 * @param dateStr
    	 * @return
    	 */
    	public static long str2Date(String date) {
    		DateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
    		try {
    			return format.parse(date).getTime();
    		} catch (ParseException e) {
    			e.printStackTrace();
    			return 0;
    		}
    	}
    	
    	
    	public static void main(String[] args) {
    		Connection conn = null;
    		PreparedStatement ps = null;
    		ResultSet rs = null;
    		try {
    			//加载驱动类
    			Class.forName("com.mysql.jdbc.Driver");
    			String c = "jdbc:mysql://localhost:3306/student?useUnicode=true&characterEncoding=utf8";
    			conn = DriverManager.getConnection(c, "root", "1234");
    			
    			ps = conn.prepareStatement("select * from student where stime>? and stime<?  order by stime ");
    			Timestamp start = new Timestamp(str2Date("2015-5-1 8:10:20"));
    			Timestamp end = new Timestamp(str2Date("2015-5-1  9:9:10"));
    			ps.setObject(1, start);
    			ps.setObject(2, end);
    			rs = ps.executeQuery();
    			while(rs.next()){
    				System.out.println(rs.getString("name")+"--"+rs.getTime("time")+"--"+rs.getTimestamp("stime"));
    			}
    			
    			
    			
    		} catch (ClassNotFoundException e) {
    			e.printStackTrace();
    		} catch (SQLException e) {
    			e.printStackTrace();
    		}finally{
    			try {
    				if(ps!=null){
    					ps.close();
    				}
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    			try {
    				if(conn!=null){
    					conn.close();
    				}
    			} catch (SQLException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

     总结:JDBC把数据库连接封装的很好,总的步骤是固定的,写几个Demo之后就熟悉了,但是在数据库连接时要注意很多细节问题,代码写的严谨才不会出BUG。

  • 相关阅读:
    对Java课程的感想
    OO第二阶段总结
    OO第一作业周期(前四周)总结
    实验7 流类库和输入输出
    实验6 类的继承和多态
    实验5 类和对象3
    实验4 类与对象2
    实验3 类和对象
    实验2
    实验1
  • 原文地址:https://www.cnblogs.com/wxisme/p/4502210.html
Copyright © 2020-2023  润新知