zoukankan      html  css  js  c++  java
  • JDBC

    使用JDBC连接Oracle

    1) 导包,导入JDBC驱动

    com.oracle下的ojdbc14,可以从http://mvnrepository.com 下载jar

    clip_image002

    导包:右击项目àBuild PathàConfigure Build PathàLibrariesàAdd External JARsà选择下载的jar包àApplyàOK

    clip_image004

    2) 注册JDBC驱动

    -参数:“驱动程序类名”

    -Class.forName(“驱动程序类名”)

    3) 创建连接,获得Connection对象

    -需要3个参数:url,username,password

    -连接到数据库

    4) 创建Statement(语句)对象

    -conn.getStatement()方法创建对象,用于执行SQL语句

    -execute(sql):执行SQL,常用于执行DDL,DCL

    -executeUpdate(sql):执行DML语句,如insert、update、delete

    -executeQuery(sql):执行DQL语句,如select

    5) 处理SQL结果集

    -execute(ddl):如果没有异常则成功

    -executeUpdate(dml):返回数字,表示更新”行”数量,抛出异常则失败

    -executeQuery(dql):返回ResultSet(结果集)对象,代表2维查询结果

    6) 关闭数据库连接

    -conn.close()

    演示:JDBC连接数据库

    //1.注册驱动,告诉DriverManager用这个类

    Class.forName("oracle.jdbc.OracleDriver");

    //2.创建连接

    String url = "jdbc:oracle:thin:@10.1.1.100:1521:orcl";

    String user = "scott";

    String password = "tiger";

    Connection conn = DriverManager.getConnection(url, user, password);

    //输出conn引用对象的实际类型,证明:驱动程序提供了Connection接口的实现类

    System.out.println(conn.getClass());

    //3.创建Statement(语句)对象

    Statement smt = conn.createStatement();

    //4.执行sql,获取结果集

    String sql = "SELECT * FROM emp WHERE ename='SMITH' ";

    ResultSet rs = smt.executeQuery(sql);

    //5.处理结果集

    while(rs.next()){

    System.out.println(rs.getInt("empno")+

    rs.getString("ename"));

    }

    //6.关闭数据库

    conn.close();

    演示:使用工具类获取连接

    创建一个工具类,获取访问数据库的操作。将数据库配置写在一个properties属性文件里,工具类读取属性文件,逐行获取数据库参数。

    1.创建db.properties

    注意:properties属性文件里不要使用中文

    src/main/resourcesàdb.properties

    clip_image006

    2.创建工具类,src/main/java/util/DBTool.java

    package util;

    import java.io.IOException;

    import java.sql.Connection;

    import java.sql.DriverManager;

    import java.sql.SQLException;

    import java.util.Properties;

    public class DBTool {

    private static String url;

    private static String user;

    private static String pwd;

    static{

    try {

    //1.创建Properties对象

    Properties p = new Properties();

    //2.加载配置文件

    p.load(DBTool.class.getClassLoader().getResourceAsStream("db.properties"));

    String driver = p.getProperty("jdbc.driver");

    url = p.getProperty("url");

    user = p.getProperty("user");

    pwd = p.getProperty("password");

    //3.注册驱动

    Class.forName(driver);

    } catch (IOException e) {

    //4.异常处理

    /*

    * 异常处理原则:

    * 1.记录日志

    * 2.能处理则处理,具体参考开发规范

    * 3.不能处理则抛出

    */

    e.printStackTrace();

    throw new RuntimeException("加载db.properties失败!,e");

    } catch (ClassNotFoundException e) {

    e.printStackTrace();

    throw new RuntimeException("找不到驱动类",e);

    }

    }

    //4.创建连接方法

    public static Connection getConnection() throws SQLException{

    return DriverManager.getConnection(url,user,pwd);

    }

    //5.创建关闭连接方法

    public static void close(Connection conn){

    try {

    if(conn != null){

    conn.close();

    }

    } catch (SQLException e) {

    e.printStackTrace();

    throw new RuntimeException("关闭连接失败!,e");

    }

    }

    }

    3.创建测试类,进行测试,src/test/java/test/TestCase.java

    package test;

    import java.io.IOException;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    import java.sql.Statement;

    import java.util.Properties;

    import org.junit.Test;

    import util.DBTool;

    public class TestCase {

    /**

    * 1.JUnit可以让类中每个方法单独执行

    * 2.对方法的要求:

    * -方法是共有的

    * -没有返回值

    * -没有参数

    * -前面必须写@Test注解

    * 3.JUnit用来测试,而测试代码在正式WEB项目里不需要,

    * 会连同JUnit包一起丢弃,所以JUnit包不用maven导入也可。

    */

    /**

    * 使用Properties读取db.properties

    * 1.此类本质上是Map

    * 2.专门用来读取properties文件

    */

    @Test

    public void test1(){

    Connection conn = null;

    Properties p = new Properties();

    //获取ClassLoader并通过它从classes下读取db.properties

    try {

    p.load(TestCase.class.getClassLoader().getResourceAsStream("db.properties"));

    System.out.println(p.getProperty("jdbc.driver"));

    System.out.println(p.getProperty("url"));

    System.out.println(p.get("user"));

    System.out.println(p.getProperty("password"));

    } catch (IOException e) {

    e.printStackTrace();

    }

    }

    /**

    * 测试DBTool工具类

    */

    @Test

    public void test2(){

    Connection conn = null;

    try {

    conn = DBTool.getConnection();

    System.out.println(conn.getClass());

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBTool.close(conn);

    }

    }

    /**

    * 执行DDL语句

    */

    @Test

    public void test3(){

    //创建连接

    Connection conn = null;

    try {

    conn = DBTool.getConnection();

    //创建Statement对象

    Statement smt = conn.createStatement();

    //执行sql

    String sql = "CREATE TABLE testtab("

    + "id NUMBER(8),"

    + "name VARCHAR2(50),"

    + "salary NUMBER(8,2) )";

    boolean b = smt.execute(sql);

    /*

    * 返回结果:

    * false:表示没有结果集

    * true:表示有结果集

    * 创建失败则抛出异常

    */

    System.out.println(b); //false

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBTool.close(conn);

    }

    }

    /**

    * 执行DML语句

    */

    @Test

    public void test4(){

    //创建连接

    Connection conn = null;

    try {

    conn = DBTool.getConnection();

    //创建Statement对象

    Statement smt = conn.createStatement();

    String sql = "INSERT INTO testtab VALUES("

    + "2,'Jerry',2000.5)";

    //返回DML语句影响的行数

    int rows = smt.executeUpdate(sql);

    System.out.println(rows);

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBTool.close(conn);

    }

    }

    /**

    * 执行DQL语句

    */

    @Test

    public void test5(){

    //创建连接

    Connection conn = null;

    try {

    conn = DBTool.getConnection();

    //创建Statement对象

    Statement smt = conn.createStatement();

    //执行sql

    String sql = "SELECT * FROM testtab";

    /*

    * 返回结果集ResultSet,里面封装了多行多列的数据

    * 该对象采用了迭代器模式,通常用while进行遍历

    */

    ResultSet rs = smt.executeQuery(sql);

    while(rs.next()){

    /*

    * 游标默认处于第一行之前

    * 每次遍历就可以从rs获取下一行数据

    * rs.get类型(字段名)

    * rs.get类型(字段序号)

    */

    System.out.println(rs.getInt("id")+","+rs.getString("name")+","+rs.getDouble("salary"));

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBTool.close(conn);

    }

    }

    }

    使用Apache DBCP连接池连接数据库

    1) 导包:需要两个jar包

    -commons-dbcp-1.4.jar:连接池的实现

    -commons-pool-1.5.jar:连接池实现的依赖库

    http://maven.aliyun.com搜索:dbcp

    clip_image008

    复制坐标代码到pom.xml后保存

    clip_image010

    maven自动添加了两个jar包

    clip_image012

    2) 配置db.properties属性文件,添加初始连接数和最大连接数(可选)

    clip_image014

    3) 通过Properties读取db.properties属性文件

    Properties p = new Properties();

    p.load(DBUtil.class.getClassLoader().getResourceAsStream("db.properties"));

    String driver = p.getProperty("jdbc.driver");

    String url = p.getProperty("url");

    String user = p.getProperty("user");

    String pwd = p.getProperty("password");

    String initsize = p.getProperty("initsize");

    String maxsize = p.getProperty("maxsize");

    4) 创建连接池

    BasicDataSource ds = new BasicDataSource();

    5) 设置连接池参数

    ds.setDriverClassName(driver);

    ds.setUrl(url);

    ds.setUsername(user);

    ds.setPassword(pwd);

    ds.setInitialSize(Integer.parseInt(initsize));

    ds.setMaxActive(Integer.parseInt(maxsize));

    6) 创建数据库连接

    Connection conn = ds.getConnection();

    演示:通过连接池连接数据库

    1.创建工具类utilàDBUtil

    package util;

    import java.io.IOException;

    import java.sql.Connection;

    import java.sql.SQLException;

    import java.util.Properties;

    import org.apache.commons.dbcp.BasicDataSource;

    public class DBUtil {

    private static BasicDataSource ds;

    static{

    //加载参数

    Properties p = new Properties();

    try {

    p.load(DBUtil.class.getClassLoader().getResourceAsStream("db.properties"));

    String driver = p.getProperty("jdbc.driver");

    String url = p.getProperty("url");

    String user = p.getProperty("user");

    String pwd = p.getProperty("password");

    String initsize = p.getProperty("initsize");

    String maxsize = p.getProperty("maxsize");

    //创建连接池

    ds = new BasicDataSource();

    //设置参数

    ds.setDriverClassName(driver);

    ds.setUrl(url);

    ds.setUsername(user);

    ds.setPassword(pwd);

    ds.setInitialSize(Integer.parseInt(initsize));

    ds.setMaxActive(Integer.parseInt(maxsize));

    } catch (IOException e) {

    e.printStackTrace();

    throw new RuntimeException("加载db.properties失败!",e);

    }

    }

    //创建连接方法

    public static Connection getConnection() throws SQLException{

    return ds.getConnection();

    }

    /**

    * 目前连接是由连接池创建的,连接的实现类是由连接池提供的,

    * 连接池将连接对象的close方法改为归还连接的逻辑。

    */

    public static void close(Connection conn){

    try {

    if(conn != null){

    conn.close(); //归还连接到数据库连接池

    }

    } catch (SQLException e) {

    e.printStackTrace();

    throw new RuntimeException("关闭连接失败!",e);

    }

    }

    }

    2.添加测试类进行测试

    package test;

    import java.sql.Connection;

    import java.sql.PreparedStatement;

    import java.sql.ResultSet;

    import java.sql.ResultSetMetaData;

    import java.sql.SQLException;

    import java.sql.Statement;

    import org.junit.Test;

    import util.DBUtil;

    public class TestCase2 {

    /**

    * 测试DBUtil

    */

    @Test

    public void test1(){

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    System.out.println(conn);

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 使用DBUtil创建连接,并执行一个update语句

    */

    @Test

    public void test2(){

    int id = 2;

    String name = "Andy";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    Statement smt = conn.createStatement();

    String sql = "UPDATE testtab SET "

    + "name='"+name+"'WHERE id="+id;

    int rows = smt.executeUpdate(sql);

    System.out.println(rows);

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 使用PreparedStatement执行DML语句

    */

    @Test

    public void test3(){

    //删除name=Andy的行

    String name = "Andy";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    String sql = "DELETE FROM testtab "

    + "WHERE name=?";

    PreparedStatement ps = conn.prepareStatement(sql);

    /*

    * 给?赋值,将值暂存到PS里,由PS一次性发送给数据库

    * ps.set类型(?的序号,?的值),序号从1开始

    */

    ps.setString(1, name);

    //发送?的值,让数据库执行计划

    ps.executeUpdate();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    /**

    * 使用PS执行DQL语句

    */

    @Test

    public void test4(){

    //查询name=TOM的数据

    String name = "TOM";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    String sql = "SELECT * FROM testtab "

    + "WHERE name=?";

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, name);

    ResultSet rs = ps.executeQuery();

    while(rs.next()){

    System.out.println(rs.getInt("id")+","+rs.getString("name")+","+rs.getDouble("salary"));

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 使用PS执行查询,模拟登陆,

    * 测试传入不正经密码时,会不会登陆成功

    * 以此证明PS能防止SQL注入攻击

    * 数据库中插入如下表做验证:

    * CREATE TABLE logincheck(

    name VARCHAR2(50),

    password VARCHAR2(50)

    );

    INSERT INTO logincheck VALUES('zhangsan','a');

    COMMIT;

    */

    @Test

    public void test5(){

    //假设传入账号密码如下:

    String name = "zhangsan";

    String password = "a' OR 'b'='b";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    String sql = "SELECT * FROM logincheck "

    + "WHERE name=?"

    + "AND password=?";

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, name);

    ps.setString(2, password);

    ResultSet rs = ps.executeQuery();

    //因为只有一行数据,所以rs.next()一次即可,存在说明登陆成功

    if(rs.next()){

    System.out.println("登陆成功!");

    }else{

    System.out.println("登陆失败!");

    }

    //登陆失败!

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 同样的,测试使用Statement传入以上sql查看执行结果

    * 以此证明Statement不能防止sql注入攻击

    */

    @Test

    public void test6(){

    String name = "zhangsan";

    String password = "a' OR 'b'='b";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    String sql = "SELECT * FROM logincheck "

    + "WHERE name='"+name+"'AND password ='"+password+"'";

    Statement smt = conn.createStatement();

    ResultSet rs = smt.executeQuery(sql);

    if(rs.next()){

    System.out.println("登陆成功!");

    }else{

    System.out.println("登陆失败!");

    }

    //登陆成功!

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    /**

    * ResultSetMetaData

    */

    @Test

    public void test7(){

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    String sql = "SELECT * FROM logincheck";

    Statement smt = conn.createStatement();

    ResultSet rs = smt.executeQuery(sql);

    //获取结果集元数据

    ResultSetMetaData rsm = rs.getMetaData();

    System.out.println(rsm.getColumnCount()); //2

    System.out.println(rsm.getColumnName(1)); //NAME

    System.out.println(rsm.getColumnTypeName(1)); //VARCHAR2

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 模拟实现转账的业务:

    * 假设:当前用户已经登陆了网银,并且输入了收款方的账号

    * 以及转账的金额,点击开始转账。

    *

    * 转账的步骤:

    * 1.查询付款方账号,看余额够不够

    * 2.查询收款方账号,是否正确

    * 3.修改付款方账号余额-N元

    * 4.修改收款方账号余额+N元

    *

    * 注意:转账是一个完整的业务,要保证在一个事务之内

    * 所以只创建一个连接

    *

    * 在数据库中添加表

    *create table accounts (

    id varchar2(20),

    name varchar2(30),

    money number(11,2)

    );

    insert into accounts values('00001','张三',9000.0);

    insert into accounts values('00002','李四',4000.0);

    commit;

    */

    @Test

    public void test8(){

    //假设付款方为李四,收款方为张三,转账金额为1000

    String payID = "00002";

    String recID = "00001";

    double mny = 1000;

    //建立数据库连接

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    //执行sql查询余额是否足够

    String sql = "SELECT * FROM accounts WHERE id=?";

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, payID);

    ResultSet rs = ps.executeQuery();

    Double payMny = null;

    while(rs.next()){

    payMny = rs.getDouble("money");

    //打桩

    System.out.println("付款方支付前余额"+payMny);

    }

    if(payMny<mny){

    System.out.println("余额不足!");

    return;

    }

    //查询收款账号是否存在

    sql = "SELECT * FROM accounts WHERE id=?";

    ps.setString(1, recID);

    rs = ps.executeQuery();

    if(!rs.next()){

    System.out.println("收款方账号不存在");

    return;

    }

    double recMny = rs.getDouble("money");

    System.out.println("收款方收款前余额"+recMny);

    //修改付款方账户余额

    sql = "UPDATE accounts SET money=? "

    + "WHERE id=?";

    ps = conn.prepareStatement(sql);

    ps.setDouble(1, payMny-mny);

    ps.setString(2, payID);

    ps.executeUpdate();

    /*

    int x = Integer.parseInt("df");

    try {

    if(x != 5){

    throw new Exception("模拟错误");

    }

    } catch (Exception e) {

    e.printStackTrace();

    }

    程序有bug,这样的情况,会出现支付方钱扣了,但是收款方钱没增加的情况。

    */

    //修改收款方账户余额

    sql = "UPDATE accounts SET money=? "

    + "WHERE id=?";

    ps = conn.prepareStatement(sql);

    ps.setDouble(1, recMny+mny);

    ps.setString(2, recID);

    ps.executeUpdate();

    //查询最后表数据

    sql = "SELECT * FROM accounts";

    ps = conn.prepareStatement(sql);

    rs = ps.executeQuery();

    while(rs.next()){

    System.out.println(rs.getString("id")+","+rs.getString("name")+","+rs.getDouble("money"));

    }

    } catch (SQLException e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    }

    演示:连接池线程处理

    package util;

    import java.sql.Connection;

    import java.sql.ResultSet;

    import java.sql.Statement;

    /**

    * 用于测试数据库连接池的测试

    * 连接池初始创建1个连接,最大2个连接

    * 创建3个线程调用数据库连接,观察连接池工作原理

    */

    public class DBCPThread {

    public static void main(String[] args){

    Thread t1 = new DemoThread(5000);

    Thread t2 = new DemoThread(6000);

    Thread t3 = new DemoThread(1000);

    t1.start();

    t2.start();

    t3.start();

    }

    }

    class DemoThread extends Thread{

    private int wait;

    public DemoThread(int wait) {

    this.wait = wait;

    }

    @Override

    public void run() {

    Connection conn = null;

    try{

    conn = DBUtil.getConnection();

    System.out.println("获取了数据库连接"+wait);

    String sql = "SELECT 'dbcp' AS a FROM dual";

    Statement st = conn.createStatement();

    ResultSet rs = st.executeQuery(sql);

    while(rs.next()){

    System.out.println(rs.getString("a")+wait);

    }

    Thread.sleep(wait);

    System.out.println("连接结束了"+wait);

    }catch(Exception e){

    e.printStackTrace();;

    }finally{

    DBUtil.close(conn);

    }

    }

    }

    运行结果:

    获取了数据库连接5000

    获取了数据库连接6000

    dbcp5000

    dbcp6000

    连接结束了5000

    获取了数据库连接1000

    dbcp1000

    连接结束了6000

    连接结束了1000

    演示:重写转账程序

    SQL:

    create table accounts (

    id varchar2(20),

    name varchar2(30),

    money number(11,2)

    );

    insert into accounts values('00001','张三',9000.0);

    insert into accounts values('00002','李四',4000.0);

    commit;

    转账程序:

    package util;

    import java.sql.Connection;

    import java.sql.PreparedStatement;

    import java.sql.ResultSet;

    import java.sql.SQLException;

    public class PayDemo {

    public static void main(String[] args) {

    Pay("00001","00002",1000);

    }

    /*

    * 转账方法

    */

    public static void Pay(String payID,String recID,double mny){

    //转账SQL

    String sql1 = "UPDATE accounts SET money=money+? "

    + "WHERE id=?";

    String sql2 = "SELECT money FROM accounts "

    + "WHERE id=?";

    //创建连接

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    //关闭自动事务提交

    conn.setAutoCommit(false);

    //创建PS对象

    PreparedStatement ps = conn.prepareStatement(sql1);

    //转账操作

    //设置参数

    ps.setDouble(1, -mny);

    ps.setString(2, payID);

    int n = ps.executeUpdate();

    if(n!=1){

    throw new Exception("转账失败!");

    }

    //收款操作

    //设置参数

    ps.setDouble(1,mny);

    ps.setString(2, recID);

    n = ps.executeUpdate();

    if(n != 1){

    throw new Exception("收款失败!");

    }

    //查询余额

    ps = conn.prepareStatement(sql2);

    ps.setString(1, payID);

    ResultSet rs = ps.executeQuery();

    while(rs.next()){

    double balance = rs.getDouble("money");

    if(balance < 0){

    throw new Exception("余额不足!");

    }

    }

    //完成操作提交事务

    conn.commit();

    } catch (Exception e) {

    e.printStackTrace();

    if(conn != null){

    try {

    conn.rollback();

    } catch (SQLException e1) {

    e1.printStackTrace();

    }

    }

    }finally{

    DBUtil.close(conn);

    }

    }

    }

    运行结果:

    运行Pay("00003","00002",1000)结果:

    java.lang.Exception: 转账失败!

    at util.PayDemo.Pay(PayDemo.java:40)

    at util.PayDemo.main(PayDemo.java:12)

    运行Pay("00001","00003",1000)结果:

    java.lang.Exception: 收款失败!

    at util.PayDemo.Pay(PayDemo.java:48)

    at util.PayDemo.main(PayDemo.java:12)

    运行Pay("00001","00002",10000)结果:

    java.lang.Exception: 余额不足!

    at util.PayDemo.Pay(PayDemo.java:57)

    at util.PayDemo.main(PayDemo.java:12)

    优化:

    catch (Exception e) {

    e.printStackTrace();

    if(conn != null){

    try {

    conn.rollback();

    } catch (SQLException e1) {

    e1.printStackTrace();

    }

    }

    这里conn.rollback()也需要做异常处理,可以和conn.close(conn)一样,在DBUtil里面写一个静态回滚方法。

    DBUtil类下添加方法:

    public static void rollback(Connection conn) {

    if(conn != null){

    try {

    conn.rollback();

    } catch (SQLException e) {

    e.printStackTrace();

    }

    }

    }

    修改PayDemo里面的catch:

    catch (Exception e) {

    e.printStackTrace();

    DBUtil.rollback(conn);

    }

    演示:Statement批量更新

    /*

    * Statement批量更新

    * 创建3张表

    */

    @Test

    public void test1(){

    String sql1 = "CREATE TABLE batchtest1("

    + "id NUMBER(8),"

    + "name VARCHAR2(50)"

    + ")";

    String sql2 = "CREATE TABLE batchtest2("

    + "id NUMBER(8),"

    + "name VARCHAR2(50)"

    + ")";

    String sql3 = "CREATE TABLE batchtest3("

    + "id NUMBER(8),"

    + "name VARCHAR2(50)"

    + ")";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    Statement smt = conn.createStatement();

    smt.addBatch(sql1);

    smt.addBatch(sql2);

    smt.addBatch(sql3);

    int[] arr = smt.executeBatch();

    System.out.println(Arrays.toString(arr));

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    演示:PreparedStatement批量更新

    /**

    * batchtest1表里面批量增加108条数据

    * 每50条批量增加一次

    */

    @Test

    public void test2(){

    /*

    * 类似于导入这样的功能,是一个完整的业务,所以只需要一个事务

    */

    String sql = "INSERT INTO batchtest1 VALUES(?,?)";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    conn.setAutoCommit(false);

    PreparedStatement ps = conn.prepareStatement(sql);

    for(int i=1;i<=108;i++){

    ps.setInt(1, i);

    ps.setString(2, "好汉"+i+"号");

    //每一条数据都暂存到ps

    ps.addBatch();

    if(i%50==0){

    //每存50条就提交一次

    ps.executeBatch();

    //清空数据以便下一次提交

    ps.clearBatch();

    }

    }

    //避免有剩余的不满50条的数据,再次提交

    ps.executeBatch();

    conn.commit();

    } catch (Exception e) {

    e.printStackTrace();

    DBUtil.rollback(conn);

    }finally{

    DBUtil.close(conn);

    }

    }

    演示:返回自动主键

    /*

    * JDBC自动返回主键

    */

    @Test

    public void test3(){

    //生成一个自动序列

    String sql = "CREATE SEQUENCE batchtest_seq";

    String sql2 = "INSERT INTO batchtest1 VALUES(batchtest_seq.NEXTVAL,?)";

    Connection conn = null;

    try {

    //创建数据库连接

    conn = DBUtil.getConnection();

    //关闭自动事务

    conn.setAutoCommit(false);

    //创建smt

    Statement smt = conn.createStatement();

    //提交sql

    smt.execute(sql);

    //创建ps

    PreparedStatement ps = conn.prepareStatement(sql2,new String[]{"id"});

    ps.setString(1, "SMITH");

    ps.executeUpdate();

    //获取主键

    ResultSet rs = ps.getGeneratedKeys();

    if(rs.next()){

    int id = rs.getInt(1);

    System.out.println("id="+id);

    }

    conn.commit();

    } catch (Exception e) {

    e.printStackTrace();

    DBUtil.rollback(conn);

    }finally{

    DBUtil.close(conn);

    }

    }

    运行结果:

    1

    演示:分页查询员工

    ORACLE分页公式:

    int begin = (page-1)*pageSize+1

    int end = begin+pageSize-1

    clip_image016

    /**

    * 分页查询

    */

    @Test

    public void test4(){

    //假设用户点击了第2页

    int page = 2;

    //假设需求规定了每页显示5条数据

    int size = 5;

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    String sql = "SELECT * FROM ("

    + "SELECT e.*,ROWNUM rn FROM ("

    + " SELECT * FROM emp ORDER BY empno"

    + ") e"

    + ") WHERE rn BETWEEN ? AND ?";

    System.out.println(sql);

    //打桩

    PreparedStatement ps = conn.prepareStatement(sql);

    //起始行

    ps.setInt(1, (page-1)*size+1);

    //终止行

    ps.setInt(2, page*size);

    ResultSet rs = ps.executeQuery();

    while(rs.next()){

    System.out.println(rs.getInt("empno")+","+rs.getString("ename"));

    }

    } catch (Exception e) {

    e.printStackTrace();

    }finally{

    DBUtil.close(conn);

    }

    }

    演示:封装DAO

    1.准备的SQL:

    create table emps (

    empno number(8) primary key,

    ename varchar(20),

    job varchar(20),

    mgr number(8),

    hiredate date,

    sal number(11,2),

    comm number(11,2),

    deptno number(8)

    );

    create sequence emps_seq;

    insert into emps values(emps_seq.nextval,'张三','领导',0,sysdate,18000.0,3000.0,1);

    insert into emps values(emps_seq.nextval,'李四','销售',1,sysdate,7000.0,5000.0,1);

    insert into emps values(emps_seq.nextval,'王五','销售',1,sysdate,8000.0,2000.0,1);

    insert into emps values(emps_seq.nextval,'马六','市场',1,sysdate,6000.0,0,1);

    insert into emps values(emps_seq.nextval,'周七','市场',1,sysdate,5000.0,0,1);

    insert into emps values(emps_seq.nextval,'冯八','市场',1,sysdate,4000.0,0,1);

    commit;

    2.创建emps实现类

    src/main/java/entity/Emp.java

    package entity;

    import java.io.Serializable;

    import java.sql.Date;

    /**

    * 1.尽量使用封装类型

    * 2.使用java.sql下的日期类型

    * 3.属性和表里面的列名一致

    * 4.java Bean满足如下规范

    * -必须有包

    * -必须有无参构造

    * -必须实现序列化结构

    * -通常有get和set方法

    */

    public class Emp implements Serializable{

    private Integer empno;

    private String ename;

    private String job;

    private Integer mgr;

    private Date hiredate;

    private Double sal;

    private Double comm;

    private Integer deptno;

    public Emp() {

    }

    public Emp(Integer empno, String ename, String job, Integer mgr, Date hiredate, Double sal, Double comm,

    Integer deptno) {

    super();

    this.empno = empno;

    this.ename = ename;

    this.job = job;

    this.mgr = mgr;

    this.hiredate = hiredate;

    this.sal = sal;

    this.comm = comm;

    this.deptno = deptno;

    }

    public Integer getEmpno() {

    return empno;

    }

    public void setEmpno(Integer empno) {

    this.empno = empno;

    }

    public String getEname() {

    return ename;

    }

    public void setEname(String ename) {

    this.ename = ename;

    }

    public String getJob() {

    return job;

    }

    public void setJob(String job) {

    this.job = job;

    }

    public Integer getMgr() {

    return mgr;

    }

    public void setMgr(Integer mgr) {

    this.mgr = mgr;

    }

    public Date getHiredate() {

    return hiredate;

    }

    public void setHiredate(Date hiredate) {

    this.hiredate = hiredate;

    }

    public Double getSal() {

    return sal;

    }

    public void setSal(Double sal) {

    this.sal = sal;

    }

    public Double getComm() {

    return comm;

    }

    public void setComm(Double comm) {

    this.comm = comm;

    }

    public Integer getDeptno() {

    return deptno;

    }

    public void setDeptno(Integer deptno) {

    this.deptno = deptno;

    }

    @Override

    public String toString() {

    return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate

    + ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + "]";

    }

    }

    3.封装DAO

    src/main/java/dao/EmpDao.java

    package dao;

    import java.io.Serializable;

    import java.sql.Connection;

    import java.sql.PreparedStatement;

    import java.sql.ResultSet;

    import java.sql.Statement;

    import java.util.ArrayList;

    import java.util.List;

    import entity.Emp;

    import util.DBUtil;

    public class EmpDAO implements Serializable{

    /**

    * 新增一个员工

    */

    public void save(Emp e){

    String sql = "INSERT INTO emps VALUES (emps_seq.NEXTVAL,?,?,?,?,?,?,?)";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, e.getEname());

    ps.setString(2, e.getJob());

    ps.setInt(3, e.getMgr());

    ps.setDate(4, e.getHiredate());

    ps.setDouble(5, e.getSal());

    ps.setDouble(6, e.getComm());

    ps.setInt(7, e.getDeptno());

    ps.executeUpdate();

    System.out.println("新增一名员工成功!");

    } catch (Exception e1) {

    e1.printStackTrace();

    throw new RuntimeException("新增员工失败!",e1);

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 根据ID修改一个员工

    */

    public void update(Emp e){

    String sql = "UPDATE emps SET "

    + "ename=?,"

    + "job=?,"

    + "mgr=?,"

    + "hiredate=?,"

    + "sal=?,"

    + "comm=?,"

    + "deptno=?"

    + "WHERE empno=?";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setString(1, e.getEname());

    ps.setString(2, e.getJob());

    ps.setInt(3, e.getMgr());

    ps.setDate(4, e.getHiredate());

    ps.setDouble(5, e.getSal());

    ps.setDouble(6, e.getComm());

    ps.setInt(7, e.getDeptno());

    ps.setInt(8, e.getEmpno());

    ps.executeUpdate();

    System.out.println("修改成功!");

    } catch (Exception e2) {

    e2.printStackTrace();

    throw new RuntimeException("修改员工失败!",e2);

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 根据ID删除一个员工

    */

    public void delete(int id){

    String sql = "DELETE FROM emps WHERE empno=?";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setInt(1, id);

    ps.executeUpdate();

    System.out.println("删除成功!");

    } catch (Exception e) {

    e.printStackTrace();

    throw new RuntimeException("删除失败!",e);

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 根据ID查询一个员工

    */

    public Emp findById(int id){

    String sql = "SELECT * FROM emps WHERE empno=?";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setInt(1, id);

    ResultSet rs = ps.executeQuery();

    if(rs.next()){

    Emp emp = new Emp();

    emp.setEmpno(rs.getInt("empno"));

    emp.setEname(rs.getString("ename"));

    emp.setJob(rs.getString("job"));

    emp.setMgr(rs.getInt("mgr"));

    emp.setHiredate(rs.getDate("hiredate"));

    emp.setSal(rs.getDouble("sal"));

    emp.setComm(rs.getDouble("comm"));

    emp.setDeptno(rs.getInt("deptno"));

    return emp;

    }

    } catch (Exception e) {

    e.printStackTrace();

    throw new RuntimeException("查询失败!",e);

    }finally{

    DBUtil.close(conn);

    }

    return null;

    }

    /**

    * 查询所有员工

    */

    public List<Emp> findAll(){

    List<Emp> list = new ArrayList<Emp>();

    String sql = "SELECT * FROM emps ORDER BY empno";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    Statement smt = conn.createStatement();

    ResultSet rs = smt.executeQuery(sql);

    while(rs.next()){

    Emp emp = new Emp();

    emp.setEmpno(rs.getInt("empno"));

    emp.setEname(rs.getString("ename"));

    emp.setJob(rs.getString("job"));

    emp.setMgr(rs.getInt("mgr"));

    emp.setHiredate(rs.getDate("hiredate"));

    emp.setSal(rs.getDouble("sal"));

    emp.setComm(rs.getDouble("comm"));

    emp.setDeptno(rs.getInt("deptno"));

    list.add(emp);

    }

    System.out.println("查询成功!");

    return list;

    } catch (Exception e) {

    e.printStackTrace();

    throw new RuntimeException("查询失败!",e);

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 查询某一页员工数据

    */

    public List<Emp> findByPage(int page,int size){

    String sql = "SELECT * FROM ("

    + " SELECT e.* ,ROWNUM r FROM("

    + " SELECT * FROM emps ORDER BY empno"

    + " ) e"

    + ") WHERE r BETWEEN ? AND ?";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setInt(1, (page-1)*size+1);

    ps.setInt(2, page*size);

    ResultSet rs = ps.executeQuery();

    List<Emp> list = new ArrayList<Emp>();

    while(rs.next()){

    Emp emp = new Emp();

    emp.setEmpno(rs.getInt("empno"));

    emp.setEname(rs.getString("ename"));

    emp.setJob(rs.getString("job"));

    emp.setMgr(rs.getInt("mgr"));

    emp.setHiredate(rs.getDate("hiredate"));

    emp.setSal(rs.getDouble("sal"));

    emp.setComm(rs.getDouble("comm"));

    emp.setDeptno(rs.getInt("deptno"));

    list.add(emp);

    }

    return list;

    } catch (Exception e) {

    e.printStackTrace();

    throw new RuntimeException("查询失败!",e);

    }finally{

    DBUtil.close(conn);

    }

    }

    /**

    * 查询某部门内的员工

    */

    public List<Emp> findByDept(int deptno){

    String sql = "SELECT * FROM emps WHERE deptno=?";

    Connection conn = null;

    try {

    conn = DBUtil.getConnection();

    PreparedStatement ps = conn.prepareStatement(sql);

    ps.setInt(1, deptno);

    ResultSet rs = ps.executeQuery();

    List<Emp> list = new ArrayList<Emp>();

    while(rs.next()){

    Emp emp = new Emp();

    emp.setEmpno(rs.getInt("empno"));

    emp.setEname(rs.getString("ename"));

    emp.setJob(rs.getString("job"));

    emp.setMgr(rs.getInt("mgr"));

    emp.setHiredate(rs.getDate("hiredate"));

    emp.setSal(rs.getDouble("sal"));

    emp.setComm(rs.getDouble("comm"));

    emp.setDeptno(rs.getInt("deptno"));

    list.add(emp);

    }

    return list;

    } catch (Exception e) {

    e.printStackTrace();

    throw new RuntimeException("查询失败!",e);

    }finally{

    DBUtil.close(conn);

    }

    }

    }

    4.测试类

    package test;

    import java.sql.Date;

    import java.util.List;

    import org.junit.Test;

    import dao.EmpDAO;

    import entity.Emp;

    public class TestCase4 {

    /**

    * 测试新增一名员工

    */

    @Test

    public void test1(){

    Date date = new Date(System.currentTimeMillis());

    System.out.println(date);

    EmpDAO dao = new EmpDAO();

    Emp e = new Emp();

    e.setEname("李白");

    e.setJob("诗人");

    e.setMgr(10);

    e.setHiredate(date);

    e.setSal(5000.0);

    e.setComm(3000.0);

    e.setDeptno(10);

    dao.save(e);

    }

    /**

    * 根据ID查询员工信息

    */

    @Test

    public void test2(){

    EmpDAO dao = new EmpDAO();

    Emp e = dao.findById(9);

    System.out.println(e);

    }

    /**

    * 根据id修改员工信息

    */

    @Test

    public void test3(){

    EmpDAO dao = new EmpDAO();

    //先查出旧的数据,然后修改

    Emp e = dao.findById(8);

    System.out.println(e);

    e.setJob("诗仙");

    dao.update(e);

    System.out.println(dao.findById(8));

    }

    /**

    * 根据ID删除一个员工

    */

    @Test

    public void test4(){

    new EmpDAO().delete(8);

    }

    /**

    * 查询所有员工

    */

    @Test

    public void test5(){

    List<Emp> list = new EmpDAO().findAll();

    for(Emp e:list){

    System.out.println(e);

    }

    }

    /**

    * 查询某一页员工

    */

    @Test

    public void test6(){

    List<Emp>list = new EmpDAO().findByPage(1, 3);

    for(Emp e:list){

    System.out.println(e);

    }

    }

    /**

    * 查询某部门员工

    */

    @Test

    public void test7(){

    List<Emp>list = new EmpDAO().findByDept(1);

    for(Emp e:list){

    System.out.println(e);

    }

    }

    }

  • 相关阅读:
    jQuery取得select选择的文本与值
    jquery 广告效果
    【JNI知识一】JNI接口函数与指针
    jQuery 中bind(),live(),delegate(),on() 区别(转)
    用angular怎么缓存父页面数据
    js条件判断时隐式类型转换
    常用原生JS方法
    gulp批量打包文件并提取公共文件
    angular下H5上传图片(可预览,可多张上传)
    angular4运行 ng build prod出错
  • 原文地址:https://www.cnblogs.com/jmwm/p/7310564.html
Copyright © 2011-2022 走看看