多对多项目

整体项目框架

1.pojo包实体类

        1.角色类

package com.xu.pojo;

import lombok.Data;

/**
 * 实体角色类
 */
@Data
public class Role {
    private Integer rid;
    private String rname;
}

        2.用户类

package com.xu.pojo;

import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 用户实体类
 */
@Data
public class User {
    private Integer uid;
    private String username;
    private String password;
    private String realname;
    private Integer sex;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date birthday;
    private Integer status;//状态
    /**
     * 多对多集合
     */
    private List<Role> roles=new ArrayList<>(10);
    private String[] chk;//用于接收角色数组
}

2.mapper包方法与xml文件

        1.mapper接口

package com.xu.mapper;

import com.xu.pojo.Role;
import com.xu.pojo.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

/**
 * mapper接口
 */
public interface UserMapper {
    /**
     * 查询用户角色表
     * @return
     */
    @Select("select * from t_role")
    List<Role> roles();
    /**
     * 登录方法
     * @param username
     * @param password
     * @return
     */
    User login(@Param("username") String username, @Param("password") String password);

    /**
     * 查询所有用户信息方法
     * @param user
     * @return
     */
    List<User> findUsers(User user);

    /**
     * 添加用户
     * @param user
     * @return
     */
    @Insert("insert into t_user(username,password,realname,sex,birthday,status)" +
            " values(#{username},#{password},#{realname},#{sex},#{birthday},0)")
    @Options(useGeneratedKeys = true,keyProperty = "uid")
    int addUser(User user);

    /**
     * 修改
     * @param user
     * @return
     */
    @Update("update t_user set username=#{username},password=#{password},realname=#{realname},sex=#{sex},birthday=#{birthday} where uid=#{uid}")
    int updateUser(User user);

    /**
     * 添加中间表
     * @param uid
     * @param arr
     * @return
     */
    int addMiddle(@Param("uid") int uid,@Param("arr") String[] arr);

    /**
     * 根据id查询单个用户
     * @param id
     * @return
     */
    @Select("select * from t_user where uid=#{id}")
    @ResultMap("userMap")
    User findById(int id);

    /**
     * 根据uid删除中间表信息
     * @param uid
     * @return
     */
    @Delete("delete  from t_user_role where uid=#{uid}")
    int deleteMiddle(int uid);

    /**
     *
     * @param username
     * @return
     */
    @Select("select count(uid) from t_user where username=#{username}")
    int hashName(String username);

    /**
     * 根据uid查询用户对应角色id
     * @param uid
     * @return
     */
    @Select("SELECT rid from t_user_role where uid=#{uid}")
    List<Integer> findRoles(int uid);

    /**
     * 中间表批删
     * @param arr
     * @return
     */
    int batch_middle(@Param("arr") String[] arr);

    /**
     * 批量删除用户信息
     * @param arr
     * @return
     */
    int del_user(@Param("arr") String[] arr);

    /**
     * 状态修改
     * @param id
     * @return
     */
    @Update("update t_user set status= !status where uid=#{id}")
    boolean status(int id);
}

        2.mapper.xml文件动态sql语句

<?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.xu.mapper.UserMapper">
    <resultMap id="userMap" type="com.xu.pojo.User">
        <id property="uid" column="uid"/>
        <result property="username" column="username"/>
        <result property="password" column="password"/>
        <result property="realname" column="realname"/>
        <result property="sex" column="sex"/>
        <result property="birthday" column="birthday"/>
        <result property="status" column="status"/>
        <collection property="roles" ofType="com.xu.pojo.Role" column="uid" select="findRolesByUid">
            <id property="rid" column="rid"/>
            <result property="rname" column="rname"/>
        </collection>
    </resultMap>
    <insert id="addMiddle">
        insert into t_user_role(uid,rid) values
        <foreach collection="arr" separator="," item="id">
            (#{uid},#{id})
        </foreach>
    </insert>
    <delete id="batch_middle">
        delete  from t_user_role where uid in
        <foreach collection="arr" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
    <delete id="del_user">
        delete  from t_user where uid in
        <foreach collection="arr" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
    <select id="login" resultType="com.xu.pojo.User">
        select * from t_user where username=#{username} and password=#{password}
    </select>
    <select id="findUsers" resultMap="userMap" parameterType="com.xu.pojo.User">
        select * from t_user
        <where>
            <if test="username!=null || username!=''">
                and username like '%${username}%'
            </if>
            <if test="realname!=null || realname!=''">
                and realname like '%${realname}%'
            </if>
        </where>
    </select>
    <select id="findRolesByUid" resultType="com.xu.pojo.Role">
        select * from t_role where rid in(select rid from t_user_role where uid=#{uid})
    </select>


</mapper>

3.service包方法接口与实现类

        1.接口

package com.xu.service;

import com.github.pagehelper.PageInfo;
import com.xu.pojo.Role;
import com.xu.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface UserService {
    /**
     * 登录
     * @param user
     * @return
     */
    User login(User user);

    /**
     * 查询所有用户信息方法
     * @param user
     * @return
     */
    PageInfo<User> pageUsers(User user, Integer offset, Integer pagesize);

    /**
     * 查询所有角色
     * @return
     */
    List<Role> roles();

    /**
     * 执行添加与修改方法
     * @param user
     * @return
     */
    boolean save(User user);

    /**
     * 根据id查询用户
     * @param id
     * @return
     */
    User findById(int id);

    /**
     * 判断用户名是否重复的方法
     * @param username
     * @return
     */
    boolean hashName(String username);

    /**
     * 根据uid查询中间表对应角色id
     * @param uid
     * @return
     */
    List<Integer> findRoles(int uid);

    /**
     * 批量删除
     * @param ids
     * @return
     */
    boolean del(String ids);

    /**
     * 状态修改
     * @param id
     * @return
     */
    boolean status(int id);
}

        2.接口实现类

package com.xu.service.impl;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.xu.mapper.UserMapper;
import com.xu.pojo.Role;
import com.xu.pojo.User;
import com.xu.service.UserService;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class UserServiceImpl implements UserService {
    //创建mapper属性
    @Resource
    private UserMapper userMapper;


    /**
     * 登录
     * @param user
     * @return
     */
    @Override
    public User login(User user) {
        return this.userMapper.login(user.getUsername(),user.getPassword());
    }


    /**
     * 分页查询所有用户
     * @param user
     * @return
     */
    @Override
    public PageInfo<User> pageUsers(User user, Integer offset, Integer pagesize) {
        PageHelper.startPage(offset,pagesize);
        return new PageInfo<>(this.userMapper.findUsers(user));
    }

    @Override
    public List<Role> roles() {
        return this.userMapper.roles();
    }

    @Override
    public boolean save(User user) {
        int m=0;
        if (user.getUid()==null || user.getUid()==0){
            //向用户表插入数据
            m=this.userMapper.addUser(user);
            //向中间表插入数据
            m+=this.userMapper.addMiddle(user.getUid(),user.getChk());
            return m>=2;
        }else {
            //修改用户信息
            m=this.userMapper.updateUser(user);
            //删除中间表数据
            m+=this.userMapper.deleteMiddle(user.getUid());
            //想中间表中插入新数据
            m+=this.userMapper.addMiddle(user.getUid(),user.getChk());
            return m>=3;
        }
    }

    @Override
    public User findById(int id) {
        return this.userMapper.findById(id);
    }

    @Override
    public boolean hashName(String username) {
        return this.userMapper.hashName(username)==1;
    }

    @Override
    public List<Integer> findRoles(int uid) {
        return this.userMapper.findRoles(uid);
    }

    @Override
    public boolean del(String ids) {
        int m=0;
        String[] split = ids.split(",");
        //删除用户
        m=this.userMapper.del_user(split);
        //删除中间表
        m+=this.userMapper.batch_middle(split);

        return m>=2;
    }

    @Override
    public boolean status(int id) {
        return this.userMapper.status(id);
    }
}

4.web包下控制器

        1.控制器类

package com.xu.web;

import com.xu.pojo.User;
import com.xu.service.UserService;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpSession;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Controller
public class UserController {
    @Resource
    private UserService userService;

    /**
     * 登录页面
     * @return
     */
    @GetMapping("/login")
    public String tologin(){
        return "login";
    }

    /**
     * 登录请求
     * @param user
     * @param session
     * @param model
     * @return
     */
    @PostMapping("/login")
    public String login(User user, HttpSession session, Model model){
        User login=this.userService.login(user);
        if (login!=null){
            session.setAttribute("username",login.getUsername());
            return "redirect:/list";
        }else{
            model.addAttribute("mess","<font color='red'>登录失败!</font>");
            return "login";
        }
    }

    /**
     * 列表页面
     * @param model
     * @param offset
     * @param pagesize
     * @param user
     * @return
     */
    @RequestMapping("/list")
    public String list(Model model,
                       @RequestParam(name = "offset",defaultValue = "1") Integer offset,
                       @RequestParam(name = "pagesize",defaultValue = "3") Integer pagesize,
                        User user){
        model.addAttribute("pager",this.userService.pageUsers(user,offset,pagesize));
        return "list";
    }

    /**
     * 添加页面
     * @param model
     * @return
     */
    @GetMapping("/add")
    public String toadd(Model model){
        model.addAttribute("roles",this.userService.roles());
        return "add";
    }

    /**
     * 返回用户姓名是否存在
     * @param username
     * @return
     */
    @GetMapping("/hasUsername/{username}")
    @ResponseBody
    public boolean hasUsername(@PathVariable String username){
        return this.userService.hashName(username);
    }

    /**
     * 添加请求
     * @param model
     * @param user
     * @return
     */
    @PostMapping("/add")
    public String add(Model model,User user){
        if (this.userService.save(user)){
            return "redirect:/list";
        }else {
            model.addAttribute("msg","新增失败!");
            return "add";
        }
    }

    /**
     * 修改页面
     * @param model
     * @param uid
     * @return
     */
    @GetMapping("/update")
    public String toupdate(Model model,int uid){
        model.addAttribute(this.userService.findById(uid));
        model.addAttribute("roles",this.userService.roles());
        return "update";
    }

    /**
     * 返回要修改对象的角色id集合,实现回显
     * @param uid
     * @return
     */
    @GetMapping("/findRoles")
    @ResponseBody
    public List<Integer> findRoles(int uid){
        return this.userService.findRoles(uid);
    }

    /**
     * 修改
     * @param model
     * @param user
     * @return
     */
    @PostMapping("/update")
    public String update(Model model,User user){
        this.userService.save(user);
        return "redirect:/list";
    }

    /**
     * 批删
     * @param ids
     * @return
     */
    @GetMapping("/del")
    @ResponseBody
    public boolean del(String ids){
        return this.userService.del(ids);
    }

    /**
     * 状态修改
     * @param id
     * @return
     */
    @GetMapping("/status/{id}")
    @ResponseBody
    public boolean status(@PathVariable int id){
        return this.userService.status(id);
    }

    /**
     * 注销
     * @param session
     * @return
     */
    @GetMapping("/logout")
    public String logout(HttpSession session){
        session.removeAttribute("username");
        return "redirect:/login";
    }

}

        2.全局异常

package com.xu.web;

import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.ExceptionHandler;

import java.sql.SQLException;

public class MyException {
    /**
     * sql语句异常
     * @param e
     * @param model
     * @return
     */
    @ExceptionHandler(SQLException.class)
    public String sqlHandle(SQLException e, Model model){
        model.addAttribute("mess","sql异常!");
        return "sql-err";
    }

    /**
     * 空指针异常
     * @param e
     * @param model
     * @return
     */
    @ExceptionHandler(NullPointerException.class)
    public String nullHandle(NullPointerException e,Model model){
        model.addAttribute("mess","空指针异常!");
        return "null-err";
    }
}

5.拦截器

package com.xu.interceptor;

import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.servlet.http.HttpSession;
import org.springframework.web.servlet.HandlerInterceptor;

public class LogInterceptor implements HandlerInterceptor {
    /**
     * 重写拦截方法(处理之前)
     * @param request
     * @param response
     * @param handler
     * @return
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        HttpSession session=request.getSession();
        String uri = request.getRequestURI();
        System.out.println(">>>>>>>>>>>>>>>>>>>>>>"+uri);
        if (session.getAttribute("username")!=null || uri.endsWith("login")){
            return true;
        }else {
            response.sendRedirect("login");
        }
        return false;
    }
}

6.页面展示

        1.登录

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>login</title>
    <script src="webjars/jquery/3.6.4/jquery.min.js"></script>
    <link href="webjars/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
    <style scoped>
        .login{
            border-radius: 15px;
            background-clip: padding-box;
            margin: 100px auto;
            width: 350px;
            padding: 35px 15px 35px 15px;
            border: 1px solid #eaeaea;
            background: #ffffff;
            box-shadow: 0 0 25px #caeaea;
        }
    </style>
</head>
<body>
    <div class="container">
        <form method="post" class="login">
            账号:<input type="text" name="username"><br>
            密码:<input type="password" name="password"><br>
            <button class="btn btn-success">登录</button>
            <span th:utext="${mess}"></span>
        </form>
    </div>
</body>
</html>

        2.列表

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>list</title>
  <script src="webjars/jquery/3.6.4/jquery.min.js"></script>
  <link href="webjars/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
  <script>
    $(function (){
      //修改按钮
      $(".btn-primary").click(function (){
        location="update?uid="+$(this).val();
      })
      //全选
      $("#all").click(function (){
        $("[name='del']").prop("checked",$(this).prop("checked"));
      })
      //批删
      $(".btn-secondary").click(function (){
        //判断是否选择
        var $name = $("[name='del']:checked");
        if($name.length==0){
          alert("对不起,请选择!")
        }else{
          //获取要删除的uid
          let values="";
          $name.each(function (){
            values += $(this).val()+','
          })
          if(confirm("确认删除选中用户吗??")){
            $.get(
                    "del",
                    {ids:values},
                    function (data){
                      if(data){
                        alert("删除成功!");
                        location.reload()
                      }else{
                        alert("删除失败!")
                      }
                    }
            )
          }
        }
      })
      //状态修改按钮
      $(".btn-warning").click(function (){
        $.get(
                "status/"+$(this).val(),
                function (data){
                  if (data){
                    alert("状态修改成功!");
                    location.reload();
                  }else {
                    alert("状态修改失败!");
                  }
                }
        )
      })
    })
  </script>
</head>
<body>
<div class="container">
  <h4>欢迎登录[[${session.username}]],<a th:href="@{logout}">注销</a></h4>
  <form action="list" method="post">
    <input type="text" name="username" placeholder="账号">
    <input type="text" name="realname" placeholder="姓名">
    <button class="btn btn-light">搜索</button>
  </form>
  <table class="table table-bordered table-hover">
    <tr>
      <td>
        <input type="checkbox" id="all">全选
        <button class="btn btn-secondary">删除</button>
      </td>
      <th>编号</th>
      <th>账号</th>
      <th>密码</th>
      <th>姓名</th>
      <th>性别</th>
      <th>生日</th>
      <th>状态</th>
      <th>角色</th>
      <th>
        <button class="btn btn-success" onclick="location='add'">新增</button>
      </th>
    </tr>

    <tr th:each="user:${pager.list}" th:object="${user}">
      <td><input type="checkbox" name="del" th:value="*{uid}"></td>
      <td th:text="*{uid}"></td>
      <td th:text="*{username}"></td>
      <td th:text="*{password}"></td>
      <td th:text="*{realname}"></td>
      <td th:text="*{sex} == 0 ? '男': '女'"></td>
      <td th:text="*{#dates.format(birthday,'yyyy-MM-dd')}"></td>
      <td th:text="*{status} ==0  ? '活动' : '禁用'"></td>
      <td>
                     <span th:each="role:*{roles}" th:object="${role}">
                       <span th:text="*{rname}"></span>
                     </span>
      </td>
      <td>
        <button th:value="*{uid}" class="btn btn-primary">修改</button>
        <button class="btn btn-warning" th:value="*{uid}" th:text="*{status}==0 ? '禁用' : '活动'"></button>
      </td>
    </tr>
    <tr>
      <td colspan="10" align="center">
        共<span th:text="${pager.total}"></span>条数据,共<span th:text="${pager.pages}"></span>页,
        当前是第<span th:text="${pager.pageNum}"></span>页。
        <a th:href="@{list(offset=1,username=${username},realname=${realname})}">首页</a>
        <a th:if="${pager.hasPreviousPage}" th:href="@{list(offset=${pager.prePage},username=${username},realname=${realname})}">上页</a>
        <a th:if="${pager.hasNextPage}" th:href="@{list(offset=${pager.nextPage},username=${username},realname=${realname})}">下页</a>
        <a th:href="@{list(offset=${pager.pages},username=${username},realname=${realname})}">末页</a>
      </td>
    </tr>
  </table>
</div>
</body>
</html>

        3.添加

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>add</title>
    <script src="webjars/jquery/3.6.4/jquery.min.js"></script>
    <link href="webjars/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
    <script>
        $(function (){
            $("[name='username']").blur(function (){
                var name = $(this).val();
                if(name.length==0){
                    $("#sp1").html("<font color='red'>对不起账号不能为空!</font>")
                }else{
                    $.get(
                        "hasUsername/"+name,
                        function (obj){
                            if(obj){
                                $("#sp1").html("<font color='red'>账号已存在!</font>");
                            }else{
                                $("#sp1").html("<font color='green'>OK!</font>");
                            }
                        }
                    )
                }
            })
        })
    </script>
</head>
<body>
        <div class="container">
            <form method="post" >
                账号:<input type="text" name="username">
                <span id="sp1"></span><br>
                密码:<input type="password" name="password"><br>
                姓名:<input type="text" name="realname"><br>
                性别:<input type="radio" name="sex" value="0"> 男
                <input type="radio" name="sex" value="1">女<br>
                生日:<input type="text" name="birthday"><br>
                角色:
                <input th:each="role:${roles}" type="checkbox" name="chk" th:value="${role.rid}" th:text="${role.rname}">


                <button class="btn btn-success">提交</button>
            </form>
        </div>

</body>
</html>

        4.修改

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>add</title>
    <script src="webjars/jquery/3.6.4/jquery.min.js"></script>
    <link href="webjars/bootstrap/5.2.3/css/bootstrap.min.css" rel="stylesheet">
    <script>
        $(function (){
            $.get(
                "findRoles",
                {uid:$("[name='uid']").val()},
                function (data){
                    console.log(data);
                    for(var i in data){
                        $("[name='chk'][value='"+data[i]+"']").prop("checked",true);
                    }
                }
            )
        })
    </script>
</head>
<body>
        <div class="container">
            <form method="post" th:object="${user}">
                <input type="hidden" name="uid" th:value="*{uid}">
                账号:<input type="text" name="username" th:value="*{username}">
                <span id="sp1"></span><br>
                密码:<input type="password" name="password" th:value="*{password}"><br>
                姓名:<input type="text" name="realname" th:value="*{realname}"><br>
                性别:<input type="radio" name="sex" th:value="0" th:checked="*{sex==0}"> 男
                <input type="radio" name="sex" th:value="1" th:checked="*{sex==1}">女<br>
                生日:<input type="text" name="birthday" th:value="*{#dates.format(birthday,'yyyy-MM-dd')}"> <br>
                角色:<input type="checkbox" name="chk" th:each="role:${roles}" th:value="${role.rid}" th:text="${role.rname}">
                <br>
                <button class="btn btn-success">提交</button>
            </form>
        </div>

</body>
</html>

切记:写注解,测试类

切记:写注解,测试类

切记:写注解,测试类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值