diff --git a/.idea/compiler.xml b/.idea/compiler.xml index f006a55..5a76f28 100644 --- a/.idea/compiler.xml +++ b/.idea/compiler.xml @@ -6,6 +6,7 @@ + diff --git a/.idea/jarRepositories.xml b/.idea/jarRepositories.xml new file mode 100644 index 0000000..712ab9d --- /dev/null +++ b/.idea/jarRepositories.xml @@ -0,0 +1,20 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/pom.xml b/pom.xml index d97c43d..19fda97 100644 --- a/pom.xml +++ b/pom.xml @@ -7,12 +7,29 @@ com.zipcoder.lab jdbcdao 1.0-SNAPSHOT + + + + org.apache.maven.plugins + maven-compiler-plugin + + 8 + 8 + + + + - + junit junit 4.10 - + + mysql + mysql-connector-java + 5.1.49 + + \ No newline at end of file diff --git a/src/main/java/MainApplication.java b/src/main/java/MainApplication.java new file mode 100644 index 0000000..04511de --- /dev/null +++ b/src/main/java/MainApplication.java @@ -0,0 +1,121 @@ +import daos.StudentRepository; +import models.Student; + +import com.mysql.jdbc.Driver; +import java.sql.*; +import java.time.LocalDate; +import java.util.StringJoiner; + +public class MainApplication { + + public static void main(String[] args) { + registerJDBCDriver(); + Connection mysqlDbConnection = getConnection("mysql"); + StudentRepository studentRepository = new StudentRepository(mysqlDbConnection); + executeStatement(mysqlDbConnection, "DROP DATABASE IF EXISTS IAODataTest;"); + executeStatement(mysqlDbConnection, "CREATE DATABASE IF NOT EXISTS IAODataTest;"); + executeStatement(mysqlDbConnection, "USE IAODataTest;"); + executeStatement(mysqlDbConnection, new StringBuilder() + .append("CREATE TABLE IF NOT EXISTS IAODataTest.students(") + .append("id int auto_increment primary key,") + .append("name text not null,") + .append("grade int not null,") + .append("school text,") + .append("dob DATE,") + .append("age int);") + .toString()); + + studentRepository.create(new Student(10L, "Thai", 3, "Sanford", LocalDate.of(2011, 11, 11))); + studentRepository.create(new Student(11L, "Tyson", 6, "Kirk Middle", LocalDate.of(2009, 4,17))); + studentRepository.create(new Student(12L, "Amira", 1, "Sanford", LocalDate.of(2014, 1,3))); + studentRepository.create(new Student(13L, "David", 3, "New Castle Charter", LocalDate.of(2011, 3, 27))); + studentRepository.create(new Student(16L, "Kassidy", 10, "Ursuline Academy", LocalDate.of(2005, 5,20))); + studentRepository.create(new Student(15L, "Meadow", 6, "Talley Middle", LocalDate.of(2009, 12, 13))); + studentRepository.create(new Student (19L, "Arden", 3, "Hanby Elementary", LocalDate.of(2011, 10, 1))); + System.out.println(studentRepository.readAll()); + Student arden = new Student (19L, "Arden", 3, "Hanby Elementary"); + studentRepository.delete(15L); + studentRepository.delete(arden); + Student kassidy = new Student(16L, "Kassidy", 10, "Ursuline Academy"); + Student david = new Student(13L, "David", 3, "New Castle Charter", LocalDate.of(2011, 3, 27)); + studentRepository.updateId(17L, kassidy); + studentRepository.updateBirthday(LocalDate.of(2010, 10, 10), david); + System.out.println(studentRepository.readAll()); + System.out.println(studentRepository.read(17L)); + System.out.println(studentRepository.read(13L)); + + } + + static ResultSet executeQuery(Connection connection, String sqlQuery) { + try { + Statement statement = getScrollableStatement(connection); + return statement.executeQuery(sqlQuery); + } catch (SQLException e) { + throw new Error(e); + } + } + + static void printResults(ResultSet resultSet) { + try { + for (int rowNumber = 0; resultSet.next(); rowNumber++) { + String firstColumnData = resultSet.getString(1); + String secondColumnData = resultSet.getString(2); + String thirdColumnData = resultSet.getString(3); + System.out.println(new StringJoiner("\n") + .add("Row number = " + rowNumber) + .add("First Column = " + firstColumnData) + .add("Second Column = " + secondColumnData) + .add("Third column = " + thirdColumnData)); + } + } catch (SQLException e) { + throw new Error(e); + } + } + + static void executeStatement(Connection connection, String sqlStatement) { + try { + Statement statement = getScrollableStatement(connection); + statement.execute(sqlStatement); + } catch (SQLException e) { + throw new Error(e); + } + } + + static Statement getScrollableStatement(Connection connection) { + int resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE; + int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY; + try { // scrollable statements can be iterated more than once without closing + return connection.createStatement(resultSetType, resultSetConcurrency); + } catch (SQLException e) { + throw new Error(e); + } + } + + + //change root name and password to local info + static Connection getConnection(String dbVendor) { + String username = "root"; + String password = "pw"; + String url = new StringBuilder() + .append("jdbc:") + .append(dbVendor) + .append("://127.0.0.1/") + .append("?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC") + .toString(); + try { + return DriverManager.getConnection(url, username, password); + } catch (SQLException e) { + throw new Error(e); + } + } + + static void registerJDBCDriver() { + // Attempt to register JDBC Driver + try { + DriverManager.registerDriver(Driver.class.newInstance()); + } catch (InstantiationException | IllegalAccessException | SQLException e1) { + throw new RuntimeException(e1); + } + } + +} diff --git a/src/main/java/daos/Repo.java b/src/main/java/daos/Repo.java new file mode 100644 index 0000000..5203de0 --- /dev/null +++ b/src/main/java/daos/Repo.java @@ -0,0 +1,39 @@ +package daos; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.sql.Statement; + +public interface Repo { + default void executeStatement(String sqlStatement) { + try { + Statement statement = getScrollableStatement(); + statement.execute(sqlStatement); + } catch (SQLException e) { + throw new Error(e); + } + } + + default Statement getScrollableStatement() { + int resultSetType = ResultSet.TYPE_SCROLL_INSENSITIVE; + int resultSetConcurrency = ResultSet.CONCUR_READ_ONLY; + try { // scrollable statements can be iterated more than once without closing + return getConnection().createStatement(resultSetType, resultSetConcurrency); + } catch (SQLException e) { + throw new Error(e); + } + } + + default ResultSet executeQuery(String sqlQuery) { + try { + Statement statement = getScrollableStatement(); + return statement.executeQuery(sqlQuery); + } catch (SQLException e) { + throw new Error(e); + } + } + + Connection getConnection(); + +} diff --git a/src/main/java/daos/StudentRepository.java b/src/main/java/daos/StudentRepository.java new file mode 100644 index 0000000..d79a029 --- /dev/null +++ b/src/main/java/daos/StudentRepository.java @@ -0,0 +1,149 @@ +package daos; + +import models.Student; + +import java.sql.Connection; +import java.sql.ResultSet; +import java.sql.SQLException; +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.util.ArrayList; +import java.util.List; + +public class StudentRepository implements Repo{ + + private Connection connection; + + public StudentRepository(Connection connection) { + this.connection = connection; + } + + @Override + public Connection getConnection() { + return connection; + } + + public void create(Student student) { + executeStatement(String.format(new StringBuilder() + .append("INSERT INTO IAODataTest.students(") + .append("id, name, grade, school, DOB, age) ") + .append("VALUES (%s, '%s', %s, '%s', DATE '%s', %s);") + .toString(), + student.getId(), + student.getName(), + student.getGrade(), + student.getSchool(), + student.getDateOfBirthSQLString(), + student.getAge())); //age will appear in table but not in resultSet; + } + + public List readAll() { + ResultSet resultSet = executeQuery("SELECT * FROM IAODataTest.students;"); + List list = new ArrayList<>(); + try { + while (resultSet.next()) { + String id = resultSet.getString(1); + String name = resultSet.getString(2); + String grade = resultSet.getString(3); + String school = resultSet.getString(4); + String dob = resultSet.getString(5); + String age = resultSet.getString(6); + list.add(new Student ( + Long.parseLong(id), + name, + Integer.parseInt(grade), + school, + LocalDate.parse(dob), + Integer.parseInt(age))); + } + } catch (SQLException throwables) { + throw new RuntimeException(throwables); + } + return list; + } + + + public Student read(Long studentId) { + return readAll() + .stream() + .filter(student -> student.getId().equals(studentId)) + .findAny() + .get(); + } + + public void updateId(Long newId, Student newStudentData) { + Long reset = newId; + Long find = newStudentData.getId(); + executeStatement(String.format(new StringBuilder() + .append("UPDATE students ") + .append("SET id = %s ") + .append("WHERE id = %s;") + .toString(), + reset, + find)); + + + } + + public void updateSchool(String newSchool, Student newStudentData){ + String reset = newSchool; + Long find = newStudentData.getId(); + executeStatement(String.format(new StringBuilder() + .append("UPDATE students ") + .append("SET school = '%s' ") + .append("WHERE id = %s;") + .toString(), + reset, + find)); + + } + + public void updateBirthday(LocalDate date, Student newStudentData){ + String reset = getDOBString(date); + Long find = newStudentData.getId(); + executeStatement(String.format(new StringBuilder() + .append("UPDATE students ") + .append("SET dob = DATE '%s' ") + .append("WHERE id = %s;") + .toString(), + reset, + find)); + + } + + public String getDOBString(LocalDate date){ + String joined = ""; + int year = date.getYear(); + int month = date.getMonthValue(); + int day = date.getDayOfMonth(); + + if (month < 10 && day < 10){ + joined = String.format("%s-0%s-0%s", year, month, day); + } else if (month < 10){ + joined = String.format("%s-0%d-%s", year, month, day); + } else if (day < 10) { + joined = String.format("%s-%s-0%s", year, month, day); + } else + + joined = String.format("%s-%s-%s", year, month, day); + + + return joined; + + } + + public void delete(Long id) { + Long deleteThis = id; + executeStatement(String.format(new StringBuilder() + .append("DELETE FROM students WHERE id = %s;") + .toString(), + id)); + + } + + public void delete(Student student) { + Long find = student.getId(); + delete(find); + + } +} diff --git a/src/main/java/models/Student.java b/src/main/java/models/Student.java new file mode 100644 index 0000000..b5d1030 --- /dev/null +++ b/src/main/java/models/Student.java @@ -0,0 +1,134 @@ +package models; + +import java.text.SimpleDateFormat; +import java.time.LocalDate; +import java.time.Period; +import java.time.format.DateTimeFormatter; +import java.time.format.DateTimeFormatterBuilder; +import java.util.Calendar; +import java.util.Date; +import java.util.GregorianCalendar; +import java.util.StringJoiner; + +public class Student { + + private Long id; + private String name; + private Integer grade; + private String school; + private LocalDate dateOfBirth; + private Integer age; + private String location; + + + public Student() { + } + + public Student(Long id, String name, Integer grade, String school){ + this.id = id; + this.name = name; + this.grade = grade; + this.school = school; + } + + public Student(Long id, String name, Integer grade, String school, LocalDate dateOfBirth){ + this(id, name, grade, school); + this.dateOfBirth = dateOfBirth; + this.age = getAge(); + } + + public Student(Long id, String name, Integer grade, String school, LocalDate dateOfBirth, Integer age){ + this(id, name, grade, school, dateOfBirth); + this.age = age; + } + + public Student (Long id, String name, Integer grade, String school, LocalDate dateOfBirth, String location){ + this(id, name, grade, school, dateOfBirth); + this.location = location; + } + + + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Integer getGrade() { + return grade; + } + + public void setGrade(Integer grade) { + this.grade = grade; + } + + public String getSchool() { + return school; + } + + public void setSchool(String school) { + this.school = school; + } + + public String getDateOfBirthSQLString() { + String toDate = getDOBString(); + return toDate; + } + + public String getDOBString(){ + String joined = ""; + int year = dateOfBirth.getYear(); + int month = dateOfBirth.getMonthValue(); + int day = dateOfBirth.getDayOfMonth(); + + if (month < 10 && day < 10){ + joined = String.format("%s-0%s-0%s", year, month, day); + } else if (month < 10){ + joined = String.format("%s-0%d-%s", year, month, day); + } else if (day < 10) { + joined = String.format("%s-%s-0%s", year, month, day); + } else + + joined = String.format("%s-%s-%s", year, month, day); + + + return joined; + + } + + public Integer getAge() { + int age = Period.between(dateOfBirth, LocalDate.now()).getYears(); + return age; + } + public String getLocation() { + return location; + } + + public void setLocation(String location) { + this.location = location; + } + + @Override + public String toString() { //add JSON ObjectMapper exception here + return "Student{" + + "id=" + id + + ", name='" + name + '\'' + + ", grade=" + grade + + ", school='" + school + '\'' + + ", dateOfBirth=" + dateOfBirth + + ", age=" + age + + ", location='" + location + '\'' + + '}'; + } +} diff --git a/src/main/java/models/Tutor.java b/src/main/java/models/Tutor.java new file mode 100644 index 0000000..337cb24 --- /dev/null +++ b/src/main/java/models/Tutor.java @@ -0,0 +1,78 @@ +package models; + +public class Tutor { + + private Long id; + private String name; + private Specialty specialty; + private String availability; //can you add multiple enum fields to a database column? + private Preference preference; + + + private enum Specialty{ + PRESCHOOL, PRIMARY, SECONDARY, POST_SECONDARY; + } + + private enum Preference{ + VIRTUAL, IN_PERSON; + } + + public Tutor(Long id, String name, Specialty specialty, String availability, Preference preference){ + this.id = id; + this.name = name; + this.specialty = specialty; + this.availability = availability; + this.preference = preference; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public Specialty getSpecialty() { + return specialty; + } + + public void setSpecialty(Specialty specialty) { + this.specialty = specialty; + } + + public String getAvailability() { + return availability; + } + + public void setAvailability(String availability) { + this.availability = availability; + } + + public Preference getPreference() { + return preference; + } + + public void setPreference(Preference preference) { + this.preference = preference; + } + + @Override + public String toString() { + return "Tutor{" + + "id=" + id + + ", name='" + name + '\'' + + ", specialty=" + specialty + + ", availability='" + availability + '\'' + + ", preference=" + preference + + '}'; + } +} diff --git a/src/test/java/models/StudentTest.java b/src/test/java/models/StudentTest.java new file mode 100644 index 0000000..2159914 --- /dev/null +++ b/src/test/java/models/StudentTest.java @@ -0,0 +1,30 @@ +package models; + +import org.junit.Assert; +import org.junit.Test; + +import java.time.LocalDate; + +public class StudentTest { + + @Test + public void getDOBStringTest(){ + //given + Long id = 50L; + String name = "Thai"; + int grade = 4; + String school = "Sanford"; + LocalDate dob = LocalDate.of(2011, 3, 11); + Student student = new Student(id, name, grade, school, dob); + String expected = "2011-03-11"; + + //when + String actual = student.getDateOfBirthSQLString(); + + //then + Assert.assertEquals(expected, actual); + + + + } +} diff --git a/target/classes/MainApplication.class b/target/classes/MainApplication.class new file mode 100644 index 0000000..055e207 Binary files /dev/null and b/target/classes/MainApplication.class differ diff --git a/target/classes/daos/Repo.class b/target/classes/daos/Repo.class new file mode 100644 index 0000000..7b468cb Binary files /dev/null and b/target/classes/daos/Repo.class differ diff --git a/target/classes/daos/StudentRepository.class b/target/classes/daos/StudentRepository.class new file mode 100644 index 0000000..20c9145 Binary files /dev/null and b/target/classes/daos/StudentRepository.class differ diff --git a/target/classes/models/Student.class b/target/classes/models/Student.class new file mode 100644 index 0000000..fbc9992 Binary files /dev/null and b/target/classes/models/Student.class differ diff --git a/target/classes/models/Tutor$Preference.class b/target/classes/models/Tutor$Preference.class new file mode 100644 index 0000000..d58bd4b Binary files /dev/null and b/target/classes/models/Tutor$Preference.class differ diff --git a/target/classes/models/Tutor$Specialty.class b/target/classes/models/Tutor$Specialty.class new file mode 100644 index 0000000..e031c03 Binary files /dev/null and b/target/classes/models/Tutor$Specialty.class differ diff --git a/target/classes/models/Tutor.class b/target/classes/models/Tutor.class new file mode 100644 index 0000000..2baf447 Binary files /dev/null and b/target/classes/models/Tutor.class differ diff --git a/target/test-classes/models/StudentTest.class b/target/test-classes/models/StudentTest.class new file mode 100644 index 0000000..44e2a75 Binary files /dev/null and b/target/test-classes/models/StudentTest.class differ