Giter Site home page Giter Site logo

database_repo's Introduction

Hello, I'm Sheldon Niu! 👋

🙋‍♂️ About Me

I'm a graduate of the Department of Computer Science at the University of Science and Technology of China (USTC). Formerly a web infrastructure engineer at ByteDance, I'm currently the founder of AskYourDatabase, helping 1000+ CEO/CTOs to get insights without the help of developers.

In addition, I'm the creator of Raber, a project aiming to simplify web development and democratize the creation of professional frontends.

I also share my insights and interact with over 70,000 followers on Zhihu.

In my spare time, I enjoy playing guitar and exploring music arrangement and theory.

🌐 Connect with Me

📫 Contact Me

Feel free to email me for any inquiries or suggestions at [email protected]

database_repo's People

Contributors

jhipster-bot avatar niudai avatar

Watchers

 avatar  avatar  avatar  avatar

Forkers

warriorod

database_repo's Issues

部分前端报告

前端部分

前端部分所用文件主要位于 src -- main -- webapp
下面介绍webapp中的前端内容

WEB-INF

文件夹内包含了web.xml文件,指定了html文件的浏览器处理方式

content

文件夹中包含了网页使用的图片与CSS和SCSS文件,供其他模块调用

i18n

文件夹中包含了国际化模块使用的前端文件,在切换语言时使用.

app

文件夹中包含着数据库应用处理各个页面前端的文件,下面主要介绍该文件夹内文件

  • home

文件夹中包含着主页部分的前端内容,用来处理主页部分的内容显示

  • layouts

文件夹中包含着错误信息窗口,悬浮栏,页脚等模块的模板前端,供其他模块调用

  • shared

文件夹中包含了各类实体的model设置,以及alert设置与登录模块界面设置等杂类文件,供其他部分调用

  • entities

文件夹中包含了对数据库实体进行操作时的前端显示部分文件,其中

  1. campus -- 校区

  2. course -- 课程

  3. grade -- 年级

  4. interval -- 开课时间

  5. j-exception -- 学籍异动

  6. major -- 专业,

  7. people -- 个人信息

  8. record -- 选课记录

  9. school-class -- 班级

  10. semaster -- 学期

  11. student -- 学生

  12. teacher -- 教师

由于各个实体部分的前端处理类似,故下面选择以course为例介绍前端处理过程

Course的前端处理过程

首先,前端文件夹中包含了course.component.html,course-delete-dialog.component.html, course-detail.component.html, course-update.component.html 4个html文件,分别对应course信息显示,删除界面,详细信息界面,以及信息创建或更新界面的模块显示

inf_show.png

图1.信息显示

delete.png

图2.删除界面

VInf.png

图3.详细信息

CorE.png

图4.信息创建或编辑

另外,文件夹中的.ts文件控制在网页操作产生的动作以及与服务器的信息交换
以course删除为例介绍过程

1.在图1中对应项点击删除后,在course.component.ts中调用

delete(course: ICourse): void {
    const modalRef = this.modalService.open(CourseDeleteDialogComponent, { size: 'lg', backdrop: 'static' });
    modalRef.componentInstance.course = course;
 }

2.随后出现类似图2的删除界面,点击删除后,在course-delete-dialog.component.ts中调用

  confirmDelete(id: number): void {
    this.courseService.delete(id).subscribe(() => {
      this.eventManager.broadcast('courseListModification');
      this.activeModal.close();
    });
  }

3.随后在course.service.ts中调用

delete(id: number): Observable<HttpResponse<{}>> {
   return this.http.delete(`${this.resourceUrl}/${id}`, { observe: 'response' });
 }

与服务器端进行通讯,通过服务器端返回参数调用其他模块

下面通过流程图来展示各个功能模块的处理过程
F_INF.png

图5.信息显示流程

F_Del.png

图6.信息删除流程

F_Vinf.png

图7.详细信息显示流程

FCorE.PNG

图8.信息创建或编辑流程

F_search.png

图8.信息查询流程

下面以创建学生信息为例展示操作流程

首先创建学生信息

XS1.PNG
XS2.png

当存在新的学生信息时,则其他部分实体信息可以与其关联,图为在用户信息部分创建该学生具体信息并与其关联

XS3.png

当学生信息被其他实体所关联时,该学生信息不能删除

XS4.PNG

只有在删除其他所有关联信息后,该学生信息才能够被删除

XS5.PNG
XS6.PNG

部分前端报告2

前端部分2

用户登录系统

liucheng.png

图1.用户登录系统

代码文件结构,位于src/main/webapp中

app

account //与账号相关

activate //注册账号激活
password //密码管理,登录后修改密码
password-reset //密码重设,用于忘记密码时修改密码

finish
init

register //注册新账号
settings //修改用户信息

core

auth //与认证相关的函数
icons
language
login //与登录相关的函数
user //与用户管理相关的函数和模型

shared

alert //alert设置
login //登录模块界面设置
user //用户model
... //各类实体的model设置等杂类文件

activate注册账号激活模块

激活成功会提醒激活成功的信息,并给出登录的接口
激活失败会提醒账号不能被激活,要求用户进行新账号注册
运用Angular作为前端开发框架

<div class="alert alert-success" *ngIf="success">     
...
</div>
<div class="alert alert-danger" *ngIf="error" 
jhiTranslate="activate.messages.error">
...
</div>

在activate.component.ts中定义了success,error参数
在初始化ngOnInit()时调用activate.service.ts中的activateService.get()函数来设置success,error的值来判定用户是否激活成功,以此来在网页avtivate.component.html显示相应的激活信息

password密码管理模块

用户登录后可以修改密码
passwordreset.png

图2.修改密码页面

password-reset密码重设模块

用户忘记密码可以在登录页面点击忘记密码来重新设置密码
register.png

图4.忘记密码页面

register注册新账号模块

输入用户名,邮箱,密码,确认密码,注册后系统会向所写邮箱发邮件,通过邮件激活账号后才能登录
register.component.ts中会检查用户名是否存在,邮箱是否已被注册,两次密码是否匹配,当一切正确后,会调用register.service.ts中以下函数,在后端数据库里保存用户信息,发邮件等用户激活账号。

this.registerService.save(
{ login, email, password, langKey: this.languageService.getCurrentLanguage() }
).subscribe(() => (this.success = true),response => this.processError(response));
  save(account: IUser): Observable<{}> {
    return this.http.post(SERVER_API_URL + 'api/register', account);
  }

register.png

图4.注册页面

settings修改信息模块

用户登录后可以修改自己的信息
settings.png

图5.修改信息页面

管理系统

代码文件结构,位于src/main/webapp中

app

admin //管理页面

audits //查看系统最近登录情况
configuration
doc
health
logs
metrics
user-management//用户管理

当用admin账号登录后可以管理用户信息,比普通用户多了管理权限
用户管理权限:

  • 增加用户
  • 删除用户
  • 修改用户消息
  • 激活用户账号

settings.png

图6.用户管理页面

后端部分报告

后端

概要

  • 以Java为后端开发语言,以MySQL为数据库管理系统
  • 以Spring Boot作为后端的开发框架
  • 以JHipster开发平台来开发生成和部署Spring Boot + Angular的Web应用
  • 使用Java普通对象(POJO)与数据库表建立映射关系。

实体配置

1

Campus

image

@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

@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

@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

@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

@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

@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

@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

@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

@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

@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

@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

@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;

永久化

  • 创建实体类的Respository(文件目录在src\main\java\com\mycompany\myapp\repository)
    image

  • 使用注解*@repository*将各接口定义为资源库,为其他程序提供存取数据库功能
    image

创建业务服务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

@RestController
@RequestMapping("/api")
@Transactional
···

一些测试中遇到的可优化项或问题

通用

删除某项后,ID不自动变化,例如删除3,4,5,6中的4,会变成3,5,6,且新添加从7开始

下拉框预览能否显示内容而不是ID,不然不够明确

学生

新建学生,专业不能下拉框选择只能填写

选课记录

bad request 不能创建

班级

新建班级班主任不能填写

教师

新建教师不能填写名字

课程

显示老师能否显示名字而不是ID

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.