我有一张桌子" MoviesInfo"与这些领域:movieId,动作,犯罪,戏剧,喜剧,恐怖,动画,纪录片,....
我需要将通过抓取(电影类型)获得的字符串与包含所有类型的列表进行比较,并插入' 1'如果该字符串在列表中,则在关联的流派列中。例如,电影的类型"黑暗骑士"是"行动","犯罪","戏剧"。所以,我想插入' 1'在列"行动","犯罪","戏剧"并插入" 0"对于其他专栏。
这是我的代码中我获得电影类型的一部分:
List<String> genre = new ArrayList<String>();
.........
Elements elms1 = doc.select("div.infobar");
Elements links1 = elms1.select("a[href]");
for(Element link1 : links1){
if(link1.attr("href").contains("/genre/"))
{
genre.add(link1.text());
}
}
.....
.....
try{
String query = "INSERT into moviesInfo (movieId, genre)" + "VALUES (?, ?)";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setString (1, ImdbID);
preparedStmt.setString (2, genre.toString());
preparedStmt.executeUpdate();
}catch (Exception e)
{
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}
我希望我能澄清我的问题,所有的想法都受到高度赞赏,
答案 0 :(得分:1)
您可能需要一个DTO(数据传输对象),您可以使用它来将该类型放入。
<强> DTO:强>
public class Genre {
//Create boolean field values for all genre and initialize to false in constructor
//Attributes and name
//Create getters/setters for all field values
}
填写DTO:
for(Element link1 : links1){
if(link1.attr("href").contains("/genre/"))
{
String genre_name = link1.text()
Genre genre = new Genre();
if(genre_name.equals("Comedy") {
genre.setComedy(Boolean.TRUE);
}
if(genre_name.equals("Horror") {
genre.setHorror(Boolean.TRUE);
}
//Repeat for all genre...
//Add genre DTO to database
}
}
现在,当您将此类型添加到数据库时,只需设置&#39; 1&#39;因为这种类型是真的。
答案 1 :(得分:0)
当项目涉及各种过滤类别时,有多种策略可以处理案例。
添加列
每个类别在数据表中表示为附加列,值为0或1以进行匹配。
添加关系
您创建一个具有mamy-to-many关系的表,您可以在其中存储item与category的关系。
添加遮罩
您构建了一个名为mask的二进制值,其中每个位置对应于category。
DRAMA,COMEDY,SCI-FI,DOCUMENTARY
SCI-FI喜剧的面具将是0110
和戏剧1000
。
添加非规范化
您只需将值存储在单列中,然后使用分隔符将它们分开。使用regexp,您可以确定该项目适用于此类别。
每种方法都有优点和缺点。在选择方法之前应该考虑各种权衡因素,很可能我将来必须进行更改。
因此,您应该选择其中一个,而不是专注于提供DB策略。并在您的应用程序中为其创建一个简单的API。不应暴露电影与类别匹配的逻辑,因此您可以快速更改它。
public Collection<Movie> findByCategories(Category... categories)
这是最终产品。
什么是Movie
和Category
类别代表描述电影性别的简单对象。
class Category {
private final String name;
public Category(String name) {
this.name = name;
}
public String name() {
return this.name;
}
//Override equals and hashCode
}
电影代表电影,所以在它的结构中我们应该有一些属性。
class Movie {
private final String title;
private final byte year;
private Collection<Category> categories;
public Movie(String title, byte year) {
this.title = title;
this.year = year;
}
public boolean isCategory(Category category) {
if(categories == null) reuturn false;
return categories.contains(category);
}
}
或
class Movie {
private final String title;
private final byte year;
private String categories;
public Movie(String title, byte year) {
this.title = title;
this.year = year;
}
public boolean isCategory(Category category) {
if(categories == null) reuturn false;
return categories.contains(category.name());
}
}
答案 2 :(得分:0)
最后,我可以解决我的问题。我不得不使用linkedList和LinkedHashMap来存储类型。 (我使用了LinkedHashMap和NOT HashMap来保持排序)。这是新的代码,效果很好:
LinkedList<String> genres = new LinkedList<String>();
genres.add("Action");
genres.add("Adventure");
genres.add("Comedy");
genres.add("Animation");
genres.add( "Drama");
genres.add("Romance");
.
.
.
LinkedHashMap<String,Integer> currentGenreHashMap = new LinkedHashMap<String, Integer>();
String baseUrl = "http://www.imdb.com/title/"+ImdbID;
try {
org.jsoup.Connection con = Jsoup.connect(baseUrl).userAgent("Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/535.21 (KHTML, like Gecko) Chrome/19.0.1042.0 Safari/535.21");
....
..
Elements elms1 = doc.select("div.infobar");
Elements links1 = elms1.select("a[href]");
LinkedList<String> currentGenres = new LinkedList<String>();
for (String g1 : genres){
currentGenreHashMap.put(g1, 0);
} //set the default to zero
for(Element link1 : links1){
if(link1.attr("href").contains("/genre/"))
{
currentGenres.add(link1.text());
System.out.println("generi: " + link1.text());
}
}
for (String genere : genres){
if (currentGenres.contains(genere))
currentGenreHashMap.put(genere, 1);
} //here I compare the genre that I get by crawler to the genres in the list and when they were equal it set it to '1'
System.out.println("movie genres:" + currentGenreHashMap);
...
...
try{
String query = "INSERT into moviesInfo (movieImdbId, Action, Adventure, Comedy, Animation, Drama, Romance, Family, Fantasy, Crime, Biography, Documentary, FilmNoir, Horror, War, History, Western, Musical, SciFi, Mystery, Thriller, RealityTV, TalkShow, GameShow, Short, Music, Sport, News, Adult, Lifestyle, Experimental, Commercial, country, trailerLink, storyline, posterLink)" + "VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ? )";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setString (1, ImdbID);
int count = 2;
for (String g1 : currentGenreHashMap.keySet()){
preparedStmt.setString (count, currentGenreHashMap.get(g1).toString());
count++;
}
preparedStmt.executeUpdate();
}catch (Exception e)
{
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}