Java - How can I INSERT values in SQLite? - java

Im starting in SQLite, I created my db and the connection works.
When I try to Insert a value (the db is empty) I get the following error:
java.sql.SQLException: near ".684": syntax error
import java.sql.*;
public class connection{
String route = "C:\\Freeman SA.db";
Connection c = null;
Statement stat = null;
String op;
public void connect(){
try{
c = DriverManager.getConnection("jdbc:sqlite:"+route);
if (c!=null)
System.out.println("Connected to db.");
}
catch (SQLException ex) {
System.err.println("Couldn't connect."+ex.getMessage());
}
}
public void insert_DB(String NAME, String LNAME, String ID, int AGE, int TIME, int SALARY) throws SQLException{
connect();
try {
stat = c.createStatement();
op = "INSERT INTO Remuneraciones (Nombre, Apellido, Rut, Edad, Tiempo, Sueldo) VALUES (" + NAME + ", " + LNAME + ", " + ID + ", " + AGE + ", " + TIME + ", " + SALARY + ");";
stat.executeUpdate(op); //Here is the problem
stat.close();
}
catch (SQLException e) {
System.err.println(e.getClass().getName() + ": " + e.getMessage());
}
c.close();
}
}
Main.
public static void main(String[] args) throws IOException {
connection n = new connection();
try {
n.insert_DB("Charlie", "White", "18.954.621-K", 21, 2, 650000);
} catch (SQLException ex) {
Logger.getLogger(main.class.getName()).log(Level.SEVERE, null, ex);
}
}
PD: I'm learning from here: http://www.tutorialspoint.com/sqlite/sqlite_java.htm

It's a bad idea to create a SQL statement by concatenating Strings like that. Do some research into SQL injection attack and Little Bobby Tables.
PreparedStatement is a better idea. Bind your variables after validation.
See if this makes your life better:
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
/**
* Demo RenumerationDao
* Created by Michael
* Creation date 6/8/2016.
* #link https://stackoverflow.com/questions/37714254/java-how-can-i-insert-values-in-sqlite/37714292#37714292
*/
public class RenumerationDao {
private static final String INSERT_SQL = "INSERT INTO Remuneraciones(Nombre, Apellido, Rut, Edad, Tiempo, Sueldo) VALUES(?, ?, ?, ?, ?, ?)";
private Connection connection; // Better to get this from a pool.
public RenumerationDao(Connection connection) {
this.connection = connection;
}
public int insert(String firstName, String lastName, String id, int age, int timeInHours, int salary) {
int numRowsInserted = 0;
PreparedStatement ps = null;
try {
ps = this.connection.prepareStatement(INSERT_SQL);
ps.setString(1, firstName);
ps.setString(2, lastName);
ps.setString(3, id);
ps.setInt(4, timeInHours);
ps.setInt(5, age); // You'll have to update this each and every year. BirthDate would be better.
ps.setInt(6, salary);
numRowsInserted = ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
close(ps);
}
return numRowsInserted;
}
public static void close(Statement statement) {
try {
if (statement != null) {
statement.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}

Related

Is the MySQL procedure in this Minecraft plugin correct?

To get an idea of what the basic structure looks like, I downloaded a money system including MySQL from Spigot and looked at the code.
public static boolean playerExists(String uuid) {
try {
ResultSet rs = Simplecoinsystem.mysql.query("SELECT * FROM CoinData WHERE UUID= '" + uuid + "'");
if (rs.next())
return (rs.getString("UUID") != null);
return false;
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public static void createPlayer(String uuid) {
if (!playerExists(uuid))
Simplecoinsystem.mysql.update("INSERT INTO CoinData (UUID, COINS) VALUES ('" + uuid +
"', '" + Simplecoinsystem.getInstance().getConfig().getInt("startcoins") + "');");
}
public static Integer getCoins(String uuid) {
Integer i = Integer.valueOf(0);
if (playerExists(uuid)) {
try {
ResultSet rs = Simplecoinsystem.mysql.query("SELECT * FROM CoinData WHERE UUID= '" + uuid + "'");
if (rs.next())
Integer.valueOf(rs.getInt("COINS"));
i = Integer.valueOf(rs.getInt("COINS"));
} catch (SQLException e) {
e.printStackTrace();
}
} else {
createPlayer(uuid);
}
return i;
}
public static void setCoins(String uuid, Integer coins) {
if (playerExists(uuid)) {
Simplecoinsystem.mysql.update("UPDATE CoinData SET COINS= '" + coins + "' WHERE UUID= '" + uuid + "';");
} else {
createPlayer(uuid);
}
}
Am I correct that it is actually impractical to create a new entry with the uuid of the non-existent player after each query of the coins if the player does not exist?
Wouldn't this make it possible to flood the database with thousands of unnecessary entries by issuing, for example, a "/money (player)" command as an evil player/admin?
Couldn't I just ask when entering the server if the uuid is already stored and if not, just enter it? This way there would only be entries from players who have already been on the server before. Whether this needs great server performance, I'm not sure.
This is my first own MySQL class.
public class MySQL {
private String host, database, user, password;
private int port;
private Connection con;
public MySQL(String host, int port, String database, String user, String password) {
this.host = host;
this.port = port;
this.database = database;
this.user = user;
this.password = password;
connect();
}
public void connect() {
try {
con = DriverManager.getConnection("jdbc:mysql://" + host + ":" + port + "/" + database + "?autoReconnect=true", user, password);
System.out.println("&cDie MySQL Verbindung wurde erfolgreich aufgebaut!");
} catch (SQLException e) {
e.printStackTrace();
}
}
public void disconnect() {
try {
if(this.con != null) {
this.con.close();
System.out.println("§cDie MySQL Verbindung wurde erfolgreich beendet!");
}
} catch (Exception e) {
e.printStackTrace();
}
}
public void update(String query) {
try {
Statement st = con.createStatement();
st.executeUpdate(query);
st.close();
} catch (Exception e) {
e.printStackTrace();
connect();
}
}
public ResultSet qry(String query) {
ResultSet rs = null;
try {
Statement st = con.createStatement();
rs = st.executeQuery(query);
} catch (Exception e) {
e.printStackTrace();
connect();
}
return rs;
}
public Connection getConnection() {
return this.con;
}
}
Except for this part, both MySQL classes are built relatively the same.
This is the part that is in the MySQL class of the Spigot plugin.
Your code have multiple issues.
When the connection will be closed, next time you will have an error. In your Mysql class, I suggest you to do:
public Connection getConnection() {
if(con == null || con.isClosed())
connect();
return con;
}
Then, use it in all method like getConnection().prepareStatement().
You can be attacked with SQL Injection. To fix this, try to do something like:
PreparedStatement st = con.prepareStatement("SELECT * FROM CoinData WHERE UUID = ?");
st.setString(1, uuid.toString()); // Yes it start at 1 !!
st.executeUpdate();
With this, even with all values, you can't be attacked with injections.
You will have an error while getting coins:
if (rs.next()) // go to good line
Integer.valueOf(rs.getInt("COINS")); // useless convertion
i = Integer.valueOf(rs.getInt("COINS")); // error if no line.
You can just do:
if(rs.next())
i = rs.getInt("COINS");
If the column "UUID" is unique, you will not have duplicated lines.
Finally, about performance, it's better to do it one time: at login, instead of all time. You can also create an object stored in an hashmap to easier access to it, without using SQL, like that:
public static HashMap<UUID, Integer> coinsByPlayer = new HashMap<>();
OR:
public static HashMap<UUID, MyObject> coinsByPlayer = new HashMap<>();
public class MyObject {
private int coins = 0;
public MyObject(UUID uuid) {
// make SQL request to get data
}
public int getCoins() {
return coins;
}
public void setCoins(int next){
coins = next;
// here make "UPDATE" sql query
}
}
What do you say? Is it ok with the try/catch function? #Elikill58
public Connection getConnection() {
try {
if(con == null || con.isClosed()) {
connect();
}
} catch (SQLException e) {
e.printStackTrace();
}
return con;
}
edit:
public Connection getConnection_one() throws SQLException {
if(con == null || con.isClosed()) {
connect();
return con;
} else {
return con;
}
}

Problem with implementing sql queries into Javafx

I wanted to ask a question about implementing SQL queries into a JavaFX application, specifically, I've been trying to create an "employee" application that connects to a MySQL database hosted in localhost. I'm using a DAO pattern to do this and the code is apparently right, the only problem I'm having is that I keep getting errors when trying to add a new employee to the table. Specifically, I'm getting an SQL syntax error and I have no idea what is wrong with the code.
I'll put the code for my EmployeeDAO class down there, please ignore the SQL errors in all the methods (I haven't corrected it yet), the method I already corrected and is still giving me problems is the insertEmp() method.
package Model;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import Util.DBUtil;
import java.sql.*;
public class EmployeeDAO {
//Select an Employee
public static Employee searchEmployee (String empId) throws SQLException, ClassNotFoundException{
String selectStmt = "SELECT * FROM employees WHERE employeeId="+empId;
try{
ResultSet rsEmp = DBUtil.dbExecuteQuery(selectStmt);
Employee employee = getEmployeeFromResultSet(rsEmp);
return employee;
}catch (SQLException e){
System.out.println("While Searching An Employee With "+empId+" Id, An Error Occurred");
e.printStackTrace();
throw e;
}
}
private static Employee getEmployeeFromResultSet(ResultSet rs) throws SQLException{
Employee emp = null;
if(rs.next()){
emp = new Employee();
emp.setEmployeeId(rs.getInt("EMPLOYEE_ID"));
emp.setFirstName(rs.getString("FIRST_NAME"));
emp.setLastName(rs.getString("LAST_NAME"));
emp.setEmail(rs.getString("EMAIL"));
emp.setPhoneNumber(rs.getString("PHONE_NUMBER"));
emp.setHireDate(rs.getDate("HIRE_DATE"));
emp.setJobId(rs.getString("JOB_ID"));
emp.setSalary(rs.getInt("SALARY"));
emp.setCommissionPct(rs.getDouble("COMMISSION_PCT"));
emp.setManagerId(rs.getInt("MANAGER_ID"));
emp.setDepartmentId(rs.getInt("DEPARTMENT_ID"));
}
return emp;
}
//Select Employees
public static ObservableList<Employee> searchEmployees() throws SQLException,ClassNotFoundException{
String selectStmt="SELECT * FROM employees";
try{
ResultSet rsEmps = DBUtil.dbExecuteQuery(selectStmt);
ObservableList<Employee> empList = getEmployeeList(rsEmps);
return empList;
}catch(SQLException e){
System.out.println("SQL Select Operation Failed");
e.printStackTrace();
throw e;
}
}
//Select * from employees operation
private static ObservableList<Employee> getEmployeeList(ResultSet rs) throws SQLException,ClassNotFoundException{
ObservableList<Employee> empList = FXCollections.observableArrayList();
while(rs.next()){
Employee emp = new Employee();
emp.setEmployeeId(rs.getInt("EMPLOYEE_ID"));
emp.setFirstName(rs.getString("FIRST_NAME"));
emp.setLastName(rs.getString("LAST_NAME"));
emp.setEmail(rs.getString("EMAIL"));
emp.setPhoneNumber(rs.getString("PHONE_NUMBER"));
emp.setHireDate(rs.getDate("HIRE_DATE"));
emp.setJobId(rs.getString("JOB_ID"));
emp.setSalary(rs.getInt("SALARY"));
emp.setCommissionPct(rs.getDouble("COMMISSION_PCT"));
emp.setManagerId(rs.getInt("MANAGER_ID"));
emp.setDepartmentId(rs.getInt("DEPARTMENT_ID"));
empList.add(emp);
}
return empList;
}
//Update an employee's email address
public static void updateEmpEmail(String empId, String empEmail) throws SQLException, ClassNotFoundException{
String updateStmt = "BEGIN\n" +
" UPDATE employees\n" +
" SET EMAIL = '" + empEmail + "'\n" +
" WHERE EMPLOYEE_ID = " + empId + ";\n" +
" COMMIT;\n" +
"END;";
try{
DBUtil.dbExecuteQuery(updateStmt);
}catch(SQLException e){
System.out.println("An Error Occurred While Updating The Information");
e.printStackTrace();
throw e;
}
}
public static void deleteEmpWithId(String empId) throws SQLException, ClassNotFoundException{
String updateStmt = "BEGIN\n" +
" DELETE FROM employees\n" +
" WHERE employee_id ="+ empId +";\n" +
" COMMIT;\n" +
"END;";
try{
DBUtil.dbExecuteQuery(updateStmt);
}catch(SQLException e){
System.out.println("An Error Occurred While Deleting An Employee With Id: "+empId);
e.printStackTrace();
throw e;
}
}
public static void insertEmp(String name, String lastName, String email) throws SQLException, ClassNotFoundException{
String updateStmt = "BEGIN\n" +
" INSERT INTO employees ('FIRST_NAME', 'LAST_NAME', 'EMAIL', 'HIRE_DATE', 'JOB_ID')\n" +
" VALUES\n" +
" (?, ?, ?, SYSDATE, 'IT_PROG');\n" +
" END;";
try{
DBUtil.dbPreparedStatement(updateStmt, name, lastName, email);
}catch(SQLException e){
System.out.println("An Error Occurred While Adding A New Employee To The Table");
e.printStackTrace();
throw e;
}
}
}
I'll also add down here the code that uses the insertEmp method.
public static void dbPreparedStatement(String sqlStmt, String name, String lastName, String email) throws SQLException,ClassNotFoundException{
PreparedStatement stmt = null;
try{
dbConnect();
stmt=conn.prepareStatement(sqlStmt);
stmt.setString(1, name);
stmt.setString(2, lastName);
stmt.setString(3, email);
stmt.execute();
}catch(SQLException e){
System.out.println("Error Occured At ExecutePreparedStatement Operation");
e.printStackTrace();
throw e;
}
dbDisconnect();
}
As shree mentioned, I made a mistake when writing down column names, I fixed that, also fixed an error regarding the SYSDATE() function being written mistakingly as only SYSDATE. The SQL still wouldn't work, so I took out the BEGIN and END lines and it works fine now, no idea why though.

How to increase Testcoverage for Class that interacts with a Database?

I got a Java class called PatientRepositoryImpl, which contains some methods, that insert, delete or update Data in a MySql Database.
I've also written some Unit Tests for this class.
When i check the Coverage of my tests, i only get 59%, although almost every line of Code is marked green by the Coverage tool, except the SQL Exceptions.
I am new here and hope i did everything right, would be very thankful if someone could help me.
Here the code for my Repository and the Tests.
public class PatientRepositoryMySqlImpl implements PatientRepository {
private DatabaseConnection connection;
private PatientGenerator patientGenerator;
public PatientRepositoryMySqlImpl(DatabaseConnection connection, PatientGenerator patientGenerator) {
this.connection = connection;
this.patientGenerator = patientGenerator;
}
/* (non-Javadoc)
* #see com.id.hl7sim.PatientRepository#insertPatient()
*/
#Override
public void insertPatient(Patient patient) {
if (!patient.isValid()) {
throw new IllegalArgumentException("Incomplete Patient");
} else {
String insert = "INSERT INTO tbl_patient(lastname, firstname, gender, birthday) VALUES('"
+ patient.getLastname() + "', '" + patient.getFirstname() + "', '" + patient.getGender() + "', '"
+ patient.getBirthday().toString() + "');";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.prepareStatement(insert)) {
statement.executeUpdate(insert);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
}
/* (non-Javadoc)
* #see com.id.hl7sim.PatientRepository#insertListOfPatients()
*/
#Override
public void insertListOfPatients(List<Patient> allPatients) {
for (Patient patient : allPatients) {
insertPatient(patient);
}
}
/* (non-Javadoc)
* #see com.id.hl7sim.PatientRepository#getRandomPatient()
*/
#Override
public Patient getRandomPatient() {
Patient patient = new Patient.Builder().build();
String query = "SELECT * FROM tbl_patient ORDER BY RAND() LIMIT 1";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.createStatement();) {
ResultSet rs = statement.executeQuery(query);
rs.next();
setPatientBasicData(patient, rs);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return patient;
}
private void setPatientBasicData(Patient patient, ResultSet rs) {
try {
patient.setId(rs.getInt("id"));
patient.setLastname(rs.getString("lastname"));
patient.setFirstname(rs.getString("firstname"));
patient.setGender(rs.getString("gender"));
patient.setBirthday(parseBirthday(rs.getString("birthday")));
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
public LocalDate parseBirthday(String birthday) {
LocalDate localDate = LocalDate.parse(birthday);
return localDate;
}
/* (non-Javadoc)
* #see com.id.hl7sim.PatientRepository#admitRandomPatient()
*/
#Override
public Patient admitRandomPatient() {
Patient patient = getRandomPatient();
patient.setDepartment(patientGenerator.getRandomDepartment());
patient.setWard(patientGenerator.getRandomWard());
patient.setAdmissionDateTime(LocalDateTime.now());
patient.setStatus("I");
String insert = "INSERT INTO tbl_inpatients(id, ward, department, admissionDate, patientStatus) VALUES('"
+ patient.getId() + "', '" + patient.getWard() + "', '" + patient.getDepartment() + "', '"
+ patient.getAdmissionDateTime().toString() + "', '" + patient.getStatus() + "')";
try (Connection dbConnection = connection.getDBConnection();
PreparedStatement statement = dbConnection.prepareStatement(insert)) {
statement.executeUpdate(insert, Statement.RETURN_GENERATED_KEYS);
ResultSet keys = statement.getGeneratedKeys();
keys.next();
patient.setCaseId(keys.getInt(1));
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return patient;
}
public Patient getRandomInpatient() {
Patient patient = new Patient.Builder().build();
String query = "SELECT * FROM tbl_inpatients ip, tbl_patient p WHERE p.id = ip.id ORDER BY RAND() LIMIT 1";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.createStatement();) {
ResultSet rs = statement.executeQuery(query);
rs.next();
setPatientBasicData(patient, rs);
setPatientCaseData(patient, rs);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return patient;
}
public void setPatientCaseData(Patient patient, ResultSet rs) {
try {
patient.setWard(rs.getString("ward"));
patient.setDepartment(rs.getString("department"));
patient.setAdmissionDateTime(parseLocalDateTime(rs.getString("admissionDate")));
patient.setStatus(rs.getString("patientStatus"));
patient.setCaseId(rs.getInt("case"));
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
public LocalDateTime parseLocalDateTime(String localdatetime) {
localdatetime = localdatetime.replace("T", "");
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-ddHH:mm:ss.SSS");
LocalDateTime formattedLocalDateTime = LocalDateTime.parse(localdatetime, formatter);
return formattedLocalDateTime;
}
/* (non-Javadoc)
* #see com.id.hl7sim.PatientRepository#transferRandomPatient()
*/
#Override
public Patient transferRandomPatient() {
Patient patient = getRandomInpatient();
patient.setPriorWard(patient.getWard());
patient.setPriorDepartment(patient.getPriorDepartment());
patient.setDepartment(patientGenerator.getRandomDepartment());
patient.setWard(patientGenerator.getRandomWard());
String update = "UPDATE tbl_inpatients SET ward='" + patient.getWard() + "', department='"
+ patient.getDepartment() + "' WHERE id='" + patient.getId() + "'";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.prepareStatement(update)) {
statement.executeUpdate(update);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return patient;
}
/* (non-Javadoc)
* #see com.id.hl7sim.PatientRepository#dischargeRandomPatient()
*/
#Override
public Patient dischargeRandomPatient() {
Patient patient = getRandomInpatient();
patient.setDischargeDateTime(LocalDateTime.now());
insertFormerPatient(patient);
String delete = "DELETE FROM tbl_inpatients WHERE `case`=" + patient.getCaseId();
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.prepareStatement(delete)) {
statement.executeUpdate(delete);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return patient;
}
public void insertFormerPatient(Patient patient) {
String insert = "INSERT INTO tbl_formerpatients(`case`, `id`, ward, department, admissionDate, dischargeDate) VALUES('"
+ patient.getCaseId() + "', '" + patient.getId() + "', '" + patient.getWard() + "', '"
+ patient.getDepartment() + "', '" + patient.getAdmissionDateTime().toString() + "', '"
+ patient.getDischargeDateTime().toString() + "')";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.prepareStatement(insert)) {
statement.executeUpdate(insert);
} catch (SQLException e) {
System.out.println(e.getMessage());
}
}
public int countInpatients() {
int numberOfPatients = 0;
String query = "SELECT COUNT(id) AS numberOfPatients FROM tbl_inpatients";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.createStatement();) {
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
numberOfPatients = rs.getInt(1);
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return numberOfPatients;
}
public int countPatients() {
int numberOfPatients = 0;
String query = "SELECT COUNT(id) AS numberOfPatients FROM tbl_patient";
try (Connection dbConnection = connection.getDBConnection();
Statement statement = dbConnection.createStatement();) {
ResultSet rs = statement.executeQuery(query);
while (rs.next()) {
numberOfPatients = rs.getInt(1);
}
} catch (SQLException e) {
System.out.println(e.getMessage());
}
return numberOfPatients;
}
Tests
public class PatientRepositoryMySqlImplTest {
PatientRepository testPatientRepository;
Patient testPatient;
Patient testPatientTwo;
List<Patient> testBothPatients;
DatabaseConnection testConnection;
PatientGenerator testPatientGenerator;
Firstnames testFirstnames;
Lastnames testLastnames;
Departments testDepartments;
Wards testWards;
#Before
public void setUp() throws Exception {
testDepartments = JAXB.unmarshal(ClassLoader.getSystemResource("departments.xml"), Departments.class);
testWards = JAXB.unmarshal(ClassLoader.getSystemResource("wards.xml"), Wards.class);
testLastnames = JAXB.unmarshal(ClassLoader.getSystemResource("lastnames.xml"), Lastnames.class);
testFirstnames = JAXB.unmarshal(ClassLoader.getSystemResource("firstnames.xml"), Firstnames.class);
testPatientGenerator = new PatientGeneratorImpl(testFirstnames, testLastnames, testDepartments, testWards);
testPatient = testPatientGenerator.randomizeNewPatient();
testPatientTwo = testPatientGenerator.randomizeNewPatient();
testBothPatients = new ArrayList<Patient>();
testConnection = new MySqlConnection();
testPatientRepository = new PatientRepositoryMySqlImpl(testConnection, testPatientGenerator);
testPatientRepository.admitRandomPatient();
}
#Test
public void testAdmitRandomPatient() {
testPatient = testPatientRepository.admitRandomPatient();
assertTrue(testPatient.isValid());
}
#Test
public void testGetRandomInpatient() {
testPatient = testPatientRepository.getRandomInpatient();
assertTrue(testPatient.isValid());
}
#Test
public void testDischargeRandomPatientValid() {
testPatient = testPatientRepository.dischargeRandomPatient();
assertTrue(testPatient.isValid());
assertTrue(testPatient.getCaseId() != 0);
}
#Test
public void testDischargeRandomPatientDatabase() {
int beforeDischarge = testPatientRepository.countInpatients();
testPatient = testPatientRepository.dischargeRandomPatient();
int afterDischarge = testPatientRepository.countInpatients();
assertTrue(afterDischarge == beforeDischarge - 1);
}
#Test(expected = IllegalArgumentException.class)
public void testInsertPatientWitIncompletePatient() {
testPatient.setFirstname("");
testPatientRepository.insertPatient(testPatient);
}
#Test
public void testTransferRandomPatient() {
testPatient = testPatientRepository.transferRandomPatient();
assertTrue(testPatient.getDepartment() != testPatient.getPriorDepartment());
}
#Test
public void testInsertPatient() {
int numberOfPatients = testPatientRepository.countInpatients();
testPatientRepository.insertPatient(testPatient);
assertTrue(testPatientRepository.countInpatients() >= numberOfPatients);
}
#Test
public void testInsertListOfPatients() {
testBothPatients.add(testPatient);
testBothPatients.add(testPatientTwo);
int countInpatientsBeforeInsertion = testPatientRepository.countPatients();
testPatientRepository.insertListOfPatients(testBothPatients);
int countInpatientsAfterInsertion = testPatientRepository.countPatients();
assertTrue(countInpatientsAfterInsertion > countInpatientsBeforeInsertion);
}
Edit:
#Test
public void mockThrowsException() {
PatientRepository testPatientRepository = mock(PatientRepositoryMySqlImpl.class);
when(testPatientRepository.getRandomPatient()).thenThrow(SQLException.class);
testPatientRepository.admitRandomPatient();
}
While I completely agree that in order to increase the coverage you should definitely "simulate" the scenario that something goes wrong and SQLExceptions are thrown, let me introduce another approach that will also answer the question but hopefully give you another perspective.
JDBC is pretty cumbersome, and the tests that will throw SQL exceptions will probably not be the most pleasant tests to write. In addition, I see that you don't really deal with exceptions, and just log them in a console.
So maybe instead of trying to struggle with this, maybe you should consider to not work directly with JDBC but use some library that will wrap the hassle of JDBC usage for you. For example of such a library, take a look onto Spring JDBC Template, I know it's a pretty old stuff, but hey, working directly with JDBC is also probably not the most modern approach, so I'm trying to make fewer changes but still gain a value. Moreover one may say that its old and not fancy, I would say, a battle-tested library, that can be even without Spring itself.
Now since it wraps the JDBC Exception handling, among other things, the point is that you won't have to cover these cases at all. So your coverage will increase naturally.
Of course other low level and no-so-low level alternatives exist (like JDBI, or JOOQ to name a few), but this a different story, all of them will increase the coverage in a sense of a question you've asked.

Inserting issue into the database via java

I have a bit of a problem with inserting some data in the database. The data is being read by an CSV parser and changed to data besides that, I continue to get this error message:
Connected to the PostgreSQL server successfully.
Naam van de garage: P_Erasmusbrug, Longditude: 4.482313155, Latitude: 51.91024645
org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
at org.postgresql.core.v3.SimpleParameterList.bind(SimpleParameterList.java:65)
at org.postgresql.core.v3.SimpleParameterList.setStringParameter(SimpleParameterList.java:128)
at org.postgresql.jdbc.PgPreparedStatement.bindString(PgPreparedStatement.java:1023)
at org.postgresql.jdbc.PgPreparedStatement.setString(PgPreparedStatement.java:374)
at org.postgresql.jdbc.PgPreparedStatement.setString(PgPreparedStatement.java:358)
at Database.ConnectDatabase.parser(ConnectDatabase.java:80)
at Events.CSVReader.main(CSVReader.java:40)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:147)
Thank you for your service.
Naam van de garage: P_St.Jacobsplaats, Longditude: 4.482054381, Latitude: 51.92410235
Thank you for your service.
Naam van de garage: P_Schouwburgplein, Longditude: 4.473618335, Latitude: 51.92102728
org.postgresql.util.PSQLException: The column index is out of range: 1, number of columns: 0.
Which continues for all the other lines of data. Is there maybe a way to fix this as I don't really understand what the error message includes..
The a, b2, and c2 are variables for the ''name'' , ''londitude'' and ''latitude''.
package Database;
import java.io.*;
import java.sql.*;
import java.util.HashMap;
import java.sql.SQLException;
public class ConnectDatabase {
private final String url = "jdbc:postgresql://localhost/Project3";
private final String user = "postgres";
private final String password = "kaas123";
private Connection conn;
public Connection connect() {
Connection conn = null;
try {
conn = DriverManager.getConnection(url, user, password);
System.out.println("Connected to the PostgreSQL server successfully.");
} catch (SQLException exception) {
System.out.println(exception.getMessage());
}
this.conn = conn;
return conn;
}
public HashMap getGarages() {
HashMap<String, Double> newHashMap = new HashMap<String, Double>();
try {
Statement stmt = conn.createStatement();
ResultSet rs;
rs = stmt.executeQuery("SELECT deelgemeente, COUNT(garagenaam) FROM garages GROUP BY deelgemeente");
while (rs.next()) {
String deelGemeenteNaam = rs.getString("deelgemeente");
double garageNaamCount = rs.getDouble("COUNT");
newHashMap.put(deelGemeenteNaam, garageNaamCount);
}
} catch (Exception e) {
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}
return newHashMap;
}
public HashMap getTheftYear(int year) {
HashMap<String, Double> newHashMap = new HashMap<String, Double>();
try {
Statement stmt = conn.createStatement();
ResultSet rs;
rs = stmt.executeQuery("SELECT deelgemeente, percentagediefstal FROM autodiefstal WHERE jaar = " + year);
while (rs.next()) {
String deelGemeenteNaam = rs.getString("deelgemeente");
double deelPercentage = rs.getDouble("percentagediefstal");
newHashMap.put(deelGemeenteNaam, deelPercentage);
}
} catch (Exception e) {
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}
return newHashMap;
}
public int parser(String a, float b2, float c2) {
int updated = 0;
Connection conn = null;
PreparedStatement stmt = null;
try {
conn = DriverManager.getConnection(url, user, password);
String insertSQL = "INSERT INTO testparser(garagenaam, xpos, ypos) VALUES(" + a + "," + b2 + "," + c2 + ")";
stmt = conn.prepareStatement(insertSQL);
stmt.setString(1, a);
stmt.setFloat(2, b2);
stmt.setFloat(3, c2);
System.out.println("Inserted data into the database...");
updated = stmt.executeUpdate();
} catch (SQLException se) {
se.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
if (stmt != null)
conn.close();
} catch (SQLException se) {
}
try {
if (conn != null)
conn.close();
} catch (SQLException se) {
se.printStackTrace();
}
}
System.out.println("Thank you for your service.");
this.conn = conn;
return updated;
}
}
You aren't correctly using the ? placeholders system, replace :
String insertSQL = "INSERT INTO testparser(garagenaam, xpos, ypos) VALUES(" + a + "," + b2 + "," + c2 + ")";
with
String insertSQL = "INSERT INTO testparser(garagenaam, xpos, ypos) VALUES(?,?,?)";

SQL Prepared Statement & returning type

I have just created a method in my class file, were I insert data into my sql database.
1) Are these prepared statements correct?
2) I need to return a type car for the method (Where could this be done)?
.....As the error I get at the moment is the method must return a type Car (Car is the name of the class file)
public Car addVehicle(String aLicense, int aJourneys, String aUsername, String aPassword) {
Car c = new Car();
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url + dbName, userName, password);
statement = conn.createStatement();
String query = " insert into eflow.registration (cLicense, cJourneys, cUsername, cPassword)"
+ " values (?, ?, ?, ?)";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setString(1, aLicense);
preparedStmt.setInt(2, aJourneys);
preparedStmt.setString(3, aUsername);
preparedStmt.setString(4, aPassword);
preparedStmt.execute();
conn.close();
} catch (Exception e) {
System.err.println("Got an exception!");
System.err.println(e.getMessage());
}
return c;
}
Calling the method returns an error that the method is not applicable for arguments
//int addingID = Integer.parseInt(enteringID.getText());
String addingReg = enteringReg.getText();
int addingJourneys = Integer.parseInt(enteringJourneys.getText());
String addingUsername = enteringUsername.getText();
#SuppressWarnings("deprecation")
String addingPassword = enteringPassword.getText();
Car newCar = new Car(addingReg, addingJourneys, addingUsername, addingPassword);
int addStatus = myCar.addVehicle(newCar);
if (addStatus == 1) {
JOptionPane.showMessageDialog(null, "Vehicle Added");
enteringID.setText("(eg. 1-999)");
enteringReg.setText("(eg. - 162-MH-749)");
enteringJourneys.setText("(eg. 7)");
enteringUsername.setText("(eg. - username#domain.com)");
enteringPassword.setText("");
}
else {
JOptionPane.showMessageDialog(null, "Error, Please Try Again");
}
} catch (Exception f) {
JOptionPane.showMessageDialog(null, "Error, Please Try Again");
}
}
});
This is not a final answer for your question, but purely to clarify my comment.
If you want your method to return a Car object, you'll have to create an instance of class Car and return it:
public Car addVehicle(String aLicense, int aJourneys, String aUsername, String aPassword) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection(url + dbName, userName, password);
statement = conn.createStatement();
String query = " insert into eflow.registration (cLicense, cJourneys, cUsername, cPassword)"
+ " values (?, ?, ?, ?)";
PreparedStatement preparedStmt = conn.prepareStatement(query);
preparedStmt.setString(1, "'" + aLicense + "'");
preparedStmt.setInt(2, aJourneys);
preparedStmt.setString(3, "'" + aUsername + "'");
preparedStmt.setString(4, "'" + aPassword + "'");
preparedStmt.execute();
conn.close();
Car c = new Car();
//Do anything with the car object that you like.
//for example: c.setColor("blue");
return c;
} catch (Exception e) {
System.err.println("Got an exception!");
System.err.println(e.getMessage());
//kayaman is correct here: we still need to return something here in order to be able to compile
return null;
}
Separate the logic!
Use this class to retrieve connection where you need it:
public class DatabaseConnection
{
private static final String CONN_URL = "some connection url";
private static Connection instance = null;
static
{
try
{
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e)
{
e.printStackTrace();
}
}
public static synchronized Connection getInstance() throws SQLException
{
if (instance == null)
{
instance = DriverManager.getConnection(CONN_URL);
}
return instance;
}
}
Use it in your function like this:
public Car addVehicle(String aLicense, int aJourneys, String aUsername, String aPassword)
{
String sql = "insert into eflow.registration (cLicense, cJourneys, cUsername, cPassword) values (?, ?, ?, ?)";
try (Connection conn = DatabaseConnection.getInstance(); PreparedStatement prepStatement = conn.prepareStatement(sql))
{
Car successfulAdd = new Car();
prepStatement.setString(1, aLicense);
prepStatement.setInt(2, aJourneys);
prepStatement.setString(3, aUsername);
prepStatement.setString(4, aPassword);
if (prepStatement.execute())
{
return successfulAdd;
}
}
catch (SQLException e)
{
e.printStackTrace();
}
return null;
}

Categories