JDBC和数据库连接池

简介

JDBC:数据库连接,是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java编写的类和接口组成。

使用步骤

 

1.引入jar文件.

2.加载数据库驱动(JavaSE项目中可以省略,Javaweb项目必须编写此步骤)

class.forName ("com.mysq1.jdbc.Driver");

3.通过驱动管理器,获取JDBC连接对象.

connection conn = DriverManager.getConnection("数据库连接地址", "帐号", "密码");

    //数据库连接地址格式:主协议:子协议://ip地址:端口号/数据库名称

    //mysql的连接地址: jdbc:mysql://loca1host: 3306/java35

    //oracle的连接地址: jdbc:oracle:thin:@loca7host:1521:ORCL

4.通过连接对象,创建SQL执行对象(SQL执行环境)

statement state = conn. createstatement();

5.通过SQL执行对象﹑,执行sQL语句.

state.execute(string sq1语句)

6.释放资源

state.close();

conn.close();

public class Demo1 {
    public static void createTable() throws ClassNotFoundException, SQLException {
        /*
            加载数据库驱动
               mysql6以下驱动:com.mysql.jdbc.Driver
               mysql6及以上驱动:com.mysql.cj.jdbc.Driver
        */
        Class.forName("com.mysql.jdbc.Driver");

        /*
            通过驱动管理器,获取JDBC连接对象
               数据库连接地址:主协议:子协议://ip地址:端口号/数据库名
         */
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test02", "root", "");

        //通过连接对象,创建SQL执行对象
        Statement state = conn.createStatement();

        /*
            state.execute():
                执行任何SQL语句,返回值不代表SQL执行是否成功或者失败
                如果有结果集就返回true,没有结果集合返回false
            state.executeQuery():
                执行后返回查询的结果集
            state.executeUpdate():
                返回SQL语句影响的行数
         */
        ResultSet resultSet = state.executeQuery("select * from msg");
        while (resultSet.next()){
            int id = resultSet.getInt("id");
            String number = resultSet.getString("学号");
            String name = resultSet.getString("姓名");
            System.out.println(id+" "+number+" "+name);
        }

        //释放资源
        resultSet.close();
        state.close();
        conn.close();
    }
}

1 111 vv
2 222 qq
3 333 aa

SQL注入问题

 

当我们在实现登录功能的时候,需要根据用户输入的账户密码,在数据库中查找是否存在该用户的信息。

我们的查询语句可能是这样

state.executeQuery("select * from xzk_user where username='"+username+"' and password='"+password+"'");

但是如果我们输入的username="zhangsan",password="  1'or'1'='1'  "时,SQL语句就变成了

state.executeQuery("select * from xzk_user where username='zhangsan' and password='1' or '1'='1'");

or 后面的那个式子就是个永真式

解决方法:将代码与参数分离

PreparedStatement

原理:

1. 将未拼接参数的SQL语句, 作为SQL指令, 先传递给数据库进行编译.

2. 再将参数传递给数据库, 此时传递的参数不会再作为指令执行, 只会被当作文本存在

PreparedStatement Statement 谁的性能高 ?
 
看是什么数据库

 

mysql, preparedStatement原理是拼接SQL, 所以Statement性能高.

Oracle, preparedStatement原理是对SQL指令进行预处理, 再传递的参数不具备特殊含义.有更好的SQL缓存策略,PreparedStatement.

JDBC事务操作

 

JDBC 事务通过连接对象开启 , 回滚 , 提交 . 只针对当前连接对象生效 .

 

- 开启事务: conn.setAutoCommit(false);(自动是每次执行SQL都会提交一次事务)

- 回滚事务: conn.rollback();

- 提交事务: conn.commit();

 

数据库连接池

Properties 作为配置文件

Properties 类 是 Java 中的 Map集合的实现类,用于通过文件描述一组键值对,可以快速的转换为 Properties 类的对象 .
 
文件内容都是字符串 , 键与值之间通过等号连接 , 多个键值对之间换行分割 .
 
例如 :
 
url=xxx
 
user=xxx
 
password=xxx
 

将文件转化为集合的步骤

  1. 创建Properties对象 Properties ppt = new Properties();

  2. 创建一个字节输入流指向.properties文件:InputStream is = new FileInputStream("文件地址");

  3. 将字节输入流, 传递给properties对象, 进行加载:ppt.load(is); 

 

连接池的使用

连接池用于缓存连接

当我们需要使用连接时, 可以不用再创建连接 , 可以直接从连接池中获取连接 .
 
注意 :
 

使用连接池中的连接对象操作数据库时, 操作完毕依然需要释放连接(调用close()).

连接池中的连接在设计时, 使用了动态代理设计模式+装饰者设计模式 . 我们调用它的close方法, 代理没有关闭这个连接, 而是将连接重新放入了池中.

 

druid连接池的使用步骤

  1. 引入相关的jar文件:druid-1.0.9.jar
  2. 将配置文件引入
  3. 将配置文件, 转换为Properties对象: Properties ppt = new Properties();    ppt.load(配置文件的输入流);
  4. 通过连接池的工厂类(DruidDataSourceFactory)的创建连接池的方法(createDataSource()) DataSource ds = DruidDataSourceFactory.createDataSource(ppt);
  5. 从连接池中 获取连接对象:Connection conn = ds.getConnection();

工具类

public class DruidUtil {

    private static DataSource ds;//连接池
    static {
        Properties ppt = new Properties();//配置文件
        try {
            ppt.load(DruidUtil.class.getClassLoader().getResourceAsStream("druid.properties"));
            ds = DruidDataSourceFactory.createDataSource(ppt);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 从连接池中取出一个连接
     */
    public static Connection getConnection(){
        try {
            return ds.getConnection();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }
    /**
     * 释放资源
     */
    public static void close(Connection conn, Statement state, ResultSet rs){
        try {
            conn.close();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }
        try {
            state.close();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }
        try {
            rs.close();
        } catch (Exception throwables) {
            throwables.printStackTrace();
        }
    }
}

实例:使用JDBC实现多表查询 ***

1、一对多关系

学生表和年级表,学生是多的那方,年级是一的那方。

     

数据库是通过外键列来维持两个表的关系,实体类是通过属性来维持两表关系。在建立一对多关系时,我们在一方的属性里面加一个多方的一个属性。口诀:一方存多方的集合,多方存一方的对象

    

查询数据库代码:

2、多对一关系

在上面的基础上,我们需要在多方添加一方的对象,多方存一方的对象

3、多对多关系

多对多关系必须是基于三张表实现的。比如菜单表和角色表,某个功能菜单可以分配给多个角色,某个角色可以拥有多个菜单。

中间表不需要声明实体类,多方存另一方的集合

        

    

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值