简体   繁体   English

Java循环显示来自SQL国家/地区表的多种语言

[英]Java Loop to Display Multiple Languages from SQL Country Table

I am working on a Java assignment that requires pulling languages from a COUNTRY_LANGS_SQL table, then using a loop to display the Country, Population, Median Age, and Language(s) for each country. 我正在处理Java作业,该作业需要从COUNTRY_LANGS_SQL表中提取语言,然后使用循环显示每个国家/地区的国家/地区,人口,中位数年龄和语言。 I'm able to display the 4 Countries, Population, Median Age, but for the life of me I cannot figure out what statement I need to declare in order for it to pull and loop the languages in. I've tried numerous variations with no success, so I'm hoping someone can take a look and point out what I'm doing wrong. 我可以显示4个国家/地区,人口,年龄中位数,但是对于我一生来说,我无法弄清楚需要声明哪种声明才能使它拉入和插入语言。没有成功,所以我希望有人可以看看并指出我做错了什么。 Any help would be greatly appreciated. 任何帮助将不胜感激。

UPDATE 3: So I'm very close to having this working now with it successfully executing and displaying language column, it's just not displaying the languages of the country (see below) 更新3:因此,我现在非常接近于成功执行并显示语言列,而只是不显示该国家/地区的语言(请参阅下文)

Name: Canada  Population: 34568211  Median Age: 41.5  ID      :   1  Language:   []
Name: Germany  Population: 81147265  Median Age: 45.7  ID      :   2  Language:   []
Name: South Africa  Population: 49601098  Median Age: 25.5  ID      :   3  Language:   []
Name: Japan  Population: 127253075  Median Age: 45.8  ID      :   4  Language:   []

I also only have one error now in the readLanguages method " The method getId() is undefined for the type List " 我现在在readLanguages方法中也只有一个错误“对于类型List,未定义方法getId()”

/**
 * @return list of countries read from the country database
 */
public List<Country> getCountries() {
    return countries;
}

private void readLanguages() {
    try (
        Connection connection = getConnection();
        PreparedStatement stmt = connection.prepareStatement(GET_COUNTRY_LANGS_SQL)
    ) {

        for (Country country : countries); {
            stmt.setInt(0, countries.getId());
            ResultSet rs = stmt.executeQuery();
        while (rs.next()) {
            int i = 0;
            countries.get(i).addLanguage(rs.getString("language")); 
            rs.close();
        }
    }}
    catch (SQLException e) {
        System.err.println("ERROR: " + e.getMessage());
        e.printStackTrace();
    }

It seems to not be pulling the Id's from the Country class, or it's not looping correctly. 似乎没有从Country类中提取ID,或者循环不正确。 Any thoughts? 有什么想法吗?

1)CountriesDB.java 1)CountriesDB.java

        package edu.pcc.cis233j.countries;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

/**
 * Read data from the countries database
 * 
 * @author 
 */
public class CountriesDB {
    private static final String DB_NAME = "Countries";
    private static final String DB_URL = "jdbc:jtds:sqlserver://cisdbss.pcc.edu/" + DB_NAME;
    private static final String USERNAME = "";
    private static final String PASSWORD = "";
    private static final String GET_COUNTRIES_SQL = "SELECT * FROM COUNTRY";
    private static final String GET_COUNTRY_LANGS_SQL = "SELECT * FROM COUNTRY_LANGUAGE WHERE CountryId = ?";

    private List<Country> countries;

    /**
     * Create a CountriesDB object
     * Read from the Countries database and populate the countries list
     */
    public CountriesDB() {
        countries = readCountries();
    }

    /**
     * Create and return a connection to the database
     * @return connection to the countries database
     */
    private Connection getConnection() throws SQLException {
        Connection connection = DriverManager.getConnection(DB_URL, USERNAME, PASSWORD);
        return connection;
    }

    /**
     * Read country info from the Country table.
     * If an error occurs, a stack trace is printed to standard error and an empty list is returned.
     * @return the list of countries read
     */
    private List<Country> readCountries() {
        List<Country> countries = new ArrayList<>();
        try (
                Connection connection = getConnection();
                PreparedStatement stmt = connection.prepareStatement(GET_COUNTRIES_SQL);
                ResultSet rs = stmt.executeQuery()
                ) {
            while (rs.next()) {
                countries.add(new Country(rs.getInt("Id"),
                        rs.getString("Name"),
                        rs.getLong("Population"),
                        rs.getDouble("MedianAge")));
            }
        }
        catch (SQLException e) {
            System.err.println("ERROR: " + e.getMessage());
            e.printStackTrace();
        }
        return countries;
    }

    /**
     * @return list of countries read from the country database
     */
    public List<Country> getCountries() {
        return countries;
    }

    private void readLanguages() {
        try (
            Connection connection = getConnection();
            PreparedStatement stmt = connection.prepareStatement(GET_COUNTRY_LANGS_SQL)
        ) {

            for (Country country : countries); {
                stmt.setInt(0, countries.getId());
                ResultSet rs = stmt.executeQuery();
            while (rs.next()) {
                int i = 0;
                countries.get(i).addLanguage(rs.getString("language")); 
                rs.close();
            }
        }}
        catch (SQLException e) {
            System.err.println("ERROR: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

2)Country.java 2)Country.java

       package edu.pcc.cis233j.countries;

import java.util.ArrayList;
import java.util.List;

/**
 * A country in the world
 * @author Your Name & Cara Tang
 */
public class Country {
    private int id;
    private String name;
    private long population;
    private double medianAge;
    private List<String> language = new ArrayList<>();


    /**
     * Create a Country object with the given properties
     */
    public Country(int id, String name, long population, double medianAge) {
        this.id = id;
        this.name = name;
        this.population = population;
        this.medianAge = medianAge;
    }

    public int getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public long getPopulation() {
        return population;
    }

    public double getMedianAge() {
        return medianAge;
    }

    public List<String> getLanguage() {
        return language;
        }

    public void addLanguage(String string) {
         language.add(string);
        }

}

3) CountryMain.java 3)CountryMain.java

    package edu.pcc.cis233j.countries;

import java.util.List;

/**
 * Read from the Country database and print data on the countries
 * @author TJ
 */
public class CountryMain {
    public static void main(String[] args) {
        CountriesDB cdb = new CountriesDB();
        List<Country> countries = cdb.getCountries();

        for (Country country : countries) {
              System.out.println("Name: " + country.getName()
                                   + "  Population: " + country.getPopulation()
                                   + "  Median Age: " + country.getMedianAge()
                                   + "  ID      :   " + country.getId()
                                   + "  Language:   " + country.getLanguage()
                      );
        }
    }
}

First, the lines: 首先,这些行:

countries.add(new Country(rs.getString("Language"),
                    rs.getString("Language")));

refer to rs before it is declared or populated. 在声明或填充之前先引用rs Also, they appear to be trying to build a Country from two strings (both the same). 而且,他们似乎正在尝试使用两个字符串(两者相同)来构建国家/地区。

Second, 第二,

countries.add(new Language ());

Is crazy because countries has Country objects in it, so you can't just add a Language object, and a new one at that (not from the database). 之所以疯狂,是因为国家中有国家对象,所以您不能只添加一个语言对象,然后再添加一个语言对象(而不是从数据库中)。

It's almost as if you didn't write the code yourself and consequently don't understand it... 几乎就像您不是自己编写代码,因此也不了解它一样。

I think what you need is closer to this: 我认为您需要的更接近此:

private void readLanguages() {
    try (
        Connection connection = getConnection();
        PreparedStatement stmt = connection.prepareStatement(GET_COUNTRY_LANGS_SQL)
    ) {
        ResultSet rs = null;
        for (Country country : countries); {
            stmt.setInt(1, country.getId());
            rs = stmt.executeQuery();
            while (rs.next()) {
              country.setLanguage(rs.getString("Language")); //assumes 1 per country - others are discarded
            }
            rs.close();
        }
    }
}

not perfect java - but should give you an idea where you are going wrong . 并不是完美的java-但是应该给你一个想法,你哪里出错了

Other notes: 其他说明:

  • The easy way to do this (assuming one language per country) would be to join the tables in the SELECT. 执行此操作的简单方法(假设每个国家/地区使用一种语言)是将表连接到SELECT中。
  • You should also close your database connection when finished with it. 完成数据库连接后,还应该关闭它。
  • I'm not sure that your try (stuff) {statements} syntax is correct. 我不确定您的try (stuff) {statements}语法是否正确。
  • If there are multiple languages per country, you need that supported in your data structures/classes. 如果每个国家/地区使用多种语言,则需要数据结构/类中支持的语言。
  • I'm assuming your Country class has getters and setters for the fields. 我假设您的Country类具有针对该字段的getter和setter。

Note: the question has been updated but I think this is still mostly relevant. 注意:这个问题已经更新,但我认为这仍然很重要。

As by design, one Country can have multiple Language s, so your model should look like: 按照设计,一个Country可以具有多种Language ,因此您的模型应类似于:

class Country {
    private int id;
    private String name;
    private List<String> language;
    //....
}

There are different ways you can construct it, most straight-forward one is something like (in pseudo-code): 您可以用不同的方法来构造它,最简单的一种方法是(用伪代码):

List<Country> resultCountries=....;
countryRows = executeGetCountrySql
foreach countryRow in countryRows {
    id = row.get("ID");
    name = row.get("NAME");
    List<String> langs = new ArrayList<();
    langRows = executeGetLanguageByCountryIdSql(id);
    foreach langRow in langRows {
        langs.add(langRow.get("LANGUAGE"));
    }
    resultCountries.add(new Country(id, name, langs));
}

Some DB iirc does not allow concurrent resultsets. 某些DB iirc不允许并发结果集。 One way you can do is to read all countries first, and loop through each country and get its corresponding languages, and set it back to country. 一种方法是首先阅读所有国家/地区,然后遍历每个国家/地区并获取相应的语言,然后将其设置回国家/地区。

Another way is to join the country table with country_language, and construct new country / add new language to existing country for each result row. 另一种方法是使用country_language加入country表,并为每个结果行构造新国家/向现有国家/地区添加新语言。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM