Maven + MyBatis + JavaFX——班级通讯录系统

闲来无事,将之前没写完的一篇文章重新写一下。本文是对基于Maven + MyBatis + JavaFX 编写的一个班级通讯录系统的介绍。其主要界面如图所示。
项目主要界面

一、开发环境

名称开发环境
编辑器IDEA2021.1
界面设计工具JavaFx SenceBuilder 2.0
JDK版本1.8.0_251
数据库MySQL 8.0.23
mysql-connector-java8.0.23
mybatis3.5.7
lombok1.18.22

二、UI 设计

我使用JavaFx SenceBuilder 2.0来设计项目界面。
创建好 .fxml 文件后,使用ScenceBuilder打开就可以根据自己的需求设计界面。

2.1 主界面设计

主界面设计如图所示。主界面包括 多个 Container,以及各种视图,包括Button、Label、TextField、TableView、TableColumn等。本节介绍几个主要小视图的使用。
学习 JavaFX 可以去 JavaFX 中文文档学习
在这里插入图片描述

2.1.1 Button

JavaFX API中的Button类用来处理当用户点击一个按钮时执行一个动作(Action)。Button类继承自Labeled类,它可以显示文本,图像,或两者兼而有之。

可以在右边设计其 fx:id ,如我设置为check。同时也可以使用 On Action 来设置其行为,其中是其行为的方法名。
在这里插入图片描述
使用 fx:id 在 Java 中的响应如下:

check.setOnAction(e -> {
    // 执行体
});

2.1.2 TextField

TextField 类实现了一个接收和显示文本输入的UI组件。它提供了从用户接收文本输入的功能。这个类和另一个文本输入组件PasswordField一样,都继承自 TextInput 类。TextInput 类是 JavaFX API中所有文本组件的超类。

可以通过 Prompt Text 设置灰色的提示文字,通过 Editable 可以设置是否可以编辑。
在这里插入图片描述
同样地,可以通过 fx:id 来对其进行操作,若设置其 fx:id 为 checkID
其获取文本的代码如下:

checkID.getText()

其设置文本的代码如下:

checkID.setText()

2.1.3 TableView

TableView 是一个表格视图,它可以包括多列 TableColumn,即多列表格。
在这里插入图片描述
它是一个相对比较复杂点的视图,具体的设置见项目代码。其数据关联设置如下,其中的 “id”、“name”等是Student类的属性,其逻辑是获取一个学生List数据 students,并通过各个属性关联到相应列。

if (students != null) {
	list.addAll(students);
	
	idCol.setCellValueFactory(
	        new PropertyValueFactory<>("id")
	);
	nameCol.setCellValueFactory(
	        new PropertyValueFactory<>("name")
	);
	genderCol.setCellValueFactory(
	        new PropertyValueFactory<>("sex")
	);
	classCol.setCellValueFactory(
	        new PropertyValueFactory<>("classNum")
	);
	phoneCol.setCellValueFactory(
	        new PropertyValueFactory<>("phone")
	);
	mailCol.setCellValueFactory(
	        new PropertyValueFactory<>("mail")
	);
	addressCol.setCellValueFactory(
	        new PropertyValueFactory<>("address")
	);
	deleteCol.setCellValueFactory(
	        new PropertyValueFactory<>("deleteButton")
	);
	updateCol.setCellValueFactory(
	        new PropertyValueFactory<>("editButton")
	);
	
	tableView.setItems(list);
}

每一行的删除和修改按钮是自己定义在 Student中的,每一个student 对象都带有这两个按钮。

2.2 添加界面

添加界面是添加学生的地方,可以输入学生各种信息。其具体布局如是:
在这里插入图片描述

2.2.1 ChoiceBox

这里新增加了一个视图,用于选择性别。其选项的添加无法在 ScenceBuilder中完成。
可以参考:1、fxml中设置添加链接描述 2、Java中设置
,其代码如是,我使用自己定义的枚举类,同时设置TableView类型为String

addGender.getItems().addAll(GenderType.getGenders());
// GenderType 是枚举类
// GenderType.getGenders() 返回 ArrayList<String>

在这里插入图片描述

2.3 修改界面

修改界面和添加界面差不多,其如图所示:
在这里插入图片描述

三、数据库设计

由于功能简单,只设计了一个 student 表,其包括 id、name、gender、classNum、phone、mail和address这七个字段,id是主键,设置了自增长。

字段类型说明
idint学生ID自增
namevarchar姓名
gendertinyint性别:0男生,1女生,2其他; [0,128)
classNumtinyint班级,[1, 128)
phonevarchar电话号码
mailvarchar邮箱
addressvarchar家庭住址

3.1 MyBatis

使用 MyBatis 来连接 MySQL数据库,相应的maven 依赖如下:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.23</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.5.7</version>
</dependency>

同时需要编写 MyBatis 配置文件,我在 resources 里添加了 MyBatis-Config.xml ,其内容如下,需要结合自己的数据库用户名和链接修改。

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <typeAliases>
        <typeAlias alias="Student" type="com.yfengl.addressBook.entity.Student"/>
    </typeAliases>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                <property name="url"
                          value="jdbc:mysql://localhost:3306/address_book?serverTimezone=UTC"/>
                <!-- 配置数据库用户名和密码 -->
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
                <!-- 配置数据库用户名和密码 -->
            </dataSource>
        </environment>
    </environments>
    <!-- 配置mapper文件位置 -->
    <mappers>
        <mapper resource="mappers/StudentDao.xml"/>
    </mappers>
    <!-- 配置mapper文件位置 -->
</configuration>

3.1.1 MyBatis Generate 插件

使用idea 的插件可以自动生成 mapper文件和实体类,省去了繁杂的SQL的编写。
在这里插入图片描述
在这里插入图片描述

3.1.2 MyBatisUtils

MyBatisUtils 是一个 MyBatis 连接的工具类,可以省去一些反复的代码,其如下:

public class MyBatisUtils {

    private static SqlSessionFactory sessionFactory = null;
    /*
     * 创建本地线程变量,为每一个线程独立管理一个session对象 每一个线程只有且仅有单独且唯一的一个session对象
     * 加上线程变量对session进行管理,可以保证线程安全,避免多实例同时调用同一个session对象
     * 每一个线程都会new一个线程变量,从而分配到自己的session对象
     */
    private static ThreadLocal<SqlSession> threadlocal = new ThreadLocal<SqlSession>();

    // 创建sessionFactory对象,因为整个应用程序只需要一个实例对象,故用静态代码块
    static {
        try {
            Reader reader = Resources.getResourceAsReader("MyBatis-Config.xml");
            sessionFactory = new SqlSessionFactoryBuilder().build(reader);
            reader.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 返回sessionFactory对象 工厂对象
     *
     * @return sessionFactory
     */
    public static SqlSessionFactory getSessionFactory() {
        return sessionFactory;
    }

    /**
     * 新建session会话,并把session放在线程变量中
     */
    private static void newSession() {
        // 打开一个session会话
        SqlSession session = sessionFactory.openSession();
        // 将session会话保存在本线程变量中
        threadlocal.set(session);
    }

    /**
     * 返回session对象
     * @return session
     */
    public static SqlSession getSession(){
        //优先从线程变量中取session对象
        SqlSession session = threadlocal.get();
        //如果线程变量中的session为null,
        if(session==null){
            //新建session会话,并把session放在线程变量中
            newSession();
            //再次从线程变量中取session对象
            session = threadlocal.get();
        }
        return session;
    }

    /**
     * 关闭session对象,并从线程变量中删除
     */
    public static void closeSession(){
        //读取出线程变量中session对象
        SqlSession session = threadlocal.get();
        //如果session对象不为空,关闭sessoin对象,并清空线程变量
        if(session!=null){
            session.close();
            threadlocal.set(null);
        }
    }
}

每次连接后需要 closeSession,放在 finally 代码块每次都会执行,参考如下:

sqlSession = MyBatisUtils.getSession();
studentDao = sqlSession.getMapper(StudentDao.class);
Student student = null;

try {
    student = studentDao.selectByPrimaryKey(id);
    sqlSession.commit();
} catch (Exception e) {
    sqlSession.rollback();
} finally {
    MyBatisUtils.closeSession();
}

四、代码设计

4.1 实体类 Student

Student类除了数据库相应的字段,还有几个其他字段,@Data 是 Lombok 的注解,可以自动生成一些getter和setter或构造函数。
其中sex是为了从数据库中存储的数字转化为字符串,它与gender都是指性别。

@Data
public class Student implements Serializable {
    private static final long serialVersionUID = 1L;

    /**
     * 学生id或编号,自增长
     */
    private Integer id;

    /**
     * 姓名
     */
    private String name;

    /**
     * 性别:0男生,1女生,2其他
     * ;<128;>=0
     */
    private Integer gender;

    /**
     * 性别:男生,女生,其他
     * 用于从数字gender获取汉字性别
     */
    private String sex;

    /**
     * 班级,数字
     * <128;>0
     */
    private Integer classNum;

    /**
     * 手机号,11位
     */
    private String phone;

    /**
     * 邮箱
     */
    private String mail;

    /**
     * 家庭住址
     */
    private String address;

    private SimpleObjectProperty<DeleteButton> deleteButton;

    private SimpleObjectProperty<EditButton> editButton;

    private final AddressList addressList = new AddressList();

    public String getSex() {
        return GenderType.valueOf(gender).getGender();
    }

    public void setSex(String sex) {
        this.sex = GenderType.valueOf(gender).getGender();
    }
}

4.2 性别 GenderType

枚举类,定义性别

public enum GenderType {
    MAN(0, "男"),
    WOMAN(1, "女"),
    OTHER(2, "其他"),
    ;
    private final Integer key;
    private final String gender;

    GenderType(Integer key, String gender) {
        this.key = key;
        this.gender = gender;
    }

    public Integer getKey() {
        return this.key;
    }

    public String getGender() {
        return this.gender;
    }

    public static ArrayList<String> getGenders(){
        ArrayList<String> genders = new ArrayList<>();
        GenderType[] genderTypes = GenderType.values();
        int i = 0;
        for (GenderType genderType : genderTypes) {
            genders.add(genderType.getGender());
        }
        return genders;
    }

    public static GenderType valueOf(Integer key) {
        GenderType[] genderTypes = values();
        for (GenderType genderType : genderTypes) {
            if (genderType.key == key) return genderType;
        }
        return null;
    }

    public static GenderType getGenderTypeByGender(String gender) {
        GenderType[] genderTypes = values();
        for (GenderType genderType : genderTypes) {
            if (genderType.gender == gender) return genderType;
        }
        return null;
    }

}

五、项目源代码

项目Github地址:https://github.com/yfengl/AddressBook

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值