JDBC

目录

1. JDBC基本概念
2. 快速入门
3. 对JDBC中各个接口和类详解

JDBC

1. 概念:Java DataBase Connectivity(Java 数据库连接),Java语言操作数据库。
	* JDBC本质:官方(SUN公司)定义的一套操作所有关系型数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动jar包。我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
2. 快速入门:
	步骤:
	1. 导入驱动jar包
	2. 注册驱动
	3. 获取数据库连接对象Connection
	4. 定义sql
	5. 获取执行sql语句的对象Statement
	6. 执行sql,接受返回结果
	7. 处理结果
	8. 释放资源
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;

public class JdbcDemo {
    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //3.获取数据库连接对象
        Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/com?serverTimezone=UTC","root","123");
        //4.定义sql语句
        String sql="update emp set age=22 where id=2";
        //5.获取执行sql的对象 Statement
        Statement stmt = conn.createStatement();
        //6.执行sql
        int count=stmt.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        stmt.close();
        conn.close();
    }
}
3. 详解各个对象
	①DriverManager:告诉程序该使用哪一个数据库驱动jar
		Ⅰ 注册驱动:告诉程序该使用哪一个数据库驱动jar
			static void registerDriver(Driver driver):注册与给定的驱动程序 DriverManager。
			写代码使用:Class.forName("com.sql.jdbc.Driver");
			通过查看源码发现:在com.mysql.jdbc.Driver类中存在静态代码块:如下
static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
            throw new RuntimeException("Can't register driver!");
         }
            }
			注意:mysql5之后的驱动jar包可以省略注册驱动的步骤
		Ⅱ 获取数据库连接
			*方法:static Connection getConnetion(String url,String user,String password)
			*参数:
				url:指定连接的路径
					jdbc:mysql://ip地址(域名):端口号/数据库名称
					jdbc:mysql://localhost:3306/db3
				user:用户名
				password:密码
	
	②Connection:数据库连接对象		
		Ⅰ 获取执行sql的对象
			* Statement createStatement()
			* PreparedStatement prepareStatement(String sql)
		Ⅱ 管理事务
			* 开启事务:SetAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务
			* 提交事务:commit()
			* 回滚事务:rollback()
	
	③Statement:执行sql的对象
		Ⅰ boolean execute(String sql):可以执行任意的sql 了解
		Ⅱ int executeUpdate(String sql):执行DML(insert、update、delete)语句、DDL(create、alter、drop)语句
			*返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功,返回值>0的则执行成功,反之,则失败。
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;

public class JdbmDemo1 {
    public static void main(String[] args) {
        Connection conn=null;
        Statement cstm=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/com?serverTimezone=UTC", "root", "123");
            cstm = conn.createStatement();
            String sql="update emp set age=25 where id=6";
            int count = cstm.executeUpdate(sql);
            if(count>0){
                System.out.println("bingo");
            }else{
                System.out.println("lose");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (cstm!=null){
                try {
                    cstm.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
		Ⅲ ResultSet executeQuery(String sql):执行DQL(select)语句 
	④ResultSet:结果集对象,封装查询结果
		*next():游标向下移动一行
		*getXXX(参数):获取数据
			*XXX:代表数据类型
import java.sql.*;

public class JdbcDomo2 {
    public static void main(String[] args) {
        Connection conn=null;
        Statement cstm=null;
        ResultSet resultSet=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/com?serverTimezone=UTC", "root", "123");
            cstm = conn.createStatement();
            String sql="select * from emp";
            resultSet = cstm.executeQuery(sql);
            while(resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                int dep_id = resultSet.getInt("dep_id");
                System.out.println(id+"-"+name+"-"+age+"-"+dep_id);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if (cstm!=null){
                try {
                    cstm.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(resultSet!=null){
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}
	⑤PreparedStatement:执行sql的对象
		Ⅰ SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全性问题
			1.输入用户随便,输入密码:a' or 'a'='a
			2.sql:select * from user where username='fhdsjkf' and password='a' or 'a'='a'
		Ⅱ 解决sql注入问题:使用PreparedStatement对象来解决
		Ⅲ 预编译的sql:参数使用?作为占位符
		Ⅳ 步骤:
			1. 导入驱动jar包
			2. 注册驱动
			3. 获取数据库连接对象Connection
			4. 定义sql
				注意:sql的参数使用?作为占位符,如:select * from user where username=? and password=?;
			5. 获取执行sql语句的对象 PreparedStatement Connection.prepareStatement(String sql)
			6. 给?赋值:
				方法:setXXX(参数1,参数2)
					参数1:?的位置编号从1开始
					参数2:?的值
			7. 执行sql ,接受返回结果,不需要传递sql语句
			8. 处理结果
			9. 释放资源
		Ⅴ 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
			* 可以放置SQL注入
			* 效率更高				
import java.sql.*;
import java.util.Scanner;

public class login {
    public static void main(String[] args) throws SQLException {
        Connection conn=null;
        Statement cstm=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        conn=JdbcUtils.getConnection();
        Scanner sca=new Scanner(System.in);
        int Id=sca.nextInt();
        String password=sca.next();
//        try {
//           cstm=conn.createStatement();
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//        String sql="select * from users where id="+Id+" and password='"+password+"'";
//        System.out.println(sql);
//        try {
//            resultSet = cstm.executeQuery(sql);
//        } catch (SQLException e) {
//            e.printStackTrace();
//        }
//        if (resultSet.next()){
//            System.out.println("登陆成功");
//        }
//        else{
//            System.out.println("登陆失败");
//        }
        String sql="select * from users where id=? and password=?";
        preparedStatement = conn.prepareStatement(sql);
        preparedStatement.setInt(1,Id);
        preparedStatement.setString(2,password);
        resultSet = preparedStatement.executeQuery();
        if (resultSet.next()){
            System.out.println("登陆成功");
        }
        else{
            System.out.println("登陆失败");
        }
        JdbcUtils.close(preparedStatement,conn,resultSet);
    }
}
~

抽取JDBC工具类:JDBCUtils

* 目的:简化书写
* 分析:
	1.注册驱动
	2.抽取一个方法获取连接对象
		*需求:不想传递参数,还得保证工具的通用性
		*解决:配置文件
			jdbc.properties
				url=
				user=
				password=
	3.抽取一个方法释放资源
import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    static {
        //读取文件资源,获取值
        //1.创建Properties集合类
        Properties pro=new Properties();

        //获取src路径下的文件的方式--->ClassLoader类加载器
        ClassLoader classLoader=JdbcUtils.class.getClassLoader();
        URL res = classLoader.getResource("jdbc.properties");
        String path=res.getPath();
        System.out.println(path);
        try {
            //2.加载文件
            pro.load(new FileReader(path));
        } catch (IOException e) {
            e.printStackTrace();
        }
        //3.获取数据
        url=pro.getProperty("url");
        user=pro.getProperty("user");
        password=pro.getProperty("password");
        driver=pro.getProperty("driver");
    }

    public static Connection getConnection()  {
        Connection conn = null;
        try {
            conn = DriverManager.getConnection(url, user, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return conn;
    }

    public static void close(Statement stmt,Connection conn){
        if (stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public static void close(Statement stmt, Connection conn, ResultSet resultSet){
        if (stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

JDBC控制事务:

1. 事务:一个包含多个步骤的业务操作。如果这个业务操作被事务管理,则这多个步骤要么同时成功,要么同时失败。
2. 操作:
	2.1 开启事务
	2.2 提交事务
	2.3 回滚事务
3. 使用Connection对象来管理事务
	3.1 开启事务:setAutoCommit(boolean autoCommit):调用该方法是指参数为false,即开启事务
	3.2 提交事务:commit()
	3.3 回滚事务:rollback()
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class JdbcDemo4 {
    public static void main(String[] args) {
        Connection connection = JdbcUtils.getConnection();
        PreparedStatement preparedStatement1 = null;
        PreparedStatement preparedStatement2 = null;
        try {
            connection.setAutoCommit(false);
            preparedStatement1 = connection.prepareStatement("update accounts set property=property - ? where id=?");
            preparedStatement2 = connection.prepareStatement("update accounts set property=property + ? where id=?");
            preparedStatement1.setDouble(1,500);
            preparedStatement1.setInt(2,1);
            preparedStatement2.setDouble(1,500);
            preparedStatement2.setInt(2,2);
            System.out.println("______________________________________");
            preparedStatement1.executeUpdate();
            int i=3/0;
            System.out.println("______________________________________");

            preparedStatement2.executeUpdate();
            connection.commit();
        } catch (SQLException e) {

            e.printStackTrace();
            try {
                System.out.println("shibai");
                connection.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        }finally {
            JdbcUtils.close(preparedStatement1,null);
            JdbcUtils.close(preparedStatement2,connection);
        }
    }
}
~

数据库连接池

1. 概念:其实就是一个容器(集合),存放数据库连接的容器
	当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户来访问数据时,从容其中获取连接对象,用户访问完后,会将连接对象归还给容器。
2. 好处:
	2.1 节约资源
	2.2. 用户访问高效
3. 实现:
	3.1 标准接口:Datasource javax.sql包下的
		3.1.1 方法:
			* 获取连接:getConnection()
			* 归还连接:如果连接对象Connection是从连接池中获取的,那么调用Connection.close()方法,则不会在关闭连接了,而是归还连接。
		3.1.2 一般我们不去实现它,有数据库厂商来实现
			* C3P0:数据库连接池技术
			* Druid:数据库连接池实现技术,由阿里巴巴提供
4. C3P0:数据库连接池技术
	下载地址:[C3P0](https://www.mchange.com/projects/c3p0/)
	步骤:
		①导入jar包(两个)c3p0-0.9.5.2.jar  mchange-commons-java-0.2.12.jar
		②定义配置文件:
			* 名称:c3p0.properties 或者 c3p0-config.xml(必须)
			* 路径:直接将文件放在src目录下即可。
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/com?serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123</property>

        <property name="initialPoolSize">10</property>
        <property name="maxIdleTime">30</property>
        <property name="maxPoolSize">20</property>
        <property name="minPoolSize">5</property>
        <property name="maxStatements">200</property>
    </default-config>

    <named-config name="mysql">
        <property name="acquireIncrement">50</property>
        <property name="initialPoolSize">100</property>
        <property name="minPoolSize">50</property>
        <property name="maxPoolSize">1000</property><!-- intergalactoApp adopts a different approach to configuring statement caching -->
        <property name="maxStatements">0</property>
        <property name="maxStatementsPerConnection">5</property>
    </named-config>
</c3p0-config>
		③连接池对象 ComboPooledDataSource
		④获取连接:getConnection
import com.mchange.v2.c3p0.ComboPooledDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.SQLException;

public class C3P0Demo {
    public static void main(String[] args) throws SQLException {
        DataSource ds=new ComboPooledDataSource();
        for(int i=0;i<11;i++){
            Connection conn=ds.getConnection();
            System.out.println(conn);
            if(i==5){
                conn.close();
            }
        }
    }
}
5.Druid:数据库连接池实现技术,由阿里巴巴提供
[下载地址](https://github.com/alibaba/druid/wiki/%E5%B8%B8%E8%A7%81%E9%97%AE%E9%A2%98)
	5.1 步骤
		5.1.1 导入jar包 druid-1.0.9.jar
		5.1.2 定义配置文件
			* 是propertie形式的
			* 可以叫任意名字,可以放在任意目录下
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/com?serverTimezone=UTC
username=root
password=123
#初始化连接数量
initialSize=5
#最大连接数
maxActive=10
#最大等待时间
maxWait=3000
		5.1.3 获取数据库连接池对象:通过工厂类来获取	DruidDataSourceFactory
		5.1.4 获取连接:getConnection
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.util.Properties;

public class DruidDemo {
    public static void main(String[] args) throws Exception {
        //1.导入jar包
        //2.定义配置文件
        //3.加载配置文件
        Properties pro=new Properties();
        InputStream resourceAsStream = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(resourceAsStream);
        //4.获取连接池对象
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //5.获取连接
        Connection connection = ds.getConnection();
        System.out.println(connection);
    }
}
	5.2 定义工具类
		5.2.1 定义一个类 JDBCUtils
		5.2.2 提供静态代码块加载配置文件,初始化连接池对象
		5.2.3 提供方法
			①获取连接方法:通过数据库连接池获取连接
			②释放资源
			③获取连接池的方法
import com.alibaba.druid.pool.DruidDataSourceFactory;
import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class DruidJdbcUtils {
    private static DataSource ds=null;

    static {
        Properties pro=new Properties();
        InputStream resourceAsStream = DruidJdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
        try {
            pro.load(resourceAsStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
        try {
            ds= DruidDataSourceFactory.createDataSource(pro);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static Connection getConnection() throws SQLException {
        return  ds.getConnection();
    }

    public void close(Connection conn, Statement statement){
        this.close(conn,statement,null);
    }

    public void close(Connection conn, Statement statement, ResultSet resultSet){
        if(resultSet!=null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement!=null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public DataSource getDatasource(){
        return ds;
    }
}

Spring JDBC

* Spring框架对JDBC的简单封装。提供一个JDBC对象简化JDBC的开发
* 步骤:
	1. 导入jar包
	2. 创建JdbcTemplate对象。依赖于数据源DataSource
		*JdbcTemplate template = new JdbcTemplate(ds);
	3. 调用JdbcTemplate的方法来完成CRUD的操作
		* update():执行DML语句。增、删、改语句
		* queryForMap():查询结果将结果集封装为map集合,将列名作为key,将值作为value
			* 注意:这个方法查询的结果集长度只能是1
		* queryForList():查询结果将结果集封装为list集合
			* 注意:将每一条记录封装为一个Map集合,再将Map集合装载到List集合中
		* query():查询结果,将结果封装为JavaBean对象
			* query的参数:RowMapper
				* 一般我们使用BeanProperRowMapper实现类。可以完成数据到JavaBean的自动封装
				* new BeanPropertyRowMapper<类型>(类型.class)
		* queryForObject():查询结果,将结果封装为对象
			* 一般用于聚合函数的查询
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值