数据库操作(事务,JDBC)

1.数据库多表之间的关系

在这里插入图片描述

2.上述关系之间的范式

  1. 注意:一对多的关系是在的一方建立外键,指向一的一方的主键
    在这里插入图片描述
  2. 注意:多对多的关系中,需要建立第三个表,其中至少有两个内容,且分别指向另外两个表的主键
    在这里插入图片描述
  3. 创作唯一外键的时候,注意要求是外键需要建立唯一外键(unique)

数据库事务

  1. 概念,一个包含多个步骤的业务操作,被事务管理,那么这些操作可以一起执行,要么同时成功, 要么同时失败
  2. 操作:
    • 开启事务:start transaction;
    • 回滚:rollback;(防止运行到一半出现错误)
    • 提交:commit;
      * 如果我们要手动提交,那么要先开启事务,再提交
      * 自动提交的话,就只需要一条DML语句mysql就会自动帮助提交一次事务
      * 查看现在是自动提交还是手动提交的方法
      * select @@autocommit ;其默认结果是1
      * set @@autocommit = 0;可以自己设置成0
    • 注意:如果是手动提交的话,那么我们修改的数据,如果没有commit那么,只是会临时改变,但是重启mysql后,又会回到原处
  3. 事物的四大特征
    • 原子性:不可分割的最小操作单位,要么同时成功,有么同时失败
    • 持久性:当食物提交或回滚后,数据库持久化的保存数据
    • 隔离性:多个事物之间,相互独立
    • 一致性:实务操作前后,数据总量不变

JDBC

  1. Java DataBase Connectivity Java 数据库连接,java连接数据库;其本质是官方定义的一套操作所有关系行动数据库的规则,即接口。各个数据库厂商去实现这套接口,提供数据库驱动的jar包。我们可以使用这套接口(JDBC)变成,真正执行的代码是驱动jar包中的实现类
  2. JDBC,定义了一套操作所有关系型数据库的规则(接口)
  3. JDBC快速入门
    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/student11","root","0916");
        //4.定义SQL语句
        String sql = "update score set math = 100 where id = 1";
        //5.获取执行SQL的对象
        Statement stmt = conn.createStatement();
        //6.执行SQL;
        int count = stmt.executeUpdate(sql);
        //7.处理结果
        System.out.println(count);
        //8.释放资源
        stmt.close();
        conn.close();
    }
  • 导入jar包的时候, 不要忘记将jar包所在的包,Add As library

用到的这些类都是借口

  • DriverManager:驱动管理对象
    - 功能:
    1. 注册驱动(DM里面有方法):告诉应该用的是哪一个数据库的驱动jar包
    static void registerDriver(Driver driver):注册于给定的驱动程序 DriverManager
    写代码使用的却是:Class.forName(“com.mysql.jdbc.Driver”);其中里面含有静态代码块
    注意:在mysql5之后的驱动jar包可以省略注册驱动的步骤Class.forName(“com.mysql.jdbc.Driver”);
    2. 获取数据库连接
    * 方法:static Connection getConnection(String url ,String user, String password)
    * 参数:
    * url:指定连接的路径
    - 语法:jdbc:mysql://IP地址(域名):端口号、数据库名称
    - 例子:jdbc:mysql”//localhost:3306/db3
    - 细节:如果链接的是本机mysql服务器,并且mysql服务默认端口是3306,则url可以简写为: jdbc : msql 😕//数据库名称
    - user
    - password
  • Connection(接口):数据库连接对象
    1. 功能:
    1. 获取SQL的对象
    - Statement createStatement()
    - PreparedStatement prepareStatement(String SQL)
    2. 管理事务 :
    - 开启事务:void setAutoCommit(boolean autoCommit): 调用该方法设置参数为false,级开启事务
    - 提交事务:commit()
    - 回滚事务:rollback()
  • Statement:执行SQL的对象
    1. 执行sql
    - boolean execute (String sql) : 可以执行任意的sql(只做了解即可)
    - int executeUpdate(String sql) : 执行DML(insert、 update、 delete)语句、DDL(对表和库进行)(create, alter , drop)语句;【注意:返回值是影响的行数,可以用以判断是否执行成功】
    - ResultSet executeQuery(String sql) :执行DQL(select)语句
    - 练习
    1. 对一个表,添加一条记录
    2. 修改记录
    3. 删除记录
    public static void main(String[] args) {
        Statement stmt = null;
        Connection conn= null;

        try {
            //1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2. 定义sql
            String sql = "insert into student1 values(2,'五liu7',36)";
            //3. 获取Connection对象
            conn = DriverManager.getConnection("jdbc:mysql:///student11", "root", "0916");
            //4. 获取执行SQL的对象 Statement
            stmt = conn.createStatement();
            //5. 执行SQL
            int count = stmt.executeUpdate(sql);
            //6. 处理结果
            System.out.println(count);
            if( count > 0 ){
                System.out.println("添加成功! ");
            }else{
                System.out.println("添加失败! ");
            }

        }catch (SQLException throwables) {
                throwables.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }finally{
//            stmt.close();     不可这样
            // 避免空指针异常

            //7. 释放资源
            //避免空指针异常
            if (stmt != null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
  • ResultSet:结果集对象(表的列就是结果集对象)
    - next():游标向下移动一行
    在这里插入图片描述
    - getXxx(参数):获取数据
    * XXX:代表数据类型, 如: int getInt(), String getString()
    * 参数:
    1. int:代表列的编号,从1开始 如: getString(1)
    2. String:代表列的名称 如: getDouble (“balance")
    * 注意:
    * 步骤如下在这里插入图片描述
    - 游标向下移动一行(游标原来在第一行之前)
    - 判断是否有数据
    - 获取数据(故:可以用while来判断游标是否是在最后一行末尾)

      * 练习:
      			1. 查询一个表的数据,将数据封装为对象,然后装在集合,返回
      			2. 敌营类
      			3. 定义方法 public List<emp> findAll(){ }
      			4. 实现方法 select * from emp;
    
public class EmpDemo006 {
    public static void main(String[] args) {
        List<Emp> list = new EmpDemo006().findAll();
        System.out.println(list);
        System.out.println(list.size());
    }

    /**
    * 查询所有emp对象
    * @return
    */

    public List<Emp> findAll(){
        Statement stmt = null;
        Connection conn = null;
        ResultSet rs = null;
        List<Emp> list = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql:///teachingmanagement", "root", "0916");
            //3.定义sql
            String sql = "select * from student";
            //4.获取执行SQL的对象
            stmt = conn.createStatement();
            //5.执行SQL
            rs = stmt.executeQuery(sql);
            //6.遍历结果集,封装对象,装载集合
            Emp emp = new Emp();
            list = new ArrayList<Emp>();
            while(rs.next()) {
                int stu_id = rs.getInt("stu_id");
                String name = rs.getString("name");
                String sex = rs.getString("sex");
                String birthday = rs.getString("birthday");
                int primary_score = rs.getInt("primary_score");
                int department_id = rs.getInt("department_id");
                //创建emp对象
                emp = new Emp();
                emp.setStu_id(stu_id);
                emp.setName(name);
                emp.setSex(sex);
                emp.setBirthday(birthday);
                emp.setPrimary_score(primary_score);
                emp.setDepartment_id(department_id);
                //装载集合
                list.add(emp);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            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();
                }
            }
        }
        return list;
    }

注意:上面的这些方法,重复度太高,想要通过一个工具类,将代码进行简化

抽取JDBC工具类:JDBCUtils

  • 目的:简化书写
  • 分析:
    1. 注册驱动抽取
    2. 抽取一个方法获取连接对象
    * 需求:不想传递参数,还得保证工具类的通用性
    * 解决方法:配置文件
    jdbc.properties
    url =
    user =
    password =
url = jdbc:mysql:///teachingmanagement
user = root
password = 0916
driver = com.mysql.jdbc.Driver
登录练习
* 需求:
		1. 通过键盘录入用户名和密码
		2. 判断用户是否登录成功
				* select * from user where username = " " and password = " " ;
				* 如果这个SQL有查询结果,则成功,否则失败
* 步骤
		1. 创建数据库表 user
		2. 将properties中的数据库名称更改
		3. 创建一个新的boolean方法(含有用户名和密码的字符参数)
				1. 先判断用户名和密码不是空,是则返回false
				2. 获取连接
				3. 定义SQL
				4. 获取执行SQL的对象
				5. 执行查询
				6. 判断
				7. psvm中进行键盘录入,接受用户名和密码
				8. psvm中调用方法
				9. 然后判断并输出
  1. 抽取一个方法来释放资源
  • PreparedStatement:执行SQL的对象,但是比其父类Statement功能更强大
    1. SQL注入问题:在拼接SQL时,有一些SQL的特殊关键字参与字符串的拼接,会造成安全性问题
      1. 输入用户名随便,输入密码: a’ or ‘a’ = 'a
      2. sql:select * from user where username = ‘dsajidjowjdio’ and password = ‘a’ or ‘a’ = ‘a’
    2. 解决SQL注入问题:使用PreparedStatement对象来解决在这里插入图片描述

数据库连接池

  1. Spring JDbc:
  2. 概念:一个容器(集合),存放数据库连接的容器
  3. 过程:当系统初始化好后,容器被创建,容器中会申请一些链接对象,当用户访问数据库时,从容器中获取链接对象,用户访问完后,会将链接对象归还给容器
  4. 好处:节约系统的资源,高效
  5. 实现:
    1. 标准接口:DataSource javax.sql包下的
    2. 获取连接诶:getConnection()
    3. 归还链接:如果连接对象COnnection是从连接池中获取的,那么调用Connection.close方法,则不会再关闭连接了,而是归还链接
    4. 用数据库厂商来实现
    5. C3P0:数据库连接池技术
    6. Druid:数据库连接池实现技术,有阿里巴巴提供的(性能高)
  6. C3P0使用步骤
    1. 导入jar包
    2.
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值