后端
概要
- 以Java为后端开发语言,以MySQL为数据库管理系统
- 以Spring Boot作为后端的开发框架
- 以JHipster开发平台来开发生成和部署Spring Boot + Angular的Web应用
- 使用Java普通对象(POJO)与数据库表建立映射关系。
实体配置
![1](https://user-images.githubusercontent.com/45042260/82551656-2d41b480-9b93-11ea-9365-9a45fb9d8f05.png)
Campus
![image](https://user-images.githubusercontent.com/45042260/82551698-45b1cf00-9b93-11ea-8ddd-40b9b3f03b24.png)
@Table(name = "campus")
public class Campus implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "address")
private String address;
}
关联
Campus关联到Major
@OneToMany(mappedBy = "campus")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Major> majors = new HashSet<>();
Major
![image](https://user-images.githubusercontent.com/45042260/82552010-e4d6c680-9b93-11ea-86f1-dae21490599e.png)
@Table(name = "major")
public class Major implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
}
关联
Major关联到SchoolClass,Teacher,Course
@OneToMany(mappedBy = "major")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<SchoolClass> schoolClasses = new HashSet<>();
@OneToMany(mappedBy = "major")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Teacher> teachers = new HashSet<>();
@OneToMany(mappedBy = "major")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Course> courses = new HashSet<>();
反向关联到Campus可提高执行效率,下同
@ManyToOne
@JsonIgnoreProperties("majors")
private Campus campus;
SchoolClass
![image](https://user-images.githubusercontent.com/45042260/82552027-eef8c500-9b93-11ea-944f-67612ac6ed19.png)
@Table(name = "school_class")
public class SchoolClass implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Column(name = "created_date")
private LocalDate createdDate;
}
关联
SchoolClass关联到Student,Grage,Major
@OneToOne
@JoinColumn(unique = true)
private Teacher master;
@OneToMany(mappedBy = "schoolClass")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Student> students = new HashSet<>();
@ManyToOne
@JsonIgnoreProperties("schoolClasses")
private Grade grade;
@ManyToOne
@JsonIgnoreProperties("schoolClasses")
private Major major;
Teacher
![image](https://user-images.githubusercontent.com/45042260/82552067-020b9500-9b94-11ea-85c0-65541813995c.png)
@Table(name = "teacher")
public class Teacher implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "work_number")
private String workNumber;
@Column(name = "start_date")
private LocalDate startDate;
@Column(name = "email")
private String email;
@Enumerated(EnumType.STRING)
@Column(name = "title")
private Title title;
}
关联
Teacher关联到SchoolClass,People,Major
@OneToMany(mappedBy = "teacher")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Course> courses = new HashSet<>();
@OneToOne(mappedBy = "master")
@JsonIgnore
private SchoolClass schoolClass;
@OneToOne(mappedBy = "teacher")
@JsonIgnore
private People people;
@ManyToOne
@JsonIgnoreProperties("teachers")
private Major major;
Course
![image](https://user-images.githubusercontent.com/45042260/82552107-0fc11a80-9b94-11ea-81ba-af02841458f6.png)
@Table(name = "course")
public class Course implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String name;
@Enumerated(EnumType.STRING)
@Column(name = "exam_type")
private ExamType examType;
}
关联
Course关联到Semaster,Major,Teacher
@OneToMany(mappedBy = "course")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Interval> times = new HashSet<>();
@ManyToOne
@JsonIgnoreProperties("courses")
private Semaster semaster;
@ManyToOne
@JsonIgnoreProperties("courses")
private Major major;
@ManyToOne
@JsonIgnoreProperties("courses")
private Teacher teacher;
Grade
![image](https://user-images.githubusercontent.com/45042260/82552141-1e0f3680-9b94-11ea-9059-33b6e324fbd4.png)
@Table(name = "grade")
public class Grade implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "grade")
private Integer grade;
}
Student
![image](https://user-images.githubusercontent.com/45042260/82552168-2f584300-9b94-11ea-8b6b-ef9dc8e78cc2.png)
@Table(name = "student")
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "student_number")
private String studentNumber;
@Column(name = "start_date")
private String startDate;
@Column(name = "email")
private String email;
@Column(name = "major")
private String major;
}
关联
Student关联到JException,Record,People,SchoolClasss
@OneToMany(mappedBy = "student")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<JException> exceptions = new HashSet<>();
@OneToMany(mappedBy = "student")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Record> records = new HashSet<>();
@OneToOne(mappedBy = "student")
@JsonIgnore
private People people;
@ManyToOne
@JsonIgnoreProperties("students")
private SchoolClass schoolClass;
Interval
![image](https://user-images.githubusercontent.com/45042260/82552442-b3122f80-9b94-11ea-987d-b88ae9b7a34c.png)
@Table(name = "jhi_interval")
public class Interval implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
@Column(name = "day")
private WeekDay day;
@Column(name = "start")
private Integer start;
@Column(name = "end")
private Integer end;
}
关联
Interval关联到Course
@ManyToOne
@JsonIgnoreProperties("times")
private Course course;
Record
![image](https://user-images.githubusercontent.com/45042260/82552468-c02f1e80-9b94-11ea-9557-6eed715fdafe.png)
@Table(name = "record")
public class Record implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "date")
private LocalDate date;
@Column(name = "score")
private Integer score;
}
关联
Record关联到Semaster,Course,Student
@ManyToOne
@JsonIgnoreProperties("records")
private Semaster semaster;
@ManyToOne
@JsonIgnoreProperties("records")
private Course course;
@ManyToOne
@JsonIgnoreProperties("records")
private Student student;
JException
![image](https://user-images.githubusercontent.com/45042260/82552512-d2a95800-9b94-11ea-9b2a-229ff8e0c648.png)
@Table(name = "j_exception")
public class JException implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "date")
private LocalDate date;
@Column(name = "is_youth_league")
private Boolean isYouthLeague;
@Column(name = "cause")
private String cause;
}
关联
JException关联到Major,SchoolClass,Grade,Student
@ManyToOne
@JsonIgnoreProperties("jExceptions")
private Major originalMajor;
@ManyToOne
@JsonIgnoreProperties("jExceptions")
private Major newMajor;
@ManyToOne
@JsonIgnoreProperties("jExceptions")
private SchoolClass originalSchoolClass;
@ManyToOne
@JsonIgnoreProperties("jExceptions")
private SchoolClass newSchoolClass;
@ManyToOne
@JsonIgnoreProperties("jExceptions")
private Grade originalGrade;
@ManyToOne
@JsonIgnoreProperties("jExceptions")
private Grade newGrade;
@ManyToOne
@JsonIgnoreProperties("exceptions")
private Student student;
Semaster
![image](https://user-images.githubusercontent.com/45042260/82552542-e0f77400-9b94-11ea-88f7-511db4e3054a.png)
@Table(name = "semaster")
public class Semaster implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "year")
private Integer year;
@Enumerated(EnumType.STRING)
@Column(name = "season")
private Season season;
}
People
![image](https://user-images.githubusercontent.com/45042260/82553512-c1614b00-9b96-11ea-8c3c-e650ed0eb218.png)
@Table(name = "people")
public class People implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Enumerated(EnumType.STRING)
@Column(name = "id_type")
private IdType idType;
@Column(name = "chinese_name")
private String chineseName;
@Column(name = "english_name")
private String englishName;
@Column(name = "gender")
private Integer gender;
@Column(name = "birth_date")
private LocalDate birthDate;
@Column(name = "race")
private String race;
@Column(name = "nation")
private String nation;
@Column(name = "address")
private String address;
@Column(name = "postcode")
private String postcode;
@Column(name = "telephone")
private String telephone;
}
关联
@OneToOne
@JoinColumn(unique = true)
private Teacher teacher;
@OneToOne
@JoinColumn(unique = true)
private Student student;
永久化
创建业务服务Service
AuditEventService
@Service
@Transactional
public class AuditEventService {
private final Logger log = LoggerFactory.getLogger(AuditEventService.class);
private final JHipsterProperties jHipsterProperties;
private final PersistenceAuditEventRepository persistenceAuditEventRepository;
private final AuditEventConverter auditEventConverter;
public AuditEventService(
PersistenceAuditEventRepository persistenceAuditEventRepository,
AuditEventConverter auditEventConverter, JHipsterProperties jhipsterProperties) {
this.persistenceAuditEventRepository = persistenceAuditEventRepository;
this.auditEventConverter = auditEventConverter;
this.jHipsterProperties = jhipsterProperties;
}
/**
* Old audit events should be automatically deleted after 30 days.
*
* This is scheduled to get fired at 12:00 (am).
*/
@Scheduled(cron = "0 0 12 * * ?")
public void removeOldAuditEvents() {
persistenceAuditEventRepository
.findByAuditEventDateBefore(Instant.now().minus(jHipsterProperties.getAuditEvents().getRetentionPeriod(), ChronoUnit.DAYS))
.forEach(auditEvent -> {
log.debug("Deleting audit data {}", auditEvent);
persistenceAuditEventRepository.delete(auditEvent);
});
}
public Page<AuditEvent> findAll(Pageable pageable) {
return persistenceAuditEventRepository.findAll(pageable)
.map(auditEventConverter::convertToAuditEvent);
}
public Page<AuditEvent> findByDates(Instant fromDate, Instant toDate, Pageable pageable) {
return persistenceAuditEventRepository.findAllByAuditEventDateBetween(fromDate, toDate, pageable)
.map(auditEventConverter::convertToAuditEvent);
}
public Optional<AuditEvent> find(Long id) {
return persistenceAuditEventRepository.findById(id)
.map(auditEventConverter::convertToAuditEvent);
}
}
EMailService
提供邮件服务
@Service
public class MailService {
private final Logger log = LoggerFactory.getLogger(MailService.class);
private static final String USER = "user";
private static final String BASE_URL = "baseUrl";
private final JHipsterProperties jHipsterProperties;
private final JavaMailSender javaMailSender;
private final MessageSource messageSource;
private final SpringTemplateEngine templateEngine;
public MailService(JHipsterProperties jHipsterProperties, JavaMailSender javaMailSender,
MessageSource messageSource, SpringTemplateEngine templateEngine) {
this.jHipsterProperties = jHipsterProperties;
this.javaMailSender = javaMailSender;
this.messageSource = messageSource;
this.templateEngine = templateEngine;
}
@Async
public void sendEmail(String to, String subject, String content, boolean isMultipart, boolean isHtml) {
···
}
@Async
public void sendEmailFromTemplate(User user, String templateName, String titleKey) {
···
}
@Async
public void sendActivationEmail(User user) {
···
}
@Async
public void sendCreationEmail(User user) {
···
}
@Async
public void sendPasswordResetMail(User user) {
···
}
}
UserSeivice
@Service
@Transactional
public class UserService {
private final Logger log = LoggerFactory.getLogger(UserService.class);
private final UserRepository userRepository;
private final PasswordEncoder passwordEncoder;
private final UserSearchRepository userSearchRepository;
private final AuthorityRepository authorityRepository;
private final CacheManager cacheManager;
public UserService(UserRepository userRepository, PasswordEncoder passwordEncoder, UserSearchRepository userSearchRepository, AuthorityRepository authorityRepository, CacheManager cacheManager) {
···
}
public Optional<User> activateRegistration(String key) {
···
}
public Optional<User> completePasswordReset(String newPassword, String key) {
···
}
public Optional<User> requestPasswordReset(String mail) {
···
}
public User registerUser(UserDTO userDTO, String password) {
···
}
private boolean removeNonActivatedUser(User existingUser) {
if (existingUser.getActivated()) {
return false;
}
userRepository.delete(existingUser);
userRepository.flush();
this.clearUserCaches(existingUser);
return true;
}
public User createUser(UserDTO userDTO) {
···
}
/**
* Update basic information (first name, last name, email, language) for the current user.
*
* @param firstName first name of user.
* @param lastName last name of user.
* @param email email id of user.
* @param langKey language key.
* @param imageUrl image URL of user.
*/
public void updateUser(String firstName, String lastName, String email, String langKey, String imageUrl) {
···
}
public Optional<UserDTO> updateUser(UserDTO userDTO) {
···
}
public void deleteUser(String login) {
···
}
public void changePassword(String currentClearTextPassword, String newPassword) {
···
}
@Transactional(readOnly = true)
public Page<UserDTO> getAllManagedUsers(Pageable pageable) {
return userRepository.findAllByLoginNot(pageable, Constants.ANONYMOUS_USER).map(UserDTO::new);
}
@Transactional(readOnly = true)
public Optional<User> getUserWithAuthoritiesByLogin(String login) {
return userRepository.findOneWithAuthoritiesByLogin(login);
}
@Transactional(readOnly = true)
public Optional<User> getUserWithAuthorities(Long id) {
return userRepository.findOneWithAuthoritiesById(id);
}
@Transactional(readOnly = true)
public Optional<User> getUserWithAuthorities() {
return SecurityUtils.getCurrentUserLogin().flatMap(userRepository::findOneWithAuthoritiesByLogin);
}
@Scheduled(cron = "0 0 1 * * ?")
public void removeNotActivatedUsers() {
···
}
public List<String> getAuthorities() {
return authorityRepository.findAll().stream().map(Authority::getName).collect(Collectors.toList());
}
private void clearUserCaches(User user) {
···
}
}
创建控制器Controller
以下文件为各种控制器文件(文件目录在\src\main\java\com\mycompany\myapp\web\rest)
![image](https://user-images.githubusercontent.com/45042260/82552913-a4784800-9b95-11ea-8830-40a33d370e49.png)
@RestController
@RequestMapping("/api")
@Transactional
···