• 【ActiveJdbc】05


    一、事务

    通常在 Java ORM 中有一个显式连接或管理器对象(JPA 中的 EntityManager,Hibernate 中的 SessionManager 等)。

    ActiveJDBC 中没有这样的对象。

    下面是一个没有事务管理的最基本的 ActiveJDBC 应用程序示例:

    public static void main(String[] args) {
       Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "the_user", "the_password");
       Employee e = new Employee();
       e.set("first_name", "John");
       e.set("last_name", "Doe");
       e.saveIt();
       Base.close();
    }

    该调用Base.open()打开一个连接并将其附加到当前线程。

    所有模型的所有后续方法都重用此连接。、

    该调用Base.close()关闭连接并将其从当前线程中删除。

    ?到目前为止一切顺利,但要进行交易。

    ActiveJDBC 确实提供了一些与事务相关的便利调用:

    开始交易:

    Base.openTransaction();

    提交交易:

    Base.commitTransaction();

    并回滚:

    Base.rollbackTransaction();

    所有这些方法都简单地调用java.sql.Connection.setAutocommit(false),java.sql.Connection.commit()java.sql.Connection.rollback()分别在 INFO 级别包装异常和记录事件。

    正如您所看到的,ActiveJDBC 在这里并没有尝试做太多事情,只是想不碍事。

    如果您需要更精细的控制,您可以获取当前连接并对其执行纯 JDBC 操作:

    java.sql.Connection con = Base.connection();
    con.setAutocommit(false);
    ...//or:
    Base.connection().setAutocommit(false);

    事务完整事例:

    一个使用事务的简单程序如下所示:

    public static void main(String[] args) {
       try{
          Base.open("com.mysql.jdbc.Driver", "jdbc:mysql://localhost/test", "the_user", "the_password");
          Base.openTransaction();
          Employee e = new Employee();
          e.set("first_name", "John");
          e.set("last_name", "Doe");
          e.saveIt();
          Base.commitTransaction();
       catch(Exception e){
          Base.rollbackTransaction();
       }finally{
          Base.close();
       }
    }

    和JNDI组合:

    但是通常情况下,连接是从容器池中请求的,而事务配置已经由容器配置提供。

    在这些情况下,用法是相同的(几乎),但您必须意识到某些调用可能不会成功,或者驱动程序可能会产生意想不到的副作用。

    例如,如果您从池中请求连接,则事务可能会在那时开始,并且在您调用时:

    Base.connection().setAutocommit(true/false);

    ,您可能会不小心提交正在进行的事务(?或者驱动程序将忽略您的调用并且什么也不做)。

    ActiveJDBC 并没有在 J2EE 和 JDBC 已经提供的东西上添加任何特殊的东西。

    以下是 MessageDriven Bean (JMS) 中使用的 ActiveJDBC 示例:

    public void onMessage(Message m){
       Base.open("myConnectionJNDIName");
       TextMessage tm = (TextMessage)m;
       String content = tm.getText();
       String name = tm.getStringProperty("name");
       try{
          Article.create("name", name, "content", content).saveIt();
       }
       catch(Exception e){
         ctx.setRollbackOnly(); // == this will send the message back into queue
       }
       finally{
          Base.close();//always close connection
       }
    }

    在上面的示例中,容器将管理事务。它将同时回滚:JDBC 和 JMS 事务。

    二、IN条件的特殊处理

    在某些情况下,您需要编写如下内容:

    SELECT my_column FROM my_table where search_column IN (?)

    不幸的是,JDBC 不支持此功能,因此我们有如下解决方法:Preparedstatement IN 子句替代方案/StackOverflow

     

    IN子句解决方法

    解决方法很简单,如果你想执行这个:

    String sql = "name IN ('John', 'Hellen', 'Henry')";

    然后你用单引号和逗号加入这个列表:

    List names = Collections.list("John", "Hellen", "Henry");
    List<Person> people = Person.where("name IN ('" + Util.join(names, "', '") + "')");

    您可以将此方法用于相对较小的列表,因为列表越大,生成的查询越长。每个数据库对查询的大小都有限制,因此您的里程可能会有所不同。

    请参阅对Util#joinCollections#list方法的引用这些类已经在每个 ActiveJDBC 应用程序的类路径上。

  • 相关阅读:
    Introspector
    jython awt demo
    java中dom解析xml
    【luogu1816】忠诚
    代码调试技巧【OI缩水版】
    【UOJ78】二分图最大匹配
    【51nod】最大子段和
    【LibreOJ109】【模板】并查集
    简单的卡常数【OI缩水版】
    QQbot
  • 原文地址:https://www.cnblogs.com/mindzone/p/15041078.html
Copyright © 2020-2023  润新知