天天看点

JDBC/Druid/JdbcTemplate操作数据库前言jdbc操作数据库druid操作数据库

前言

本文重在展示jdbc、druid、jdbcTemplate三种方式操作数据库(Mysql)。

搭配其他文章与自己实际操作为佳。如有错误还请指正

jdbc操作数据库

jdbc是java语言操作数据库,即对数据库数据做增删查改操作,事务操作等。

使用步骤

1. 导入jar包
	mysql-connector-java-5.1.37-bin.jar
2. 注册驱动
3. 获取数据库连接对象 Connection
4. 定义sql
5. 获取执行sql语句的对象 Statement
6. 执行sql,接收返回结果
7. 释放资源
           

 具体实现实例

//1. 导入驱动jar包
//2.注册驱动
Class.forName("com.mysql.jdbc.Driver");
//3.获取数据库连接对象
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/One", "root", "pass");
//4.定义sql语句
String sql = "update account set balance = 500 where id = 1";
//5.获取执行sql的对象 Statement
Statement stmt = conn.createStatement();
//6.执行sql
int count = stmt.executeUpdate(sql);
//7.处理结果
System.out.println(count);
//8.释放资源
stmt.close();
conn.close();
           

 详解对象

1. DriverManager:驱动管理对象
	* 功能:
	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 (SQLException 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:密码 
2. Connection:数据库连接对象
	1. 功能:
		1. 获取执行sql 的对象
			* Statement createStatement()
			* PreparedStatement prepareStatement(String sql)  
		2. 管理事务:
			* 开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务
			* 提交事务:commit() 
			* 回滚事务:rollback() 
3. Statement:执行sql的对象
	1. 执行sql
		1. boolean execute(String sql) :可以执行任意的sql 了解 
		2. int executeUpdate(String sql) :执行DML(insert、update、delete)语句、DDL(create,alter、drop)语句
			* 返回值:影响的行数,可以通过这个影响的行数判断DML语句是否执行成功 返回值>0的则执行成功,反之,则失败。
		3. ResultSet executeQuery(String sql)  :执行DQL(select)语句
		
4. ResultSet:结果集对象,封装查询结果
		* boolean next(): 游标向下移动一行,判断当前行是否是最后一行末尾(是否有数据),如果是,则返回false,如果不是则返回true
		* getXxx(参数):获取数据
			* Xxx:代表数据类型   如: int getInt() ,	String getString()
			* 参数:
				1. int:代表列的编号,从1开始   如: getString(1)
				2. String:代表列名称。 如: getDouble("balance")
		
		* 注意:
			* 使用步骤:
				1. 游标向下移动一行
				2. 判断是否有数据
				3. 获取数据
5. PreparedStatement:执行sql的对象
		1. SQL注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接。会造成安全性问题
			1. 输入用户随便,输入密码:a' or 'a' = 'a
			2. sql:select * from user where username = 'fhdsjkf' and password = 'a' or 'a' = 'a' 

		2. 解决sql注入问题:使用PreparedStatement对象来解决
		3. 预编译的SQL:参数使用?作为占位符
		4. 步骤:
			1. 导入驱动jar包 mysql-connector-java-5.1.37-bin.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:?的值
					如:pstmt.setString(1,"username");
			7. 执行sql,接受返回结果,不需要传递sql语句
			8. 处理结果
			9. 释放资源

		5. 注意:后期都会使用PreparedStatement来完成增删改查的所有操作
			1. 可以防止SQL注入
			2. 效率更高
           

使用JDBC操作数据库

查看jdbc库中的user表数据:

//导包
        //注册驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获取数据库连接
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC","root","pass");
        //定义sql
        String sql = "select id,name from user";
        //获取sql的执行对象Statement
        Statement stmt = conn.createStatement();
        //执行sql
        ResultSet rs = stmt.executeQuery(sql);
        while(rs.next()){
            String id = rs.getString("id");
            String name = rs.getString("name");
            System.out.println(id + " - " + name);
        }
        //关闭连接
        rs.close();
        stmt.close();
        conn.close();
           

往jdbc库中的user表插入数据如“XXX”,“123”:

Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
		//插入数据
        String sql = "insert into user values('XXX','123')";
		//更新数据
		//String sql = "update user set name = '456' where id = 'XXX'";
		//删除数据
		//String sql = "delete from user where id = 'XXX'";
        Statement stmt = conn.createStatement();
        int i = stmt.executeUpdate(sql);
        System.out.println(i);
        stmt.close();
        conn.close();
           

修改jdbc库中user表的id = “XXX”对应的name为“456”:增删改的执行操作都是executeUpdate(),区别在sql语句而已,返回的是修改行数;

而查的执行操作是executeQuery(),返回的是一个结果集resultSet

jdbc操作事务

使用Connection对象来管理事务

        开启事务:setAutoCommit(boolean autoCommit) :调用该方法设置参数为false,即开启事务

        在执行sql之前开启事务

        提交事务:commit() 当所有sql都执行完提交事务

        回滚事务:rollback() 在catch中回滚事务

/**
 * aaa向bbb转账 
 */
public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "pass");
            //开启事务
            conn.setAutoCommit(false);
            String sql1 = "update balance set balance = ? where username = ?";
            String sql2 = "update balance set balance = ? where username = ?";
            pstmt1 = conn.prepareStatement(sql1);
            pstmt2 = conn.prepareStatement(sql2);
            pstmt1.setInt(1,500);
            pstmt1.setString(2,"aaa");
            pstmt2.setInt(1,1500);
            pstmt2.setString(2,"bbb");
            pstmt1.executeUpdate();
            pstmt2.executeUpdate();
        } catch (ClassNotFoundException | SQLException e) {
            try {
                //回滚事务
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        } finally {
            try {
                //提交事务
                conn.commit();
                pstmt1.close();
                pstmt2.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
           

druid操作数据库

druid数据库连接池,避免了jdbc频繁创建关闭连接的过程。

使用步骤

//导包:druid-1.2.5.jar 、mysql-connector-java-8.0.22.jar
//定义配置
//加载配置
Properties properties = new Properties();
InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
properties.load(is);
//获取数据库连接池
dataSource = DruidDataSourceFactory.createDataSource(properties);
//获取连接
conn = dataSource.getConnection();
//往下与jdbc一样
           

读取jdbc库中balance表的数据:

public static DataSource dataSource;
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try{
            //定义配置
            Properties properties = new Properties();
            InputStream is = DruidDemo1.class.getClassLoader().getResourceAsStream("druid.properties");
            //加载配置
            properties.load(is);
            //创建数据库连接池
            dataSource = DruidDataSourceFactory.createDataSource(properties);
            //获取连接
            conn = dataSource.getConnection();
            //定义sql
            String sql = "select username,balance from balance";
            //获取执行对象
            pstmt = conn.prepareStatement(sql);
            //获取结果集
            rs = pstmt.executeQuery();
            while(rs.next()){
                String username = rs.getString("username");
                String balance = rs.getString("balance");
                System.out.println(username + " " + balance);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                rs.close();
                pstmt.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
           

 往jdbc库中的balance表插入数据行”ddd“,1000:

private static DataSource dataSource;
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        try{
            Properties pro = new Properties();
            InputStream is = DruidDemo2.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            dataSource = DruidDataSourceFactory.createDataSource(pro);
            conn = dataSource.getConnection();
            String sql = "insert into balance values(?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1,"ddd");
            ps.setInt(2,1000);
            int i = ps.executeUpdate();
            System.out.println(i);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try{
                ps.close();
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
           

增删查改跟jdbc大同小异,其思想就是对数据库连接的池化。

druid处理事务

跟jdbc操作事务基本相似。

jdbcTemplate操作数据库

使用步骤

//导包
commons-logging-1.2.jar
spring-beans-5.0.0.RELEASE.jar
spring-core-5.0.0.RELEASE.jar
spring-jdbc-5.0.0.RELEASE.jar
spring-tx-5.0.0.RELEASE.jar
           

 使用jdbcTemplate查询数据库数据:

private static DataSource dataSource;
    public static void main(String[] args) {
        try{
            //定义配置
            Properties pro = new Properties();
            InputStream is = JdbcTemplate1.class.getClassLoader().getResourceAsStream("druid.properties");
            //加载配置
            pro.load(is);
            //创建数据池连接
            dataSource = DruidDataSourceFactory.createDataSource(pro);
            //创建jdbcTemplate实例对象
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            String sql = "select * from balance";
            //获取结果集
            List<Map<String, Object>> list = jdbcTemplate.queryForList(sql);
            for (Map<String, Object> stringObjectMap : list) {
                System.out.println(stringObjectMap);
            }
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
           

 使用jdbcTemplate增删改数据:

private static DataSource dataSource;
    public static void main(String[] args) {
        try{
            Properties pro = new Properties();
            InputStream is = JdbcTemplate2.class.getClassLoader().getResourceAsStream("druid.properties");
            pro.load(is);
            dataSource = DruidDataSourceFactory.createDataSource(pro);
            JdbcTemplate jdbcTemplate = new JdbcTemplate(dataSource);
            String sql = "insert into balance values(?,?)";
            int update = jdbcTemplate.update(sql,"eee",1000);
            //String sql = "update balance set balance = ? where username = ?";
            //int update = jdbcTemplate.update(sql, 100, "eee");
            //String sql = "delete from balance where username = ?";
            //int update = jdbcTemplate.update(sql, "eee");
            System.out.println(update);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
           

不需要手动关闭连接。