JDBC相关知识点

概念

java DataBase Connectivity java 数据库连接 ,java语言操作数据库

JDBC本质:其实是官方(sum公司)定义的一套操作所有关系类型数据库的规则,即接口.
各个数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套接口(JDBC)编程.
真正执行的代码是驱动jar包中的实现类

快速入门

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
//        1.导入驱动包	mysql-connector-java-5.1.37-bin.jar
//        复制mysql-connector-java-5.1.37-bin.jar到项目lib文件夹下(没有可以自己创建)
//        右键--> Add As Library
//        2.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
//        3.获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/db3", "root", "1234");
//        4.定义sql
        String sql="update account set balance =500 where id=1;";
//        5.获取执行sql语句对象 Statemen
        Statement stmt = conn.createStatement();
//        6.执行sql,接收返回结果
        int count = stmt.executeUpdate(sql);
//        7.处理结果
        System.out.println(count);
//        8.释放资源
        stmt.close();
        conn.close();
    }
}

详解各个对象

DriverManager:

DriverManager:    英 /ˈdraɪvə(r)/   英 /ˈmænɪdʒə(r)/    [拽我麦妮哲]

驱动管理对象
功能:
1.注册驱动:告诉程序该使用哪一个数据库驱动jar

	static void registerDriver(Driver driver):注册与给定的驱动程序 DriverManager 。
	写代码使用:class.forName("com.mysql.jdbc.Driver");
	通过查看源码发现:com.mysql.jdbc.Driver类中存在静态代码块 
	static {
		try {
			java.sql.DriverManager.registerDriver(new Driver());
			}catch(SOLException E){
				throw new RuntimeException("Can't register driver!");
			}
		}
注意:mysql5之后的驱动jar包可以省略注册驱动的步骤。

2.获取数据库连接:

方法:static connection.getconnection(string url, string user, string password)
参数:
	url:指定连接的路径
		语法:jdbc:mysql://ip地址(域名):端口号/数据库名称
		例子:jdbc:mysql://localhost:3306/db3
		细节:如果连接的是本机mysql服务器,并且mysql服务默认端口是3306,
		则url可以简写为:jdbc:mysql:///数据库名称 
	user:用户名 
	password:密码

Connection:

数据库连接对象

Connection:	英 /kəˈnekʃn/						 [科 耐克神]

功能:
1.获取执行sql对象

Statement createStatement()
PreparedStatement preparedStatement();

2.管理实务

	开启事务:
		setAutoCommit(boolean aotuCommit):调用该方法色后置参数为false,即开启事务
	提交事务:
		commit()
	回滚事务:
		rollback()

Statement:

执行sql的对象

Statement:  英 /ˈsteɪtmənt/						 [斯戴特闷特]

1.执行:sql

1.boolean execute(String sql):可以执行任意的sql(了解即可)
2.int executeUpdate(String SQL):执行DML(insert/update/delete)语句,DDL(create/alter/drop)语句
	返回值:影响的行数,可以通过这个影响的行数判断语句是否执行成功,返回值>0则成功,反之,则失败
3.Result executeQuery(String sql):执行DQL(select)语句

ResultSet:

结果集对象

	ResultSet: 英 /rɪˈzʌlt/						 [瑞饶特 赛特]
	next():游标向下移动一行
	getXxx(): 获取数据
		Xxx:代表数据类型	如:int getInt()		String getString()	
			参数:
				1.int :代表列的编号,1开始	比如:getString(1):获取第一列的值
	注意:使用步骤
		1.游标向下移动一行
		2.判断是否有数据
		3.获取数据
		//执行sql语句
             rs = stat.executeQuery(sql);
		//循环判断游标是否是最后一行末尾
		while (rs.next()){
                int id = rs.getInt(1);
                String name = rs.getString("name");
                int balaance = rs.getInt(3);
                System.out.println(id+"==="+name+"==="+balaance);
            }

PreparedStatement:

执行sql的对象

英 /prɪˈpeəd/ 英 /ˈsteɪtmənt/		 [普瑞 派的 斯戴特闷特]
	1,sql 注入问题:
		1.用户随便输入密码: a' or 'a'='a
		2.sql:select * from user where username ='fhdsjkf' and password = 'a' or 'a'='a'

解决方案:

 public static void main(String[] args) {
        //键盘录入姓名和密码
        System.out.println("请输入用户名:");
        Scanner sc=new Scanner(System.in);
        String name = sc.nextLine();
        System.out.println("请输入密码:");
        String password = sc.nextLine();
        boolean flag = opinion(name, password);
        if (flag){
            System.out.println("登陆成功");

        }else {
            System.out.println("登录失败");
        }
    }

    public static boolean opinion(String name ,String password){
if (name==null||password==null){
    System.out.println("请检查账户或者密码");
    return false;
}
        Connection conn=null;
        PreparedStatement pstmt=null;
        ResultSet rs=null;
        try {
            //使用工具类获取connection对象
            conn = Utils.getConnection();
            String sql="select *from account where name=? and password=?;";
            //select *from account where name='lisi' or 1=1 and password='1234' ;
            //获取Statement对象
           pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,name);
            pstmt.setString(2,password);
            rs = pstmt.executeQuery();
            return rs.next();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            Utils.close(rs,pstmt,conn);
        }
        return false;
    }

抽取jdbc的工具类

JDBCUtils

 目的:简化书写
分析:
	1.注册驱动也抽取
		
	2.抽取一个方法获取连接对象 
		需求:不想传递参数(麻烦那),还得保证工具类的通用性.
		解决:配置文件
			jdbc.properties
				url=
				user=
				passwo=
JDBC.properties文件:

url=jdbc:mysql:///db3
user=root
password=1234
driver=com.mysql.jdbc.Driver
	3.抽取一个方法释放资源

JDBC工具类:

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

    /**
     * 文件的读取,只需要读取一次即可拿到这些值,使用静态代码块
     * */

    static {
        //读取资源文件,获取值


        try {
            //1.创建Properties集合类
            Properties pro = new Properties();
            //获取src路径下的文件的方式:--->ClassLoader 类加载器
            ClassLoader classLoader = Utils.class.getClassLoader();
            URL res = classLoader.getResource("jdbc.properties");
            String path = res.getPath();
            //2.加载文件
            pro.load(new FileReader(path));
            //3.获取数据,在赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //4.注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }

    /**
     * 获取连接
     * return连接对象
     **/
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, user, password);
    }

    /**
     * 释放资源
     */
    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(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

    }
}

测试工具类:

public class Test002 {
    //测试工具类


    public static void main(String[] args) {
        Connection conn=null;
        Statement stat=null;
        ResultSet rs=null;
        try {
            //使用工具类的方法
            conn = Utils.getConnection();



            //3.获取statement对象
            stat = conn.createStatement();
            //4.定义sql语句
            String sql="select *from account;";//删除account表中字段你name=wangwu的所有记录
            //5.执行sql语句
            rs = stat.executeQuery(sql);
            //6.输出结果
            while (rs.next()){
                int id = rs.getInt(1);
                String name = rs.getString("name");
                int balaance = rs.getInt(3);
                System.out.println(id+"==="+name+"==="+balaance);
            }
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally{
            //释放资源
         if(rs!=null){
             try {
                 rs.close();
             } catch (SQLException throwables) {
                 throwables.printStackTrace();
             }
         }
            if(stat!=null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    rs.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }
    }
}

JDBC控制事务

事务:一个包含多个步骤的业务操作.如果这个业务操作被事务管理,则这个步骤要么同时成功,要么同时失败
操作
	开启事务
	提交事务
	回滚事务
使用connection对象来管理事务
		开启事务:setAutoCommit(Boolean autoCommit):调用该方法设置参数为false,即为开启事务
		提交事务:commit()
		回滚事务:rollback()

案例:银行转账系统张三给李四转账500元,中途手动制造异常,使用事务处理

 public static void main(String[] args) throws SQLException {
        Connection conn=null;
        PreparedStatement pstmt1=null;
        PreparedStatement pstmt2=null;
        try {
            //获取连接
            conn = Utils.getConnection();
            //开启事务
            conn.setAutoCommit(false);//false为开启事务
            //定义sql

            String sql1="update yinhang set money=money-? where name=?;";//定义张三-500
            String sql2="update yinhang set money=money+? where name=?;";//定义李四+500
            //获取sql对象
            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);
            //设置参数
            pstmt1.setInt(1,500);
            pstmt1.setString(2,"zhangsan");
            pstmt2.setInt(1,500);
            pstmt2.setString(2,"lisi");

            pstmt1.executeUpdate();
            //手动制造异常
            int i=3/0;
            pstmt2.executeUpdate();
            //提交事务
            conn.commit();
        } catch (Exception throwables) {
            if(conn!=null){
                try {
                    conn.rollback();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            throwables.printStackTrace();
        }finally {
            Utils.close(pstmt1,conn);
            Utils.close(pstmt2,null);//实际开发不能这样写,只为测试
        }
    }

数据库连接池

概念 :
	其实就是一个容器(集合),存放数据库连接的容器
		当容器初始化好,容器被创建,容器中会申请一些连接对象,当用户来访问数据库时,从容器中获取连接对象,用户访问完之后,会将连接对象归还给容器;
好处:
	节约资源
	用户访问高效
实现:
	标准接口:DataSource javax.sql包下的
	方法:
		获取连接:getConnection()
		归还连接:Connection.close().
			如果连接对象connection是从连接池中获取的,那么调用Connection.close()方法
			则不会再关闭了,而是归还连接.
	一般我们不去实现它,有数据库厂商来实现
		C3P0:数据库连接池技术;
		Druid:数据库连接池技术,由阿里巴巴提供的

C3P0:数据库连接池技术

步骤:
1导入jar包(两个)c3p0-0.9.5.2.jar mchange-commons-java-0.2.12.jar
*不要忘记导入数据库驱动jar包
2.定义配文件:
*名称:c3p0.properties或者c3p0-config.xml
* 路径:直接将文件放在src目录下即可。
3.创建核心对旅数据库连接池对象EomboPooledDataSource
4.获取连接:getConnection

Druid:数据库连接池技术

步骤:
1.导入jar包 druid-1.0.9.jar
2.定义配文件:
*是properties形式的
可以叫任意名称,可以放在任意目录下
3.加载配文件。Properties
4.获取数据库连接池对象:通过工厂来来获取DruidDataSourceFactory
5.获取连接:getConnection

public static void main(String[ args) throws :Exception { 
	//1.导入jar包  文件复制到lib
	//2.定义配文件	把properties文件复制
	//3.加载配置文件
	Properties pro = new Properties();
	InputStream is =DruidDemo.class.getClassLoader.getResourceAsStream( name: "druid.properties" );
	pro.load(is);
	//4.获取连接池对象
	DataSource ds =DruidDataSourceFactory.createDataSource(pro);
	//5.获取连接
	Connection conn =ds.getConnection(); 
	System.out.println(conn);

定义一个工具类:

druid.properties文件

	url=jdbc:mysql:///db3
	username=root
	password=1234
	driverClassName=com.mysql.jdbc.Driver
	initialSize=5
	maxActive=10
	maxWait=3000

定义一个类 JDBCUtils
提供静态代码块加载配置文件,初始化连接池对象
提供方法
获取连接的方法:通过数据库连接池获取连接
释放资源
获取连接池的方法

 //1定义成员变量DataSource
    private static DataSource ds;

    static {
        try {
			//1.加载配置文件
            Properties pro = new Properties();//创建properties属性集对象
			//读取druid.properties配置文件
            pro.load(JDBCUtils.class.getClassLoader().getResourceAsStream(name:"druid.properties"));
            //使用druid提供的api,获取DataSource
            ds = DruidDataSourceFactory.createDataSource(pro);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    /**
     * 获取连接
     */
    public static Connection getConnection() throws SQLException {
        return ds.getConnection();
    }

    /**
     * 释放资源
     * <p>
     * /**
     * 释放资源
     */
    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(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static DataSource getDataSource(){
        return ds;
    }


测试druid工具类

给account表增加一条数据,添加成功则控制台打印输出:录入数据的行数

public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;

        //给account表添加一条记录
        try {
            //获取数据
            conn = JDBCUtils.getConnection();
            //定义sql
            String sql = "insert into account(ID,NAME, password) value (NULL,?,?);";
            //获取PreparedStatement对象
            pstmt = conn.prepareStatement(sql);
            //给?赋值
            pstmt.setString(1, "zhangsan");
            pstmt.setInt(2, 1000);
            //执行sql
            int index = pstmt.executeUpdate();
            System.out.println(index);
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        } finally {
            JDBCUtils.close(pstmt,conn);
        }
    }
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值