【问题标题】:implement SQL like select in Java在 Java 中实现类似于 select 的 SQL
【发布时间】:2011-11-23 16:33:29
【问题描述】:

一般我想知道SQL select在底层是如何实现的,看起来是这样的

他们使用的算法接近于 O(1)..... 在 Java 中你只能通过使用来实现这一点

hashmaps,我想知道他们是怎么做到的

示例:

如果我有一组学生,一组班级,为了选择任何一个学生属于哪个班级

或任何班级拥有哪组学生,我会设计一个关系数据库,其中 3 个表:

学生表、班级表、关系表

应该代表良好的多对多关系

但是,如果我不想使用 SQL、JDBC,请创建和设计表

我怎样才能在纯java中实现这个

我想要类似的东西

List<Student> getStudentsByClass(String className) 

 List<Class> getClassesByStudent(String StudentName)

理想情况下,我将有一个 hashMap,使用唯一的 studentID 作为键,实际的 studentObject 作为值 另一个 hasMap 使用 classID 作为键,classObject 作为值

然后一个关系 ArrayList 包含所有关系对象,在关系对象内你有 2 个文件,classID 和 studentID

问题是我不想每次搜索时都循环遍历关系 ArrayList

我知道对象上有一个比较方法,我可以覆盖它,只帮助你对对象进行排序 它对选择没有多大帮助不是吗?

有一个链接,我什么都明白,但不是选择位,请任何人给点提示!

http://www.javaworld.com/javaworld/jw-11-2004/jw-1122-select.html?page=3

【问题讨论】:

    标签: java database design-patterns database-design


    【解决方案1】:

    您可以遍历您的“表”并检查每个项目是否符合指定条件。这将适用于 O(n) 复杂度。如果您想让您的程序更快地使用 Map(例如 HashMap 或 TreeMap)(O(1))创建某种索引或/和对数据进行排序并使用二进制搜索(log(n))。

    【讨论】:

    • 你能说得更具体些吗? O(n) 会起作用,但这就是我想要避免的,关键是如何构造关系集合,它应该是一个地图吗?一组或......一张地图很好,但你需要一个唯一的钥匙......更重要的是钥匙应该是什么?
    【解决方案2】:

    对象序列化在这里可能对你有用...

    public static void testSerialization() {
      String filename = "person.txt";
      StudentDetails s1 = new PersonDetails("hemanth", 10, "Male");
      StudentDetails s2 = new PersonDetails("bob", 12, "Male");
      StudentDetails s3 = new PersonDetails("Richa", 10, "Female");
      List list = new ArrayList();
      list.addAll(Arrays.asList(s1, s2, s3));
      FileOutputStream fos = null;
      ObjectOutputStream out = null;
      try {
        fos = new FileOutputStream(filename);
        out = new ObjectOutputStream(fos);
        out.writeObject(list);
        out.close();
        System.out.println("Object Persisted");
      } catch (IOException ex) {
        ex.printStackTrace();
      }
    } 
    

    当然,阅读会非常相似。可悲的是,对此进行“选择”查询并非易事。我建议查看 H2 数据库。这非常简单,而且效果很好。这是一个创建数据库、表、插入内容并再次读取的小示例。

    public static void h2test() throws SQLException {
        JdbcDataSource ds = new JdbcDataSource();
        ds.setURL("jdbc:h2:testdb/somedb");
    
        Connection connection = ds.getConnection();
        PreparedStatement statement = connection.prepareStatement("CREATE TABLE IF NOT EXISTS TEST(ID INT PRIMARY KEY, NAME VARCHAR(255))");
        System.out.println(statement.execute());
    
        statement = connection.prepareStatement("INSERT INTO TEST VALUES(10, 'ten')");
        System.out.println(statement.executeUpdate());
        connection.commit();
    
        statement = connection.prepareStatement("SELECT * FROM TEST");
        ResultSet resultSet = statement.executeQuery();
    
        while (resultSet.next()) {
            System.out.println(resultSet.getInt(resultSet.findColumn("ID")) + ", " + resultSet.getString(resultSet.findColumn("NAME")));
        }
    }
    
    public static void main(String[] args) throws SQLException {
        System.out.println("Hello world");
        h2test();
    }
    

    我真的可以推荐它。

    【讨论】:

    • 对不起,没有第三部分库,甚至没有序列化,但是这是个好主意,但它并不能帮助我理解 sql 的工作原理以及关系数据库的工作原理
    • 那么抱歉,但请查看 H2 以供将来参考。值得知道。
    【解决方案3】:

    您可以简单地构建多个索引视图来满足您想要解决的查询。

    HashMap<String, List<Student>> studentsByClassId;
    HashMap<String, List<SchoolClass>> classesByStudentId;
    
    HashMap<String, Student> studentByStudentId;
    HashMap<String, SchoolClass> classByClassId;
    

    在单个类中维护它们,该类充当您的数据访问层并提供您建议的查找方法。 CRUD 操作通过该类。

    如果您稍后想要切换到数据库实现,那么您的数据访问类的实现会发生变化。但是如果你做了一个合理的工作,那么它的界面就不会。

    【讨论】:

    • 我同意!它是一个 O(1) 并且这有效,但是通过给出这个我没有得到这份工作,我徘徊了所谓的更好的解决方案.....他们说 sql jdbc hibernate 不是答案..... ..啊啊啊啊
    【解决方案4】:

    我想推荐Guava。我没有完整的细节来给你一个完整的例子,但在番石榴中,你可以创建充当过滤器的谓词。

    我喜欢他在番石榴上做的这个教程,链接到网址是here

    只是给你一个可能使用的例子,你可以指定一个方法来为你返回一个谓词

    public static Predicate<String> isStartsWith(final String input){
        return new Predicate<String>()
        {
            @Override
            public boolean apply( String str )
            {
                if(str.startsWith( input ))
                    return true;
                return false;
            }
        };
    }
    

    然后这样调用方法

    filteredList.addAll( Collections2.filter( youList, isStartsWith("thing you want to filter") ) );
    

    【讨论】:

    • 谢谢,但再次,没有第 3 方库,请只使用纯 java
    【解决方案5】:

    您是否考虑过使用Hibernate?它允许您直接在 Java 对象上使用类似 SQL 的查询 (HQL)。它通常意味着由“真实”数据库支持,但您不必这样做。事实上,在我之前的一个专业经验中,我们非常成功地将它与内存数据库 (HSQLDB) 一起使用,原因是:能够在非常大的数据上执行复杂的查询(包括聚合、连接等) java 对象的集合。

    【讨论】:

    • 正常人的正常反应是冬眠,是的!我同意它是最好的选择,但我只想知道是否可以使用纯 java 来做到这一点
    • 如果你不使用数据库来支持你的模型,你可能会说 Hibernate 纯 java...
    • 抱歉纯java是你自己实现的select算法
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多