知识点总结

1:什么是数据库的事务?

事务就是DBA(数据库管理员)操作多个sql的时候,可能有一条执行语句可能异常了,其他sql不执行了,就会导致出现紊乱,

将整个sql(多个sql)的执行看成一个"整体",要么同时执行成功,要么同时执行失败!

始终保证的数据的一致性(高并发中,读/写)

2:传统事务特点(重点)ACID

原子性:执行的某业务操作,同时操作多个sql(增删改),要么同时执行成功,要么同时执行失败!

一致性:在实际开发中,多个线程同时去写和读的时候,数据必须一致性

隔离性:事务和事务之间(业务和业务之间)相互独立的, 互不影响!

持续性:就是对增删改这些sql语句,一旦事务提交了,对数据库中表的操作是永久性,即使关机了,数据永久保存!

3:传统事务的隔离级别

读未提交:read uncommited;一个事务读取到另一个没有没有提交的事务(最不安全),出现"脏读" (最严重的问题!) 

读已提交:read committed; 有效防止脏读! 会出现另一种问题"不可重复读", 读取到自己本身没有提交的事务的数据前后两次不一致,本身这个事务没有提交,多次读取到的数据必须一致! 

可重复读 :mysql的默认隔离级别 (repetable-read) /* 有效防止脏读,不可重复读,可能出现"幻读"  -串行话:serializable

4:jdbc的本质是什么?

Jdbc是一个普通的Java类,是数据库厂商提供的驱动jar包,可以实现sun提供一套接口规范!

java.sql.Driver:驱动接口---->驱动jar包--->实现了这个接口

java.sql.Connection:数据库的连接会话--->驱动jar包--->ConnectionImpl实现了这个接口

5:jdbc的7大操作步骤,代码体现

// 7大步骤 后期--->开源框架:就是对原生Jdbc代码的封装+一些配置文件
//1)导入驱动jar包 --mysql-connnecto-java驱动jar包  
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ; 
//3)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"123456") ;
//4)准备sql语句:DDL语句或者DML语句
String sql = "insert into employee(name,age,gender,birthday,address) values(xxx,xx,xx,xx,xx,xx)" ;
//5)通过连接对象获取执行对象Statement 
Statement stmt  = conn.createStatement() ;
//6)执行sql,通用的更新
int count = stme.executeUpdate(sql) ;
//7)释放资源
stmt.close() ;
conn.close() ;

6:jdbc针对DQL语句,遍历结果集

//1)导入驱动jar包 --mysql-connnecto-java驱动jar包  
//2)注册驱动
Class.forName("com.mysql.jdbc.Driver") ; 
//3)获取数据库的连接对象
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/库名",
"root",
"123456") ;
//4)准备sql语句:DDL语句或者DML语句
String sql = "select 指定的字段列表  from 表名" ;
//5)通过连接对象获取执行对象Statement 
Statement stmt  = conn.createStatement() ;
//6)执行sql,通用的查询操作
ResultSet rs = stmt.executeQuery(sql) ;

//遍历结果集
while(rs.next()){
    //获取数据
    //通用的写,列的名称获取/列的索引值获取
    XXX 变量= rs.getXXX("字段名称") ;
    //自己封装数据...
}

//7)释放资源
stmt.close() ;
conn.close() ;

7:自定义工具类JdbcUtils的步骤

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/库名
user=root
password=123456

class JdbcUtils{
    private static String user = null ;
    private static String password = null ;
    private static String driverClass = null ;
    private static String url = null ;
    
    //定义static代码块
    static{
        //读取配置文件
        Properties prop = new Properties() ;
        //获取key对应的value,赋值给上面四个成员变量
        InputStream inputStream = JdbcUtils.class.getClassLoader().getResourceAsStream("jdbc.properties") ;
        user = prop.getProperty("user") ;
        password = prop.getProperty("password") ;
        url = prop.getPrpperty("url") ;
        driverClass = prop.getProperty("driverClass") ;
        //注册驱动
        Class.forName(driverClass) ;
    }
    
    
 
    private JdbcUtils(){}
    public static Connnection getConnection(){
            Connection conn = DriverManager.getConnection(url,user,password) ;
        return conn ;
    }
    //释放资源
    //带三个参数:ResultSet ,Statment,Connection---针对DQL语句操作
    //带两个参数:Satement,Connection--->针对DML语句
}

8:junit单元测试的使用步骤

1)导入junit的核心包: 4.13.1以及依赖包

2)建立测试类---XXXTest

3)定义单元测试方法,在方法上加入@Test

4)方法中要么Assert断言,要么直接测试指定功能(XXXDao--->添加,删除,修改,查询的功能)

9:Statement和PreparedStatement的区别?

1)共同点: 都是可以发送sql到数据库的,都是执行对象,后者继承前者(java.sql.包下的接口)

2)不同点:

2.1)是否会造成sql注入

Statement永远执行的是静态sql语句:语句中存在"硬编码",存在SQL的字符串拼接,就造成sql注入,不安全!

PreparedStatement:永远执行的是参数化的sql语句,全部参数都是"?", 占位符号,有效防止sql的拼接,预防sql注入,提高执行sql的安全性!

2.2)是否会提高sql执行效率

Statement:不会提高sql执行效率, 获取执行对象,然后将sql语句发送数据库(没写一个sql,发一次!),频繁的操作访问数据库

PreparedStatement:大大提高SQL执行效率 参数化sql是在获取PreparedStatement,就已经发送给数据库了,然后在PreparedStatement赋值不同的值;

10:德鲁伊Druid配置文件的参数说明

#这些名称都是DruidDataSoure提供的参数
#连接数据库的驱动类
driverClassName=com.mysql.jdbc.Driver   
#连接数据库的url地址:统一资源定位符
url=jdbc:mysql://localhost:3306/myee2302_db_2
#用户名
username=root
#密码
password=123456
#连接池一旦创建,初始化5个连接数量
initialSize=5
#最大连接数量值:默认值8个,自己设定值,和maxIdel:最大空闲数量相等
maxActive=10
#最大等待时间:为毫秒值,一旦连接池中创建连接对象超过了最大连接数量,等待3秒中,如果还连接不上,连接池会产生错误日志,提示"连接超时"
maxWait=3000

11:什么视图 ?

就是一个虚拟表:只是定义视图,表的数据来源于基础表中的(数据库中真实存在表)

作用:保证数据的安全性/简单性(快速查看到真实表的结构,类型....)

12:创建视图

CREATE VIEW <视图名> AS <SELECT语句>
CREATE VIEW view_employee AS 
SELECT 
  id,
  NAME,
  gender,
  age,
  salary,
  address,
  birthday 
FROM
  employee ;
  -- 查看视图的内容
 SELECT * FROM view_employee ;
 -- 查看视图的结构---查询表的结构语法相同
 -- 查询基础表(employee) 它的结构
 DESC employee ;
 -- 查询指定视图的结构
 DESCRIBE view_employee ; -- 简写成功desc 视图名称;
 
 -- 查询当前库中的所有表以及视图的名称
 SHOW TABLES ;
 
 -- 查询当前库中的所有表以及视图的名称以及后面的table_type:表类型
 SHOW FULL TABLES ;
 
 
 -- 修改视图的内容
 -- ALTER VIEW <视图名> AS <SELECT语句>

ALTER VIEW view_employee 
AS 
SELECT 
      id,NAME,salary  FROM employee ;
 
 
 
 -- 更新视图(视图添加数据/修改数据/删除数据,会直接影响基础表的内容,
 -- 一般很少去使用视图去更新基础表的内容)
 UPDATE  view_employee  SET NAME = '姚笛' WHERE id = 2 ;
 
 SELECT * FROM view_employee ;
 
 -- 删除视图:就是drop  view 视图名称,多个视图名称;
 -- 只是的删除视图的定义,不会影响基础表的任何内容
 DROP VIEW view_employee ;
  
  
 -- 查询employee基础表的内容
 SELECT * FROM employee ;
 
 -- 重命名视图跟表的重命名语法一样
 -- renname  table 视图名 to 新视图名;
 
 CREATE VIEW my_view AS SELECT * FROM employee ;
 
 SELECT * FROM my_view ;
 
 RENAME TABLE my_view TO view_emp;
 

13:Druid使用步骤

/**
 * Druid连接池的使用步骤:
 *      1)导包 druid-1.1.10.jar包
 *      2)准备好连接池的配置文件
 *      3)从连接池获取连接对象
 *          提供jar包--->com.alibaba.druid.pool.DruidDataSource--->本质实现了一个接口javax.sql.DataSource
 *              --->Connection getConnection()
 *
 */
public class DruidDemo {
    public static void main(String[] args) throws Exception {

        //3)创建数据源DruidDataSource对象
        //德鲁伊提供的数据源工厂:DruidDataSourceFactory提供静态方法,返回值就是DataSource
        //public static DataSource createDataSource(Properties properties)
        //创建属性集合列表
        Properties prop = new Properties() ;

        //读取src下配置文件
        InputStream inputStream = DruidDemo.class.getClassLoader().getResourceAsStream("druid.properties");
        //将字节输入流加载进来
        prop.load(inputStream) ;

        DataSource dataSource = DruidDataSourceFactory.createDataSource(prop);
        for(int x = 1 ; x <=11 ; x++){
            //System.out.println(dataSource.getConnection());
            Connection conn = dataSource.getConnection() ;
            if(x==3){
                conn.close(); //暂时释放,归还连接池中
            }
            System.out.println(conn);
        }

14:加入连接池自定义工具的步骤

Jdbc方式---加入Druid连接池,----自动的封装配置文件的所有数据

封装一个静态方法--->获取Connection(从连接池获取)

获取DataSource:数据源----> 连接参数(数据库的信息)以及初始化数量,最大激活数量,最大等待时间

释放资源

public class DruidJdbcUtils {

    //静态实例--->java.lang.ThreadLocal<T>  模拟线程,每一个用户都有自己的Connection
    private static ThreadLocal<Connection> tl = new ThreadLocal<>() ; //里面没有连接对象
    //声明一个DataSource接口类型 变量
    private static DataSource ds ;

    //构造方法私有化
    private DruidJdbcUtils(){}

    //静态代码块
    static{
        try {
            //1)读取德鲁伊的配置文件,让德鲁伊自己封装配置文件参数
            InputStream inputStream = DruidJdbcUtils.class.getClassLoader().getResourceAsStream("druid.properties");
            //创建属性集合列表
            Properties prop = new Properties() ;
            //加载属性集合列表
            prop.load(inputStream) ;
            //2)创建DruidDataSource(连接池)
            ds = DruidDataSourceFactory.createDataSource(prop) ;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取DataSource数据源信息 (连接池的所有参数)
    public static DataSource getDataSource(){
        return  ds ;
    }

    //从数据源(连接池) 获取连接对象
    public static Connection getConnection(){
        //1)线程本地线程中获取连接对象---ThreadLocal<T>--->T get():从当前线程中获取存储的内容
        Connection conn = tl.get() ;
        try {

            //2)判断
            //如果当前conn对象为null,说明当前线程中没有要操作的连接对象
            if(conn==null){
                //3)从数据源(连接池中)获取Connection
                conn = ds.getConnection();
                //4)将从数据源中获取到的conn连接对象,绑定当当前线程中
                //ThreadLocal<T>--->public void set(T t):绑定
                tl.set(conn) ;
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
        return conn ;
    }

    //释放资源
    public static void  close(ResultSet rs, PreparedStatement stmt, Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
                //从当前线程解绑
                tl.remove();  //ThreadLocal<T> :从线程中移出
            } catch (SQLException throwables) {
                throwables.printStackTrace();

            }
        }
    }

    //主要针对DDL/DML语句操作释放资源
   /* public static void close(Statement stmt,Connection conn){
        close(null,stmt,conn);
    }*/
    public static void close(PreparedStatement stmt,Connection conn){
        close(null,stmt,conn);
    }

    public static void main(String[] args) {


        System.out.println(DruidJdbcUtils.getDataSource());
        System.out.println(DruidJdbcUtils.getConnection());
    }
}

15:连接池的好处

节省资源:当前连接池(DataSource接口)创建之后,就会初始化一些连接对象,节省连接对象的创建;

重复利用:当某个线程持有的连接对象被使用完之后,归还连接池等待下次利用;

提高性能:连接池中:只需要配置好这些连接参数(最基本参数:数据库的相关信息)/连接池中的优化参数,DataSource里的实

现类---DruidDataSource自己封装这里面的所有连接参数;(还可以不断监控连接池中连接数量的变化)

16:使用PreparedStatement完成jdbc操作:DQL语句操作

//导包 (驱动jar包)
//注册驱动
Class.forName("com.mysql.jdbc.Driver") ;
//获取数据库连接对象
Connection conn = DriverManager.getConnecton(
"jdbc:mysql://localhost:3306/库名",
"用户名",
"密码") ;
//sql
String sql = "select * from employee where id = ?" ;
//通过数据库连接对象获取预编译对象,同时发送参数化sql到数据库
PreparedStatement ps = conn.prepareStatement(sql) ;
//对参数进行赋值
ps.setInt(1,id实际值) ;
//通过赋值执行sql语句
Resultset rs = ps.executeQuery() ;
//遍历结果集,封装数据
while(rs.next()){
//获取,封装数据到实体对象中
类名 对象名 = new 类名() ;
对象名.setXXX属性名称(rs.getXXX("column名称")) ;
}
//释放资源
//关闭结果集,关闭预编译对象,关闭连接对象

17:jdbc控制事务

转账业务操作:

同时操作多个账户内容(更新),这些更新语句要么同时执行成功,要么同时执行失败!

public void setAutoCommit(boolean auto) ;参数为true,表示自动提交,如果是false,手动提交

void rollback():事务回滚,撤销之前所有更改,必须释放连接对象,连接对象需要从线程中解绑

void commit():提交事务,将更改数据永久保存,提交完毕,释放连接对象,需要从线程中解绑

18:什么是事务?

针对多个sql或者多张表的sql(增删改),要么同时执行成功,要么同时执行失败,应该将整个业务看成一个整体,一块执行!

事务的特点:原子性,一致性,隔离性,持久性

19:commons-dbutils的使用步骤:

 1)导包 commons-dbutils-1.6.jar
    2)创建执行器 QueryRunner---> 底层PreparedStatement
     public QueryRunner(DataSource ds) 参数就是数据源--->自定义工具获取到了数据源 (自动提交)
     public QueryRunner():创建执行器,手动提交


   3)准备好sql语句
        DML语句---添加/修改/删除
                  insert into
                  update
                  delete from...

        QueryRunner提供通用的更新操作:
        public int update(Connection conn, String sql, Object... params) throws SQLException  :手动提交
        public int update(String sql, Object... params):自动提交


        DQL语句--- 查询语句

        QueryRunner提供的通用查询操作
        public <T> T query(String sql, ResultSetHandler<T> rsh, Object... params) throws SQLException
        第一个参数:查询的sql语句
        第二个参数:ResultSetHandler结果集的处理
                    它的子实现类:BeanHandler---->将查询的某一条记录封装到实体了中(JavaBean:是具体类,属性私有,对外提供setXXX()/getXXX)
                    public BeanHandler(Class<T> type) --->  参数针对查询的记录--封装到类名.class中

                    子实现类:BeanListHandler<T>    ---将查询的多条记录封装到List集合中,List集合都是当前类对象

                     public BeanListHandler(Class<T> type)
                    子实现类:

                        ScalarHandler:通过聚合函数(count(列名称),其他max(xx),avg(xxx))查询单行单的列的数据
                        的结果封装到Object类中
        第三个参数:就是赋值的实际参数params,没有参数可以不写

注意事项:


    使用commons-dbutils工具库:无论添加/删除/修改/查询数据,
        必须保证实体类的属性名称和表的字段名称一一对应,否则数据封装不上去的,永远是null!
        如果不对应,可以在(查询语句)--->给这字段给别名(保证别名和实体类的属性名称一致)

        实体类的属性名称不要出现大写字母,否则也可能是null值!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值