7-0 Java JDBC编程

目录

一.MySQL 下载和 MySQL 驱动下载

二.MySQL 命令行

三.MySQL特殊操作

四.MySQL常用操作 增删改查

五.MySQL 事务

六.MySQL 数据库连接池


一.MySQL 下载和 MySQL 驱动下载

MySQL是应用最广泛的开源关系数据库。
下载链接:https://dev.mysql.com/downloads/mysql/
下载 Connector 驱动:https://dev.mysql.com/downloads/connector/j/

选择 Platform Independent

二.MySQL 命令行

      进入MySQL命令行:
           mysql -u root -p
           (输入密码)
      切换到test数据库:
           mysql> use test;
      查看数据库表:
           mysql> show tables;

三.MySQL特殊操作

1.excute 和 excuteUpdate 区别

2.获取自增 ID

3.获取元数据

1.excute 和 excuteUpdate 和 excuteQuery区别

executeQuery(String sql) 

    执行select语句,它返回的是查询后得到记录集(resultset)。

executeUpdate(String sql) 

    执行update,insert,delete语句,它返回的是语句执行后说影响到的记录条数(int)

execute(String sql) 

    执行任何sql语句,也就是前两者之和。

    当执行结果是查询语句时,返回true,可以通过getResultSet方法获取结果;

   当执行的是update,delete,insert语句时,返回false,可以通过getUpdateCount方法获取更新的记录数量。

2.获取自增 ID

public int add(){
   Connection conn=null;
   PreparedStatement ps=null;
   try {
       conn = ConnUtil.getConnection();
       ps = conn.prepareStatement("insert student(name,age)values(?,?)", Statement.RETURN_GENERATED_KEYS);
       ps.setString(1,"joe");
       ps.setInt(2,23);
       int i = ps.executeUpdate();
       // 在执行完插入语句后,MySQL会为新插入的数据分配一个自增长id
       // JDBC通过getGeneratedKeys获取该id
       ResultSet rs=ps.getGeneratedKeys();
       while(rs.next()){
          int id=rs.getInt(1);
          System.out.println("自增 id:"+id);
       }
       return i;
   }catch (SQLException e){
            e.printStackTrace();
   }finally {
      ConnUtil.close(ps,conn);
   }
   return 0;
}

3.获取元数据

public void getDataBaseMetaData(){
        Connection conn=null;
        try{
            conn=ConnUtil.getConnection();
            DatabaseMetaData dbmd=conn.getMetaData();
            // 获取数据库服务器产品名称
            System.out.println("数据库产品名称:\t"+dbmd.getDatabaseProductName());
            // 获取数据库服务器产品版本号
            System.out.println("数据库产品版本:\t"+dbmd.getDatabaseProductVersion());
            // 获取数据库服务器用作类别和表名之间的分隔符 如test.user
            System.out.println("数据库和表分隔符:\t"+dbmd.getCatalogSeparator());
            // 获取驱动版本
            System.out.println("驱动版本:\t"+dbmd.getDriverVersion());

            System.out.println("可用的数据库列表:");
            // 获取数据库名称
            ResultSet rs = dbmd.getCatalogs();

            while (rs.next()) {
                System.out.println("数据库名称:\t"+rs.getString(1));
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            ConnUtil.close(conn);
        }
    }

四.MySQL常用操作 增删改查

public class ConnUtil {

    public static Connection getConnection(){
        Connection connection;
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/students?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&user=root&password=12345678");
            return connection;
        }catch (Exception e){
            e.printStackTrace();
        }
        return null;
    }
    public static void close(Object ...objects){
        try {
            for (Object object : objects) {
                if (object instanceof ResultSet) {
                    ResultSet rs = (ResultSet) object;
                    rs.close();
                } else if (object instanceof Statement) {
                    Statement statement = (Statement) object;
                    statement.close();
                } else if (object instanceof Connection) {
                    Connection conn = (Connection) object;
                    conn.close();
                }
            }
        }catch (SQLException e){
            e.printStackTrace();
        }

    }
}
public class StudentDao {
    public int add(){
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            conn = ConnUtil.getConnection();
            ps = conn.prepareStatement("insert student(name,age)values(?,?)", Statement.RETURN_GENERATED_KEYS);
            ps.setString(1,"joe");
            ps.setInt(2,23);
            int i = ps.executeUpdate();
            ResultSet rs=ps.getGeneratedKeys();
            while(rs.next()){
                int id=rs.getInt(1);
                System.out.println("自增 id:"+id);
            }
            return i;
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            ConnUtil.close(ps,conn);
        }
        return 0;
    }
    public int delete(){
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            conn=ConnUtil.getConnection();
            ps=conn.prepareStatement("delete from student where id=?");
            ps.setInt(1,2);
            int i=ps.executeUpdate();
            return i;
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            ConnUtil.close(ps,conn);
        }
        return 0;
    }
    public int update(){
        Connection conn=null;
        PreparedStatement ps=null;
        try {
            conn=ConnUtil.getConnection();
            ps=conn.prepareStatement("update student set name=?,age=? where id=?");
            ps.setString(1,"joe1");
            ps.setInt(2,24);
            ps.setInt(3,1);
            int i=ps.executeUpdate();
            return i;
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            ConnUtil.close(ps,conn);
        }
        return 0;
    }
    public void get(){
        Connection conn=null;
        PreparedStatement ps=null;
        ResultSet rs=null;
        try {
            conn=ConnUtil.getConnection();
            ps=conn.prepareStatement("select * from student ");
            rs=ps.executeQuery();
            while(rs.next()){
                int id=rs.getInt("id");
                String name=rs.getString("name");
                int age=rs.getInt("age");
                System.out.println("id="+id+" name="+name+" age="+age);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }finally {
            ConnUtil.close(rs,ps,conn);
        }

    }
    public void getDataBaseMetaData(){
        Connection conn=null;
        try{
            conn=ConnUtil.getConnection();
            DatabaseMetaData dbmd=conn.getMetaData();
            // 获取数据库服务器产品名称
            System.out.println("数据库产品名称:\t"+dbmd.getDatabaseProductName());
            // 获取数据库服务器产品版本号
            System.out.println("数据库产品版本:\t"+dbmd.getDatabaseProductVersion());
            // 获取数据库服务器用作类别和表名之间的分隔符 如test.user
            System.out.println("数据库和表分隔符:\t"+dbmd.getCatalogSeparator());
            // 获取驱动版本
            System.out.println("驱动版本:\t"+dbmd.getDriverVersion());

            System.out.println("可用的数据库列表:");
            // 获取数据库名称
            ResultSet rs = dbmd.getCatalogs();

            while (rs.next()) {
                System.out.println("数据库名称:\t"+rs.getString(1));
            }

        }catch (Exception e){
            e.printStackTrace();
        }finally {
            ConnUtil.close(conn);
        }
    }

}

五.MySQL 事务

 在MySQL中,只有当表的类型是INNODB的时候,才支持事务,所以需要把表的类型设置为INNODB,否则无法观察到事务.
 修改表的类型为INNODB的SQL:alter table student ENGINE = innodb;
查看表的类型的SQL show table status from student;

//conn.setAutoCommit(false); 将自动提交设置为 false
//conn.commit();手动提交操作
//conn.rollback();出现错误时回滚

public int add(){
   Connection conn=null;
   PreparedStatement ps=null;
   try {
       conn = ConnUtil.getConnection();
       conn.setAutoCommit(false);

       ps = conn.prepareStatement("insert student(name,age)values(?,?)", Statement.RETURN_GENERATED_KEYS);
       ps.setString(1,"joe");
       ps.setInt(2,23);
       int i = ps.executeUpdate();
       int test=5/0;
       conn.commit();
       ResultSet rs=ps.getGeneratedKeys();
       while(rs.next()){
          int id=rs.getInt(1);
          System.out.println("自增 id:"+id);
       }
       return i;
   }catch ( Exception e){
       e.printStackTrace();
       try {
          System.out.println("进行了回滚操作");
          conn.rollback();
       }catch (Exception ex){
           ex.printStackTrace();
       }

   }finally {
      ConnUtil.close(ps,conn);
   }
   return 0;
}

4.JDBC事务

数据库事务(Transaction)具有ACID特性:
    Atomicity:原子性
    Consistency:一致性
    Isolation:隔离性
    Durability:持久性

JDBC提供了事务的支持

事务隔离级别
Isolation LevelDirty ReadNon Repeatable ReadPhantom Read
Read UncommittedYYY
 Read Committed  YY
 Repeatable Read  Y
 Serializable    


 

 

 

 

 

六.MySQL 数据库连接池

1.不使用数据库连接池

2.使用数据库连接池

3.自己写数据库连接池

1.不使用数据库连接池

当有多个线程,每个线程都需要连接数据库执行SQL语句的话,那么每个线程都会创建一个连接,并且在使用完毕后,关闭连接。
创建连接和关闭连接的过程也是比较消耗时间的,当多线程并发的时候,系统就会变得很卡顿。
同时,一个数据库同时支持的连接总数也是有限的,如果多线程并发量很大,那么数据库连接的总数就会被消耗光,后续线程发起的数据库连接就会失败。

2.使用数据库连接池

与传统方式不同,连接池在使用之前,就会创建好一定数量的连接。如果有任何线程需要使用连接,那么就从连接池里面借用,而不是自己重新创建. 使用完毕后,又把这个连接归还给连接池供下一次或者其他线程使用。倘若发生多线程并发情况,连接池里的连接被借用光了,那么其他线程就会临时等待,直到有连接被归还回来,再继续使用。整个过程,这些连接都不会被关闭,而是不断的被循环使用,从而节约了启动和关闭连接的时间。

3.自己写数据库连接池

public class ConnPool {
    List<Connection> lists=new ArrayList<Connection>();
    private int size;

    public ConnPool(int size){
        this.size=size;
        init();
    }
    public void init(){
        try{
            Class.forName("com.mysql.cj.jdbc.Driver");
            for(int i=0;i<size;i++){
                Connection connection=DriverManager.getConnection("jdbc:mysql://localhost:3306/students?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT&user=root&password=12345678");
                lists.add(connection);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }

    public synchronized Connection getConn(){
        while (lists.isEmpty()){
            try {
                this.wait();
            }catch (Exception e){
                e.printStackTrace();
            }
        }
        Connection connection=lists.remove(0);
        return connection;
    }
    public synchronized void returnConn(Connection conn){
        lists.add(conn);
        this.notifyAll();
    }

    public int getSize() {
        return size;
    }

    public void setSize(int size) {
        this.size = size;
    }
}
public class WorkThread extends Thread {
    private ConnPool connPool;
    private String name;
    public WorkThread(String name,ConnPool connPool){
        super(name);
        this.connPool=connPool;
    }

    @Override
    public void run() {

        Connection connection = connPool.getConn();
        System.out.println(this.getName() + " 获得一个链接并开始工作"+connection.toString());
        try(Statement s= connection.createStatement()){
            Thread.sleep(1000);//模拟时耗1秒的数据库SQL语句
            //s.executeQuery("select* from student");
        }catch (Exception e){
            e.printStackTrace();
        }
        connPool.returnConn(connection);

    }

    public ConnPool getConnPool() {
        return connPool;
    }

    public void setConnPool(ConnPool connPool) {
        this.connPool = connPool;
    }
    
}
首先初始化一个有5条连接的数据库连接池
然后创建100个线程,每个线程都会从连接池中借用连接,并且在借用之后,归还连接。 拿到连接之后,执行一个耗时1秒的SQL语句。

public static void main(String[] args){
        
        ConnPool pool=new ConnPool(5);
        for (int i=0;i<100;i++){
            new WorkThread("working thread"+i,pool).start();
        }
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值