1、导入坐标
坐标 | 作用 |
---|---|
pagehelper-spring-boot-starter | mybatis分页插件 |
spring-boot-starter-thymeleaf | JSP模板引擎 |
mybatis-spring-boot-starter | mybatis |
spring-boot-starter-web | web |
spring-boot-starter-test | test |
lombok | 不需要再写getter、setter或equals方法,只要有一个注解 |
mybatis-plus-boot-starter | mybatis plus |
druid-spring-boot-starter | druid连接数据库 |
hutool-all | hutool工具类 |
bootstrap | 前端 |
jquery | 前端 |
mysql-connector-java | mysql |
2、配置文件application.yml
# 应用服务 WEB 访问端口
server:
port: 8080
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/minzu?useUnicode=true&characterEncoding=utf8
username: root
password: root
type: com.alibaba.druid.pool.DruidDataSource
druid:
min-idle: 5
max-active: 10
max-wait: 3000
thymeleaf:
prefix: classpath:/templates/water/
suffix: .html
mybatis-plus:
configuration:
map-underscore-to-camel-case: true
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
global-config:
db-config:
id-type: auto
pagehelper:
helper-dialect: mysql
3、登录功能
需要tb_account表
在pojo实体包下创建Account实体类
使用@TableName("tb_account")
注解,用于标识实体类对应的数据库表名
在service层提供登录方法,分为接口和接口实现
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
//自动注入AccountMapper,AccountMapper继承了BaseMapper<Account>,是mybatisplus接口,有基本的CURD
private AccountMapper accountMapper;
@Override
public boolean login(String user, String password) {
QueryWrapper<Account> qw = new QueryWrapper<>();
qw.eq("user_name",user);//精确查找
Account account = accountMapper.selectOne(qw);//从数据库中选择上面查找到的对象
if(account == null){
return false;
}
String userPwd = account.getUserPwd();
//String s = DigestUtil.md5Hex(password);
//System.out.println(s);
if(Objects.equals(userPwd,password)){//比较密码
return true;
}else{
return false;
}
}
}
登录方法的controller
@Controller
public class AccountController {
@Autowired
private AccountService accountService;
@PostMapping("/login")
public String login(String userName, String userPwd, Model model, HttpSession session){
boolean login = accountService.login(userName,userPwd);//接收前端参数userName和userPwd
if(login){
session.setAttribute("currentUser",userName);
return "waterMainMenu";
//用的thymeleaf,配置文件中已经写好路径与.html,直接跳转
}else{
model.addAttribute("msg","用户名或者密码错误");
return "index";
}
}
}
4、主页展示
需要tb_history表
@RestController
@RequestMapping("main")
public class MainMenuController {
@Autowired
private HistoryService historyService;
@Autowired
private WorkerService workerService;
@RequestMapping("mainMenu")
public List<MainMenu> list(){
List<MainMenu> list = new ArrayList<>();
Map<Integer,Integer> map = new HashMap<>();
historyService.queryHistory().forEach(h -> {//遍历数据库,将对应workerId键放入map中,值为sendWaterCount
map.put(h.getWorkerId(),map.getOrDefault(h.getWorkerId(),0)+h.getSendWaterCount());
});
workerService.queryWorker().forEach(w ->{//遍历数据库中的所有数据,这些数据最后是需要展示的
//MainMenu中只有WorkerName和SendWaterCount属性
MainMenu mainMenu = new MainMenu();
//设置WorkerName
mainMenu.setWorkerName(w.getWorkerName());
//设置SendWaterCount
mainMenu.setSendWaterCount(map.get(w.getWid())==null?0:map.get(w.getWid()));
list.add((mainMenu));
});
//将所有拿到的数据排序,只取前12个
Collections.sort(list,(o1,o2)->{
if(o1.getSendWaterCount()>o2.getSendWaterCount()){
return -1;
}else if(o1.getSendWaterCount()<o2.getSendWaterCount()){
return 1;
}else{
return 0;
}
});
if(list.size()<12){
return list;
}
List<MainMenu> arrList = new ArrayList<>();
for(int i=0;i<12;i++){
arrList.add(list.get(i));
}
return arrList;
}
}
5、客户管理功能模块
需要tb_customer表
用的是PageInfo<>(listCust)
前端展示页面
业务层
@Service
public class CustomerServiceImpl implements CustomerService {
@Autowired
//自动注入CustmoerMapper,用于连接操作数据库
private CustomerMapper customerMapper;
@Override
//查询展示所有
//返回值是一个PageInfo对象,里面放的是从数据库查询到的每个Customer对象
public PageInfo<Customer> list(Customer customer) {
QueryWrapper<Customer> qw = new QueryWrapper<>();
String custName = customer.getCustName();
String custMobile = customer.getCustMobile();
if(!StringUtils.isNullOrEmpty(custName)){
//custName模糊查询
qw.like("cust_name",custName);
}
if(!StringUtils.isNullOrEmpty(custMobile)){
//custMobile精确查询
qw.eq("cust_mobile",custMobile);
}
//selectList查询多条数据,封装成集合返回
List<Customer> listCust = customerMapper.selectList(qw);
return new PageInfo<>(listCust);
}
@Override
//添加
public int addCust(Customer customer) {
//调用insert方法
return customerMapper.insert(customer);
}
//删除
//前端留的接口数据就是cid
@Override
public int deleteCust(int id) {
QueryWrapper<Customer> qw = new QueryWrapper<>();
qw.eq("cid",id);//精确比较cid,拿到对象
int delete = customerMapper.delete(qw);//用Mapper中的delete方法从数据中删除上面拿到的qw
return delete;
}
}
Controller
@Controller
@RequestMapping("cust")
//前端留的接口就是cust
public class CustomerController {
@Autowired
private CustomerService customerService;
//Customer页面显示
@RequestMapping("listCust")
public String list(@RequestParam(required = false,defaultValue = "1",value = "pageNum") Integer pageNum,
@RequestParam(required = false,defaultValue = "10",value = "pageSize") Integer pageSize,
Model model, Customer customer){
if(pageNum<=0 || pageNum.equals("")||pageNum==null){
pageNum = 1;
}
if(pageSize<=0 || pageSize.equals("")||pageSize==null){
pageNum = 10;
}
PageHelper.startPage(pageNum,pageSize);
PageInfo<Customer> pageInfo = customerService.list(customer);
model.addAttribute("pageInfo",pageInfo);//前端留的pageInfo
return "customerList";
}
//跳转到添加数据页面,有一个单独的custSave.html页面
@RequestMapping("preSaveCust")
public String preSave(){
return "custSave";
}
//真正的添加数据页面,保存数据
@RequestMapping("saveCust")
public String save(Customer customer){
int i = customerService.addCust(customer);
return "redirect:/cust/listCust";
}
//删除Customer数据
@RequestMapping("delCust/{cid}")
public String deleteCust(@PathVariable int cid){
int i = customerService.deleteCust(cid);
return "redirect:/cust/listCust";
}
}
6、送水工管理模块
需要tb_worker表
业务层
@Service
public class WorkerServiceImpl implements WorkerService {
@Autowired
private WorkerMapper workerMapper;
@Override
//查询所有
public List<Worker> queryWorker() {
return workerMapper.selectList(null);
}
@Override
//查询所有带分页
public PageInfo<Worker> list(Worker worker) {
String workName = worker.getWorkerName();
QueryWrapper<Worker> qw = new QueryWrapper<>();
if(!StringUtils.isNullOrEmpty(workName)){
qw.like("worker_name",workName);
}
List<Worker> workers = workerMapper.selectList(qw);
return new PageInfo<>(workers);
}
@Override
//添加
public int addWorker(Worker worker) {
return workerMapper.insert(worker);
}
@Override
public Worker getWorkerById(Integer id) {
QueryWrapper<Worker> qw = new QueryWrapper<>();
qw.eq("wid",id);
Worker worker = workerMapper.selectOne(qw);
return worker;
}
@Override
//更新
public int updateWorker(Worker worker) {
Integer wid = worker.getWid();
QueryWrapper<Worker> qw = new QueryWrapper<>();
qw.eq("wid",wid);
int update = workerMapper.update(worker, qw);
return update;
}
@Override
//更新薪资
public int updateSalary(Integer wid, String workerSalary) {
QueryWrapper<Worker> qw = new QueryWrapper<>();
qw.eq("wid",wid);
Worker worker = workerMapper.selectOne(qw);
worker.setWorkerSalary(workerSalary);
int update = workerMapper.update(worker, qw);
return update;
}
}
Controller
@Controller
@RequestMapping("worker")
public class WorkerController {
@Value("${location}")
private String location;
@Autowired
private WorkerService workerService;
@RequestMapping("workerList")
public String list(@RequestParam(required = false,defaultValue = "1",value = "pageNum") Integer pageNum,
@RequestParam(required = false,defaultValue = "10",value = "pageSize") Integer pageSize,
Model model, Worker worker){//Model用于存PageInfo
if (pageNum<=0||pageNum.equals("")||pageNum==null){
pageNum = 1;
}
if (pageSize<=0||pageSize.equals("")||pageSize==null){
pageSize = 10;
}
PageHelper.startPage(pageNum,pageSize);
PageInfo<Worker> list = workerService.list(worker);
model.addAttribute("pageInfo",list);
return "workerList";
}
@RequestMapping("preSaveWorker")
public String preAdd(){
return "workerSave";
}
@PostMapping("workerSave")
public String add(Worker worker, MultipartFile file){
transFile(worker,file);
workerService.addWorker(worker);
return "redirect:/worker/workerList";
}
private void transFile(Worker worker, MultipartFile file) {
String originalFileName = file.getOriginalFilename();
int index = originalFileName.lastIndexOf(".");
String suffix = originalFileName.substring(index);
String prefix = System.nanoTime()+"";
String path = prefix+suffix;
File file1 = new File(location);
if(!file1.exists()){
file1.mkdirs();
}
File file2 = new File(file1,path);
try {
file.transferTo(file2);
} catch (IOException e) {
e.printStackTrace();
}
worker.setWorkerImage(path);
}
@RequestMapping("preUpdateWorker/{id}")
public String preUpdate(@PathVariable Integer id,Model model){
Worker worker = workerService.getWorkerById(id);
model.addAttribute("worker",worker);
return "workerUpdate";
}
@RequestMapping("updateWorker")
public String update(Worker worker,MultipartFile file){
transFile(worker,file);
int i = workerService.updateWorker(worker);
return "redirect:/worker/workerList";
}
//ajax传参数放在Data里了,不用@PathVariable接收,也不用跳转
@PostMapping("addSalary")
@ResponseBody
public String addSalary(Integer wid,String workerSalary){
int i = workerService.updateSalary(wid, workerSalary);
if(i>0){
//返回值根据前端ajax(workerList.html中)写好的参数返回
return "OK";
}else{
return "error";
}
}
}
7、送水历史管理模块
需要tb_history表
需要用到一些mybatisPlus没有的方法,需要在mapper下写需要的方法,具体实现在resources/com/example/HistoryMapper.xml
@Repository
public interface HistoryMapper extends BaseMapper<History> {
List<History> listHistory(Map<String,Object> map);
//除了mybatisPlus自己的一些方法,如果有其他方法,需要自己在下面写
//相当于接口,具体实现在resources下的HistoryMapper.xml文件里,写SQL语句
//添加
int addHis(History history);
//批量删除
int deleteHis(List<Integer> ids);
//根据id获取history对象
History getHisById(Integer id);
//修改
int updateHis(History history);
}
HistoryMapper.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"><!--记住 我的电脑这里只能是http才能出来小鸟-->
<mapper namespace="com.example.mapper.HistoryMapper">
<resultMap id="historyMap" type="com.example.pojo.History">
<id column="hid" property="hid"/>
<result column="send_water_time" property="sendWaterTime"/>
<result column="send_water_count" property="sendWaterCount"/>
<association property="customer">
<id column="cid" property="cid"/>
<result column="cust_name" property="custName"/>
</association>
<association property="worker">
<id column="wid" property="wid"/>
<result column="worker_name" property="workerName"/>
</association>
</resultMap>
<select id="listHistory" resultType="com.example.pojo.History" resultMap="historyMap">
select h.hid, w.worker_name, c.cust_name, h.send_water_time, h.send_water_count
from tb_history h,tb_customer c,tb_worker w
<where>
AND h.cust_id=c.cid AND h.worker_id=w.wid
<if test="workerName != null and workerName!='' ">
and w.worker_name like concat('%',#{workerName},'%')
</if>
<if test="sendWaterTime != null and sendWaterTime !='' ">
and h.send_water_time like concat('%',#{sendWaterTime},'%')
</if>
</where>
</select>
<insert id="addHis">
insert into tb_history (cust_id,worker_id,send_water_time,send_water_count)
values (#{customer.cid},#{worker.wid},#{sendWaterTime},#{sendWaterCount})
</insert>
<delete id="deleteHis">
delete from tb_history
where hid in
<foreach collection="ids" item="hid" open="(" close=")" separator=",">
#{hid}
</foreach>
</delete>
<select id="getHisById" resultType="com.example.pojo.History" resultMap="historyMap">
select h.hid, w.worker_name, c.cust_name, h.send_water_time, h.send_water_count
from tb_history h,tb_customer c,tb_worker w where h.cust_id=c.cid and h.worker_id=w.wid and hid=#{id}
</select>
<update id="updateHis">
update tb_history set cust_id=#{customer.cid},worker_id=#{worker.wid},send_water_time=#{sendWaterTime},send_water_count=#{sendWaterCount}
where hid=#{hid}
</update>
</mapper>
然后在业务层完成业务,controller层完成,controller层有一个数据回显的功能模块
@RequestMapping("preSaveHis")
//添加功能需要数据回显,必须是已经存在的worker和customer
//数据回显是放在model中的
public String preAddHis(Model model){
List<Worker> workers = workerService.queryWorker();
List<Customer> customer = customerService.querycustomer();
//在historySave.html中有变量名,"custList"需要保持一致
model.addAttribute("custList",customer);
model.addAttribute("workerList",workers);
return "historySave";
}
8、计算薪资模块
在pojo创建Salary实体类
在mapper下创建SalaryMapper(用@Repository注解)
主要是sql语句
SalaryMapper.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"><!--记住 我的电脑这里只能是http才能出来小鸟-->
<mapper namespace="com.example.mapper.SalaryMapper">
<select id="list" resultType="com.example.pojo.Salary">
SELECT w.worker_name,w.worker_salary,w.worker_money,
IFNULL(SUM(h.send_water_count),0) as send_water_count,
IFNULL(SUM(w.worker_money*h.send_water_count)+w.worker_salary , w.worker_salary) as final_salary
FROM
tb_worker w LEFT JOIN tb_history h on w.wid=h.worker_id
<where>
<if test="startDate!=null and startDate!='' and endDate!=null and endDate != '' ">
and h.send_water_time between #{startDate} and #{endDate}
</if>
</where>
GROUP BY w.wid
ORDER BY final_salary DESC
</select>
<select id="listAll" resultType="com.example.pojo.Salary">
SELECT w.worker_name,w.worker_salary,w.worker_money,
IFNULL(SUM(h.send_water_count),0) as send_water_count,
IFNULL(SUM(w.worker_money*h.send_water_count)+w.worker_salary , w.worker_salary) as final_salary
FROM
tb_worker w LEFT JOIN tb_history h on w.wid=h.worker_id
GROUP BY w.wid
ORDER BY final_salary DESC
</select>
<select id="listNull" resultType="com.example.pojo.Salary">
SELECT w.worker_name,w.worker_salary,w.worker_money,
IFNULL(SUM(h.send_water_count),0) as send_water_count,
IFNULL(SUM(w.worker_money*h.send_water_count)+w.worker_salary , w.worker_salary) as final_salary
FROM
tb_worker w LEFT JOIN tb_history h on w.wid=h.worker_id
where h.worker_id is null
GROUP BY w.wid
ORDER BY final_salary DESC
</select>
</mapper>