【问题标题】:"Select or create" from database, in Java用Java从数据库中“选择或创建”
【发布时间】:2012-07-15 02:23:23
【问题描述】:

在过去的几年里,我用 Ruby 完成了我所有的数据库开发,主要是使用 ActiveRecord。现在我被困在一个项目中使用 Java,感觉如此冗长且笨拙,我想知道我是否做错了。

在 ORM 范式中,如果我想插入相关表,我会这样做

# Joe Bob got a new car
p = Person.find_or_create_by_name("Joe Bob");
Car.new({:make=>"Toyota", :plate=>"ABC 123", :owner=>p});

在 Java 中,至少直接使用 JDBC,我将不得不手动进行 Person 查找,如果不存在则插入,然后创建 Car 条目。

当然,在现实生活中,不仅仅是两张桌子,而且痛苦呈指数级增长。肯定有更好的方法吗?

【问题讨论】:

    标签: java mysql orm


    【解决方案1】:

    更好的方法是学习 SQL!你非常喜欢的 ORM 在幕后为你编写 SQL。

    因此,您可以创建一个快速帮助函数来尝试选择记录,如果它不存在,则为您创建它。

    在 MySQL 中,您可以使用 INSERT IGNORE .....,它只会在该行不存在时插入该行。

    这里有一段你可能喜欢的特殊 SQL(仅限 MySQL):

    INSERT INTO table (a,b,c) VALUES (1,2,3)
      ON DUPLICATE KEY UPDATE id=LAST_INSERT_ID(id), c=3;
    

    这会尝试插入记录,如果它不存在,它会像往常一样返回您在程序中检索的 auto_increment。

    但是:如果它确实存在,那么它会更新它 - (在这种情况下只有 c 被设置为更新),但很酷的部分是它设置 LAST_INSERT_ID() 就像它在插入时一样。

    因此,无论哪种方式,您都会获得 ID 字段。所有这些都在一个 SQL 中。

    SQL 是一门非常好的语言 - 你应该学习它,而不是依赖 orm 的伪语言。

    【讨论】:

    • 我已经了解了相当多的 SQL ——我手动创建了一个视图来连接读取它们的应用程序的表,并有各种存储过程来操作数据,因为其他原因——但我还没有听说过INSERT IGNOREON DUPLICATE KEY。超级有用!
    • @Coderer INSERT IGNOREON DUPLICATE KEY MySQL 只记住这一点。
    【解决方案2】:

    如果您使用的是 JDBC,您需要自己查找并创建人员(如果不存在)。如果使用 JDBC,没有更好的方法。

    但是您可以使用 Hibernate,它会帮助您减少自己编写 O-R 映射并减少样板。

    由于您来自 Ruby,如果您发现编写所有 SQL 查询、JDBC 样板文件很痛苦,那么更好的方法是使用 ORM。我推荐以下之一,

    1. 休眠
    2. JPA(如果要更改 ORM 实现,请使用 JPA)

    【讨论】:

      【解决方案3】:

      您可以使用 Java 的 ORM 解决方案 - 有多种可用的解决方案。

      值得一看的链接:

      话虽如此,但我通常发现,对于复杂的应用程序,ORM 经常会带来比其价值更多的麻烦(是的,这确实包括带有 Activerecord 的 Ruby 项目)。有时,直接通过 SQL 获取数据而不是尝试在其之上强制使用面向对象的外观确实很有意义。

      【讨论】:

        【解决方案4】:

        Sormula 包含一个active record packagesave method 将更新现有记录,如果不存在记录则插入。

        请参阅网站上的active record example

        另请参阅项目中的 org.sormula.tests.active.SaveTest.java:

        SormulaTestAR record = new SormulaTestAR();  
        record.attach(getActiveDatabase()); // record needs to know data source
        record.setId(8002);
        record.setType(8);
        record.setDescription("Save one AR 2");
        record.save();
        

        【讨论】:

          【解决方案5】:

          看来我来晚了,不过,ActiveJDBC 会在 Java 中做你想做的事:

          Person p = Person.findOrCreateIt("name", "Joe Bob");
          Car car = Car.createIt("make", "Toyota", "plate", "ABC 123", "owner", p);
          

          它还有很多功能,请查看:http://javalite.io/

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2014-04-26
            • 2012-11-18
            • 1970-01-01
            • 1970-01-01
            • 2010-09-06
            • 2016-07-14
            • 2017-01-05
            • 2010-10-17
            相关资源
            最近更新 更多