会员管理系统
1.1需求
本案例实现一个会员管理系统,对会员信息有基本的管理功能,增删改查即可,主要是为了熟悉mybatis框架使用流程。
1.2 具体功能
根据id查询会员信息
新增会员信息。
根据id修改会员信息
根据id删除会员信息
1.3 工具准备
我用的是IDEA2021版,JDK使用的是17.0.2,mysql使用8.0版本,提前安装好。不一样的话只要不是太老应该没问题。
1.4 具体步骤
1.4.1 创建数据库与表
-- 创建数据库
create database db_vip
-- 创建会员表
USE javaee_learn;
CREATE TABLE `t_vip` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '会员编号',
`name` varchar(255) NOT NULL COMMENT '会员名称',
`age` int(11) NOT NULL COMMENT '会员年龄',
`rank` varchar(255) NOT NULL COMMENT '会员等级',
`gmt_create` datetime NOT NULL COMMENT '会员注册时间',
`gmt_update` datetime NOT NULL COMMENT '最新会员信息修改时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='会员表';
-- 插入几个备用数据
INSERT INTO `t_vip` (`id`,`name`,`age`,`rank`) VALUES
(1, '张三', 20, '普通'),
(2, '李四', 18, '青铜'),
(3, '王五', 35, '钻石');
执行完后得到下表:
1.4.2 创建项目(IDEA)
打开IDEA->文件->新建->选中maven->下一步,项目路径与名称自定。
这个模块做一个管理模块用的“壳子”,把src目录删掉。
接下来创建会员管理模块,注意父模块选刚刚创建的那个:
完成创建。
1.4.3 依赖下载
打开最外面的pom,我的是javaEE_learn模块的pom文件。
在properties标签中加入:
<!--依赖版本管理-->
<lombok.version>1.18.20</lombok.version>
<mysql.version>8.0.26</mysql.version>
<mybatis.version>3.5.7</mybatis.version>
<junit.version>5.9.2</junit.version>
在该文件最下方插入:
<dependencyManagement>
<dependencies>
<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<scope>provided</scope>
<!-- provided 表示该依赖在编译时需要,但在运行时不需要,
因为这些类将由容器或其他依赖项提供。 -->
</dependency>
<!-- MySQL 驱动依赖 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<!-- MyBatis 依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
dependencyManagement标签的作用是管理依赖。
下一步打开experience_01_vip模块的pom文件,在properties标签后加入:
<dependencies>
<!--mysql-driver-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- MyBatis 依赖 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
</dependency>
<!-- JUnit 5 -->
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope>
</dependency>
<!-- Lombok 依赖 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<scope>provided</scope>
<!-- provided 表示该依赖在编译时需要,但在运行时不需要,
因为这些类将由容器或其他依赖项提供。 -->
</dependency>
</dependencies>
这几个包的作用是:
mysql-driver:数据库驱动,用以连接数据库
MyBatis:Mybatis框架
JUnit 5:测试使用
Lombok:简化pojo类,自动补充get、set方法
点击右上角的这个,下载依赖:
或者打开侧边maven选项卡,找到刷新:
至此,依赖下载完成。
1.4.4 配置Mybatis
在resources目录下创建下图两个文件:
jdbc.properties作用是配置数据库信息,mybatis-config.xml是mybatis的配置文件,用以配置mybatis。 注意把数据库什么的改成自己的。
jdbc.properties
jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javaee_learn?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.username=root
jdbc.password=
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>
<!-- 1、属性:例如jdbc.properties -->
<properties resource="jdbc.properties"/>
<!-- 2、设置:定义全局性设置,例如开启二级缓存 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 3、类型名称:为一些类定义别名 -->
<!--<typeAliases>-->
<!--</typeAliases>-->
<!-- 4、类型处理器:定义Java类型与数据库中的数据类型之间的转换关系 -->
<typeHandlers/>
<!-- 7、环境:配置mybatis的环境 -->
<environments default="development">
<!-- 环境变量:支持多套环境变量,例如开发环境、生产环境 -->
<environment id="development">
<!-- 事务管理器:默认JDBC -->
<transactionManager type="JDBC" />
<!-- 数据源:使用连接池,并加载mysql驱动连接数据库 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- 9、映射器:指定映射文件或者映射类 -->
<!--<mappers>-->
<!--</mappers>-->
</configuration>
1.4.5 编写程序
①创建pojo类
在java中创建如下目录:
先建实体,在pojo包中创建VipPojo类:
package com.example.pojo;
import lombok.Data;
/**
* @author blackjack
*/
@Data
public class VipPojo {
Integer id;
String name;
Integer age;
String rank;
String gmtCreate;
String gmtUpdate;
}
@Data注释是Lombok的,有了这个注释不需要写get,set等方法,它会帮我们写好。
②创建mapper映射
在mapper包创建:
VipMapper是一个Interface接口,VipMapper.xml是数据库映射文件
这个VipMapper.xml正常来说是写在resources文件夹的,图省事我直接写在这里了。注意在pom里加上这个build,我们只有两个pom,子模块的pom会继承父模块的,加在哪个都可以。
<!--maven默认不会将xml文件打包,要加上这个:-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*</include>
</includes>
</resource>
</resources>
</build>
pom文件更新了注意刷新。
VipMapper
package com.example.mapper;
/**
* t_vip表的映射接口
* @author blackjack
*/
public interface VipMapper {
}
VipMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.VipMapper">
<!--resultMap作用是将从数据库查到的记录一个个对应VipPojo对象的属性,给其赋值-->
<resultMap id="VipResultMap" type="com.example.pojo.VipPojo">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="rank" property="rank"/>
<result column="gmt_create" property="gmtCreate"/>
<result column="gmt_update" property="gmtUpdate"/>
</resultMap>
</mapper>
column是表的字段名,property是类的属性名
随后在mybatis-config.xml中加入:
<!-- 9、映射器:指定映射文件或者映射类 -->
<mappers>
<mapper class="com.example.mapper.VipMapper"/>
</mappers>
③创建MybatisUtil
MybatisUtil便于得到SqlSession。
在utils包创建MybatisUtil类:
package com.example.utils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
/**
* MyBatis 工具类,用于获取 SqlSession 和 Mapper 对象
*
* @author blackjack
*/
public class MyBatisUtil {
private static SqlSessionFactory sqlSessionFactory;
/*
静态初始化块,在类加载时执行,用于初始化 SqlSessionFactory 对象
*/
static {
try {
// 加载 MyBatis 配置文件
String resource = "mybatis-config.xml";
InputStream inputStream = MyBatisUtil.class.getClassLoader().getResourceAsStream(resource);
// 创建 SqlSessionFactory 对象
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 获取 SqlSession 对象
*
* @return SqlSession 对象
*/
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
}
④实现功能
1.在VipMapper新增各映射
package com.example.mapper;
import com.example.pojo.VipPojo;
import java.util.List;
/**
* t_vip表的映射接口
* @author blackjack
*/
public interface VipMapper {
/**
* 根据id查询会员信息
* @param id id
* @return 员工信息
*/
VipPojo selectById(Integer id);
/**
* 新增一条会员信息
* @param vipPojo 要新增的会员
* @return 受影响的行数
*/
Integer insertVip(VipPojo vipPojo);
/**
* 修改一条会员信息
* @param vipPojo 更改后的会员信息
* @return 受影响的行数
*/
Integer updateVip(VipPojo vipPojo);
/**
* 删除一条会员信息
* @param id 要删除的会员的id
* @return 受影响的行数
*/
Integer deleteVipById(Integer id);
/**
* 查询所有会员信息
* @return 会员信息列表
*/
List<VipPojo> selectAllVips();
}
点这个,会跳到VipMapper.xml并创建好标签,在其标签内写操作数据库的sql语句即可。
写好sql的VipMapper.xml应是如此:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.mapper.VipMapper">
<!--resultMap作用是将从数据库查到的记录一个个对应VipPojo对象的属性,给其赋值-->
<resultMap id="VipResultMap" type="com.example.pojo.VipPojo">
<id column="id" property="id"/>
<result column="name" property="name"/>
<result column="age" property="age"/>
<result column="rank" property="rank"/>
<result column="gmt_create" property="gmtCreate"/>
<result column="gmt_update" property="gmtUpdate"/>
</resultMap>
<insert id="insertVip">
INSERT INTO t_vip (`name`, `age`, `rank`) VALUES (#{name}, #{age}, #{rank});
</insert>
<update id="updateVip">
UPDATE t_vip SET name=#{name}, age=#{age}, `rank`=#{rank} WHERE id=#{id};
</update>
<delete id="deleteVipById">
DELETE FROM t_vip WHERE id = #{id};
</delete>
<select id="selectById" resultMap="VipResultMap">
SELECT * FROM t_vip WHERE id = #{id};
</select>
<!--mybatis会自动判断该返回的是单条记录还是List集合-->
<select id="selectAllVips" resultMap="VipResultMap">
SELECT * FROM t_vip;
</select>
</mapper>
t_vip可能会报红,查看最后的“可能出现的问题”解决
2. 写service
在service包创建:
VipService
package com.example.service;
import com.example.pojo.VipPojo;
import java.util.List;
/**
* VipService接口,定义了关于VIP会员的业务逻辑处理方法
* @author blackjack
*/
public interface VipService {
/**
* 根据ID获取VIP会员信息
*
* @param id VIP会员ID
* @return 对应的VIP会员实体对象
*/
VipPojo getVipById(int id);
/**
* 获取所有VIP会员信息列表
*
* @return VIP会员信息列表
*/
List<VipPojo> getAllVips();
/**
* 添加新的VIP会员
*
* @param vip 新的VIP会员实体对象
* @return 受影响的行数,0表示插入失败
*/
int addVip(VipPojo vip);
/**
* 更新VIP会员信息
*
* @param vip 要更新的VIP会员实体对象
* @return 受影响的行数,0表示更新失败
*/
int updateVip(VipPojo vip);
/**
* 根据ID删除VIP会员信息
*
* @param id VIP会员ID
* @return 受影响的行数,0表示删除失败
*/
int deleteVipById(int id);
}
VipServiceImpl
package com.example.service.impl;
import com.example.mapper.VipMapper;
import com.example.pojo.VipPojo;
import com.example.service.VipService;
import com.example.utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import java.util.List;
/**
* VipService接口的实现类,实现了关于VIP会员的业务逻辑处理方法
* @author blackjack
*/
public class VipServiceImpl implements VipService {
/**
* 获取MyBatis的SqlSession对象
* @return MyBatis的SqlSession对象
*/
private SqlSession getSession() {
return MyBatisUtil.getSqlSession();
}
/**
* 获取VipMapper对象
* @return VipMapper对象
*/
private VipMapper getMapper(SqlSession sqlSession) {
return sqlSession.getMapper(VipMapper.class);
}
@Override
public VipPojo getVipById(int id) {
try (SqlSession session = getSession()) {
return getMapper(session).selectById(id);
}
}
@Override
public List<VipPojo> getAllVips() {
try (SqlSession session = getSession()) {
return getMapper(session).selectAllVips();
}
}
@Override
public int addVip(VipPojo vip) {
try (SqlSession session = getSession()) {
int result = getMapper(session).insertVip(vip);
session.commit();
return result;
}
}
@Override
public int updateVip(VipPojo vip) {
try (SqlSession session = getSession()) {
int result = getMapper(session).updateVip(vip);
session.commit();
return result;
}
}
@Override
public int deleteVipById(int id) {
try (SqlSession session = getSession()) {
int result = getMapper(session).deleteVipById(id);
session.commit();
return result;
}
}
}
⑤编写主程序
com.example包下创建:
package com.example;
import com.example.pojo.VipPojo;
import com.example.service.impl.VipServiceImpl;
import com.mysql.cj.util.StringUtils;
import java.util.List;
import java.util.Scanner;
/**
* @author blackjack
*/
public class VipManagementApplication {
public static void main(String[] args) {
while (true) {
System.out.println(" 会员管理系统");
System.out.println("*********************************************");
System.out.println("1.) Add VIP 2.) Remove VIP");
System.out.println("3.) View VIP 4.) update VIP");
System.out.println("5.) View All VIPS 6.) Exit");
System.out.println("**********************************************");
System.out.println("请选择:");
int choice;
Scanner scanner = new Scanner(System.in);
try {
choice = scanner.nextInt();
if (choice < 1 || choice > 6) {
throw new Exception();
}
} catch (Exception e) {
System.out.println("输入有误!");
continue;
}
switch (choice) {
case 1:
addVip();
break;
case 2:
removeVip();
break;
case 3:
viewVip();
break;
case 4:
updateVip();
break;
case 5:
viewAllVips();
break;
case 6:
return;
default:
}
System.out.println("\n输入任何非空格字符回到菜单。。。");
scanner.next();
}
}
static void addVip() {
VipPojo vip = new VipPojo();
Scanner scanner = new Scanner(System.in);
System.out.println("输入姓名:");
vip.setName(scanner.next());
System.out.println("输入年龄:");
vip.setAge(scanner.nextInt());
System.out.println("输入等级:");
vip.setRank(scanner.next());
int result = new VipServiceImpl().addVip(vip);
if (result == 1) {
System.out.println("添加成功!");
} else {
System.out.println("添加失败!");
}
}
static void viewVip() {
Scanner scanner = new Scanner(System.in);
System.out.println("输入id查询会员:");
VipPojo vip = new VipServiceImpl().getVipById(scanner.nextInt());
if (vip!= null) {
System.out.println(vip);
}else {
System.out.println("查无此人哦~");
}
}
static void removeVip() {
Scanner scanner = new Scanner(System.in);
System.out.println("输入id删除会员:");
int id = scanner.nextInt();
System.out.println("确定删除吗?yes/no");
if ("yes".equals(scanner.next())) {
int r = new VipServiceImpl().deleteVipById(id);
if (r > 0) {
System.out.println("删除成功!");
} else {
System.out.println("删除失败!");
}
} else {
System.out.println("已取消删除");
}
}
static void updateVip() {
Scanner scanner = new Scanner(System.in);
System.out.println("输入id修改会员:");
VipServiceImpl vipService = new VipServiceImpl();
VipPojo newVip = vipService.getVipById(scanner.nextInt());
if (newVip == null) {
System.out.println("查无此人哦~");
return;
}
System.out.println("你要修改的会员是:" + newVip.getName());
System.out.println("输入新姓名(空白默认不修改)");
String newName = new Scanner(System.in).nextLine();
if (!StringUtils.isNullOrEmpty(newName)) {
newVip.setName(newName);
}
System.out.println("输入新年龄(空白默认不修改)");
//新建scanner,清空缓冲区
String newAge = new Scanner(System.in).nextLine();
if (!StringUtils.isNullOrEmpty(newAge)) {
try {
newVip.setAge(Integer.parseInt(newAge));
} catch (NumberFormatException e) {
System.out.println("输入有误!");
return;
}
}
System.out.println("输入新等级(空白默认不修改)");
String newRank = new Scanner(System.in).nextLine();
if (!StringUtils.isNullOrEmpty(newRank)) {
newVip.setRank(newRank);
}
int result = vipService.updateVip(newVip);
if (result > 0) {
System.out.println("修改成功!");
} else {
System.out.println("修改失败!");
}
}
static void viewAllVips() {
List<VipPojo> allVips = new VipServiceImpl().getAllVips();
if (allVips.size() == 0) {
System.out.println("暂无会员!");
return;
}
for (int i = 0; i < allVips.size(); i++) {
System.out.println(allVips.get(i));
}
}
}
如此,一个简简简单的小练习就算完成了,启动就可以了。
此练习主要是本人理顺mybatis的工作流程而作,功能很不完善,很多的逻辑问题也没处理,比如年龄可以负数可以几千岁等等。懒。
呀,原来还多了两个字段,gmtCreate和gmtUpdate,记录创建时间和更新时间的,不响玩辣~。
1.5最终效果
菜单:
添加
删除
查看一只
修改
查看所有
退出
1.6 可能出现的问题
①sql语句表名报红
idea问题,识别不出数据源,不管他也可以,最后不会有问题。
可以如此解决:
点开数据库选项卡:
添加数据源:
再:
就OK了。