Javaweb学习笔记——(十八)——————事务、DBCP、C3P0、装饰者模式

事务
    什么是事务?
        转账:
            1.给张三账户减1000元
            2.给李四账户加1000元

        当给张三账户减1000元之后,抛出了异常,这样会导致张三账户减了1000元,然后李四账户没有加上1000元。

        使用事务就可以处理这一问题:把多个对数据库的操作绑定成一个事务,要么都成功,要么都失败!

=====================================================

事务的特性:ACID
    *原子性:事务中的所有操作是不可再分割的原子单位。事务中所有操作要么全部执行成功,要么全部执行失败。
    *一致性:事务执行后,数据库状态与其他业务规则保持一致。如转账业务,无论事务执行成功与否,参与转账的两个账号余额之和应该是不变的。
    *隔离性:隔离性是指在并发操作中,不同事务之间应该隔离开来,使每个并发中的事务不会相互干扰。
    *持久性:一旦事务提交成功,事务中所有的数据操作都必须被持久化到数据库中,即使提交事务后,数据库马上崩溃,在数据库重启时,也必须能保证通过某种机制恢复数据。

=====================================================
    
MySQL操作事务
    1.开始事务:start transaction
    2.结束事务:commit或rollback

=====================================================

JDBC事务
    1.开始事务:conn.setAutoCommit(false);
    2.结束事务:conn.commit()或conn.rollback();

=====================================================

保存点
    保存点的是可以回滚到事务中的某个位置,而不是回滚整个事务。
    回滚到保存点不会结束事务。
    设置保存点:Savepoint sp = conn.setSavepoint();
    回滚到保存点:conn.rollback(sp);

=====================================================

事务隔离级别
    *脏读:读到未提交
    *不可重复读:两次读取不一致,读取到另一事务修改的记录
    *幻读:两次读取不一致,读取到另一事务插入的记录

----------------------------------------------------

四大隔离级别
    *SERIALIZABLE(串行化):对同一数据的访问是串行的,即非并发的,所以不会出现任何并发问题。易出现死锁,效率太低,不可用!
    *REPATABLE READ(可重复读):防止了脏读、不可重复读,但没有防止幻读。
    *READ COMMITTED(读已提交):防止了脏读,但没有防止不可重复读,以及幻读。
    *READ UNCOMMITTED(读未提交):可能出现所有并发问题,效率最高,但不可用。

    MySQL默认事务隔离级别是:REPEATABLE READ
    Oracle默认事务隔离级别为:READ COMMITTED

----------------------------------------------------

MySQL设置事务隔离级别
    *查看:SELECT @@tx_isolation
    *设置:set transaction isolation level 四选一

JDBC设置事务隔离级别
    conn.setTransactionIsolation(四选一)

=====================================================

数据库连接池
    作用:使用池来管理连接的生命周期,节省资源,提高性能。
    Java提供的连接池接口:javax.sql.DataSource,连接池厂商的连接池类需要实现这一接口。

----------------------------------------------------

DBCP
    jar:commons-pool.jar、commos-dbcp.jar

    BasicDataSource ds = new BasicDataSoure();
    ds.setUsername("root");
    ds.setPassword("123456");
    ds.setUrl("jdbc:mysql://localhost:3306/mydb1");
    ds.setDriverClassName("com.mysql.jdbc.Driver");

    ds.setMaxActive(20);
    ds.setMaxIdle(10);
    ds.setInitialSize(10);
    ds.setMinIdle(2);
    ds.setMaxWait(1000);

    Connection conn = ds.getConnection();

----------------------------------------------------

C3P0
    jar:
        c3p0-0.9.2-pre1.jar、
        c3p0-oracle-thin-extras-0.9.2-pre1.jar、
        mchange-commons-0.2.jar

    ComboPooledDataSource ds = new ComboPooledDataSource();
    ds.setJdbcUrl("jdbc:mysql://localhost:3306/mydb1");
    ds.setUser("root");
    ds.setPassword("123456");
    ds.setDriverClass("com.mysql.jdbc.Driver");

    ds.setAcquireIncrement(5);
    ds.setInitialPoolSize(20);
    ds.setMinPoolSize(2);
    ds.setMaxPoolSize(50);

    Connection conn = ds.getConnection();

----------------------------------------------------

C3P0配置文件
    1.通过默认配置初始化连接池
        ComboPooledDataSource ds = new ComboPooledDataSource();
        Connection conn = ds.getConnection();

        <default-config>
            <property name="xxx">XXX</property>
        </default-config>

    2.通过命名配置初始化连接池
        ComboPooledDataSource ds = new ComboPooledDataSource("oracle-config");
        Connection conn = ds.getConnection();

        <named-config name="oracle-config">
            <property name="xxx">XXX</property>
        </named-config>

=====================================================

Tomcat配置连接池
    在server.xml中,或在conf/catalina/localhost/下创建xml文件

    <Context>  
      <Resource name="myc3p0" 
                type="com.mchange.v2.c3p0.ComboPooledDataSource"
                factory="org.apache.naming.factory.BeanFactory"
                user="root" 
                password="123" 
                classDriver="com.mysql.jdbc.Driver"    
                jdbcUrl="jdbc:mysql://127.0.0.1/mydb1"
                maxPoolSize="20"
                minPoolSize ="5"
                initialPoolSize="10"
                acquireIncrement="2"/>
    </Context> 

----------------------------------------------------

获取Tomcat资源
    Context cxt = new InitialContext();
    DataSource ds = (DataSource)cxt.lookup("java:/comp/env/myc3p0");
    Connection conn = ds.getConnection();

=====================================================

修改JdbcUtils

public class JdbcUtils{
    private static DataSource dataSource = new ComboPooledDataSource();

    public static DataSource getDataSource(){
        return dataSource;
    }

    public static Connection getConnection(){
        try{
            return dataSource.getConnection();
        }catch(Exception e){
            throw new RuntimeException(e);
        }
    }
}

=====================================================

DBUtils
    jar:
        commons-dbutils.jar
    核心类:
        QueryRunner、ResultSetHandler

    QueryRunner方法:
        *update():DDL、DML
        *query():DQL
        *batch():批处理

----------------------------------------------------


    DataSource ds = JdbcUtils.getDataSource();
    QueryRunner qr = new QueryRunner(ds);
    String sql = "SELECT * FROM tab_student";

    //把结果集转换成Bean
    Student stu = qr.query(sql, new BeanHandler<Student>(Student.class));

    //把结果集转换成Bean的List
    List<Student> list = qr.query(sql, new BeanListHandler<Student>(Student.class));

    //把结果集转换成Map
    Map<String, Object> map = qr.query(sql, new MapHandler());

    //把结果集转换成List<Map>
    List<Map<String, Object>> list = qr.query(sql, new MapListHandler());

    //把结果集转换成一列的List
    List<Object> list = qr.query(sql, new CollumnListHandler("name"));

    //把结果转换成单行单列的值
    Number number = (Number)qr.query(sql, new ScalarHandler());

=====================================================

批处理
    DataSource ds = JdbcUtils.getDataSource();
    QueryRunner qr = new QueryRunner(ds);
    String sql = "INSERT INTO tab_student VALUES(?,?,?,?)";
    Object[][] params = new Object[10][]; //表示要插入10行记录
    for(int i = 0; i < params.length; i++){
        params[i] = new Object[]{"S_300"+i, "name"+i, 30+i, i%2=0?"男":"女"};
    }
    qr.batch(sql, params);

=====================================================
=====================================================


装饰者模式
    对象增强的手段
        *继承
            被增强的对象固定的
            增强的内容也是固定的
        *装饰者模式
            被增强的对象是可以切换的
            增强的内容是固定的
        *动态代理(AOP)
            被增强的对象可以切换:Service
            增强的内容也可以切换:事务处理

----------------------------------------------------

    继承:
        缺点:
            1.增强的内容是死的,不能动
            2.被增强的对象也是死的

        使用继承会使得类增多

        class 咖啡类{}

        class 有糖咖啡 extends 咖啡类 {
        }

        class 加奶咖啡 extends 咖啡类 {
        }

        class 加盐咖啡 extends 咖啡类 {
        }

        class 加糖加奶 extends 加奶 {
        }

----------------------------------------------------

    装饰者模式:
        1.增强的内容是不能修改的
        2.被增强的对象可以是任意的

        class 咖啡类{
        }

        class 有糖咖啡 extends 咖啡类 {
        }

        class 加奶咖啡 extends 咖啡类 {
        }

        class 加盐咖啡 extends 咖啡类 {
        }

        咖啡 a = new 加糖();
        咖啡 b = new 加盐(a);//对a进行装饰,就是给a加盐
        咖啡 c = new 加奶(b);


    Java API
    IO流

    四大家:
        1.字节:InputStream、OutputStream
        2.字符:Reader、Writer

    InputStream:
        FileInputStream:它是节点流,就是和一个资源绑定在一起的,文件
        BufferInputStream:它是装饰流,创建我是一定要给我一个底层对象,然后不管给的是什么流,都会给他添加缓冲流。

    new BufferedInputStream(任意的InputStream)

    FileInputStream fis = new FileInputStream("F:/a.jpg");
    BufferedInputStream bis = new BufferedInputStream(fis);
    ObjectInputStream ois = new ObjectInputStream(bis);

----------------------------------------------------

Connection conn = ...

装饰:不知道被增强·对象的具体类型时,可以使用

1,是你还是你,一起都是你

is a
has a
use a

class MyConnection implements Connection{//是你
    //还有你
    private Connection conn;//底层对象,被增强对象

    public MyConnection(Connection conn){//通过构造器传递底层对象
        this.conn = conn;
    }

    //一切拜托你
    public Statement createStatement(){
        return conn.createStatement();
    }

    //增强点
    public void close(){
        //把当前连接归还给池!
    }
}

Conneciton conn = 通过四大参数创建连接对象,是由Mysql提供的。
Connection conn1 = new MyConnection(conn);

conn1.createStatement();
conn.createStatment();

conn1.close();
conn.close();
        
}
 

转载于:https://www.cnblogs.com/changemax/p/10015061.html

JSP(JavaServer Pages)是一种服务器端的动态网页开发技术,它可以将 Java 代码嵌入 HTML 页面中,从而实现动态网页的生成。 JSP 的基本原理是将 JSP 页面翻译成 Servlet,在服务器端执行 Servlet 代码,再将执行结果返回给客户端。因此,我们在使用 JSP 开发网页时,需要先了解 Servlet 的相关知识。 JSP 的语法基本上就是 HTML 标签加上 Java 代码。以下是一些基本的 JSP 标签: 1. <% ... %>:嵌入 Java 代码,可以用于定义变量、写循环、判断语句等。 2. <%= ... %>:输出 Java 代码的执行结果。 3. <%-- ... --%>:注释,不会被翻译成 Servlet。 4. <jsp:include ... />:包含其他 JSP 页面或 HTML 页面。 5. <jsp:forward ... />:将请求转发到其他资源(JSP 页面、Servlet 或 HTML 页面)。 6. <jsp:useBean ... />:创建 JavaBean 对象。 7. <jsp:setProperty ... />:为 JavaBean 对象设置属性。 8. <jsp:getProperty ... />:取得 JavaBean 对象的属性值。 在 JSP 页面中,我们还可以使用 EL 表达式和 JSTL 标签库来简化代码编写,提高开发效率。 EL(Expression Language)表达式是一种简化的表达式语言,可以用于取值、赋值、计算等操作。例如,${name} 表示取得名为 name 的变量的值。 JSTL(JavaServer Pages Standard Tag Library)是一套标签库,提供了循环、条件判断、格式化、国际化等常用功能的标签。例如,<c:forEach> 标签可以用于循环遍历集合,<c:if> 标签可以用于条件判断。 除了以上标签库,JSP 还支持自定义标签库。我们可以通过编写标签处理器来扩展 JSP 的功能。 JSP 的优点是可以将 Java 代码嵌入 HTML 页面中,使得网页的开发更加灵活和方便。但是,由于 JSP 页面需要翻译成 Servlet,因此会增加服务器的负担和响应时间。此外,JSP 页面中夹杂着 Java 代码,也不利于代码的维护和调试。因此,在开发大型网站时,建议使用 MVC 设计模式,将业务逻辑和视图分离,使得代码更加清晰和易于维护。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值