简体   繁体   中英

What is the correct way to structure a Database Management Java application?

Firstly, forgive me if I don't sound coherent as I am still a beginner and not quite certain how to word some of these things.

I am creating a Library Management system in JavaFX using SQLite for the database. I have familiarised myself with how SQL queries are handled in Java and my application is functional. However, I am now restructuring the application to make it follow OOP principles. My question is in regard to what approach I should take with methods that involve querying the database.

In an ordinary application, I think I would write these methods in the relevant Class - say, for instance, a method to view information on a book would be contained in the "Book" class. But here that would involve creating a new database connection or passing around the current one, and my gut tells me this isn't the right way to do it. Should I instead have a separate class to store the connection and also handle all database operations? What is the correct way to go about this?

The problem is, relational tables don't map well to objects. How does:

SELECT author.name, book.title,
book.lang = author.native_tongue AS nativeWritten
FROM book LEFT JOIN author ON author.id = book.author;

translate to objects?

It doesn't.

If you want to forego the power of SQL everywhere, or at least in most places, and basically do SELECT * FROM book WHERE unid = 1; and not go much further, you can make the trite oversimplification that there is a class of type Book and it matches both the book table and can reasonably encapsulate all the things you might want to do to the DB that involve books at all, okay, well, you could re-invent the wheel and rewrite all of JPA/Hibernate, or you just use that.

Alternatively, you should look into JDBI or JOOQ which forego the idea that 'table in db == class in java', and are more SQL oriented. These have all sorts of tutorials and guides to show you exactly how to use them.

If you really are insistent on reinventing this wheel: Passing a connection object around is not crazy. It's what is needed to perform the stated task. Something like:

public static Book getById(Connection db, int unid) throws SQLException { ... }

is one way. A slightly more involved way that makes life easier for testing would be something like:

public class DbBridge {
    public Book getById(int unid) throws SQLException { ... }
}

lets you abstract the notion of how to do the job, but.. then it means you're passing a DbBridge object around to everything.

The general principle of 'I have this somewhat complicated, stateful concept that I need in a ton of places, it's almost like a configuration' is a common problem. It is what 'dependency injection' frameworks such as dagger are trying to solve. You can either reinvent that wheel too, or just one of them. If you want to reinvent, well, have a look at how those projects work so you have an idea of what solutions are available.

NB: If you chose SQLite because it's 'lite', it's not. Not from the java perspective: You need a native executable to use it. A muuch simpler and lighter approach is to use a java-native file-based db engine such as H2 or JavaDB. Only use SQLite from java if you need that db to be accessible from non-java applications, or you're more or less forced into it, eg because you're writing android apps. Complexity-wise, SQLite is about as complicated as a full blown postgres or whatnot, from the java perspective.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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