登录注册,文件增删查改实现

登录注册文件增删查改实现

需求:实现登录功能,注册功能。登录后文件可以进行增加删除修改查看等基本功能的操作。

知识点:mybatis ,Tomcat,servlet , asion , json ,req , resp ,session

前提准备:

pom.xml坐标导入:

导入Mybatis和Mysql驱动坐标,日志坐标,Servlet坐标

 <dependencies>
        <!--mybatis环境-->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.5.3</version>
        </dependency>
        <!--mysql环境-->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.47</version>
        </dependency>
        <!--分页插件坐标-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>5.1.2</version>
        </dependency>

        <!--servlet环境-->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!--jstl-->
        <dependency>
            <groupId>jstl</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
        </dependency>
        <dependency>
            <groupId>taglibs</groupId>
            <artifactId>standard</artifactId>
            <version>1.1.2</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.62</version>
        </dependency>

        <!--其他组件-->
        <!--junit单元测试-->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
        <!--日志-->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-api</artifactId>
            <version>1.7.20</version>
        </dependency>
        <!-- 添加logback-classic依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
        <!-- 添加logback-core依赖 -->
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>

    </dependencies>

    <build>
        <plugins>
            <!-- tomcat 插件 -->
            <plugin>
                <groupId>org.apache.tomcat.maven</groupId>
                <artifactId>tomcat7-maven-plugin</artifactId>
                <version>2.2</version>
                <configuration>
                    <port>80</port>
                    <path>/</path>
                    <uriEncoding>utf-8</uriEncoding>
                </configuration>
            </plugin>
        </plugins>
    </build>

mybatis需要的相关准备

  1. 创建的是mavenweb项目,且导入mybatis框架。需要在resources资源包下导入mybatis核心配置文件。写数据库连接和资源配置文件路径等。

  2. 在java项目下创建pojo包,里面写数据库中表对应的实体类,settergetter,toString,空参,满参构造。

  3. 在java项目下创建mapper包,里面写实体类对应的mapper接口。eg:实体类User mapper下就创建UserMapper接口,一个实体类对应一个mapper

  4. 在resources资源包下创建和mapper对应路径的mapper文件名.xml。详细SQL写这里,或者java中mappe的方法上写注解。

包名解析

pojo : 存放实体类

util:存放工具类

mapper : 存放操作数据库数据的类,

service : 存放业务处理的逻辑业务类,逻辑层

web : 存放与前端交互的类,界面层

登录

思路分析:

在这里插入图片描述

  1. 用户在登录页面输入用户名和密码,提交请求给LoginServlet
  2. 在LoginServlet中接收请求和数据[用户名和密码]
  3. 在LoginServlt中通过Mybatis实现调用UserMapper来根据用户名和密码查询数据库表
  4. 将查询的结果封装到User对象中进行返回
  5. 在LoginServlet中判断返回的User对象是否为null
  6. 如果为null,说明根据用户名和密码没有查询到用户,则登录失败,请求转发到登录页面,携带数据(用户名或者密码不正确,请重新登录)
  7. 如果不为null,则说明用户存在并且密码正确,则登录成功,请求转发到查询所有页面

代码实现:

数据处理mapper

写根据用户名和密码查询数据,返回一个user对象。给逻辑层查询使用

public interface UserMapper {
    //查询是否有这个用户名密码
    @Select("select * from tb_user where username=#{username} and password=#{password}")
    User selectNP(User user);
}

细节解析:这个接口中查询用户名和密码是否存在,是一个简单SQL查询。可以直接使用注解。

​ 查出来就是一条数据,没有数据就返回null

逻辑层

接收界面层传入数据,写一个对应的用户登录验证方法。类:UserService

public class UserService {
    //  获取数据库连接方式。使用了工具类
    private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();


    // 判断登录的方法
    public User selectDL(User user) {
//1. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();

//  2,调用登录对比查询方法
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User user1 = mapper.selectNP(user);
      
//  3, 返回数据
        return user1;
    }
}

细节分析:

  1. 这个类里面可以写关于user的所有逻辑处理,现在写的是登录判断selectDL方法
  2. 因为这个类需要连获取数据库连接,会写好多方法,所以直接写到类里面,所有方法可用。 private私有化其他类不可以用。
private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
  1. 方法内调用mapper中写的SQL语句,返回数据即可。
界面层:

接收请求和数据,判断是否登录成功,响应数据

//  登录
@WebServlet("/loginServlet")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // 处理请求数据中文乱码
        request.setCharacterEncoding("utf-8");
//1.接收用户数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");

//2.封装用户对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

//3.调用逻辑层进行判断
        UserService userService = new UserService();
        User user1 = userService.selectDL(user);

//4. 判断用户对象是否为null
        // 响应数据中文乱码处理
        response.setContentType("text/html;charset=utf-8");
        if( user1 == null){
            // 用户名信息错误,返回提示信息和登录页面
            request.setAttribute("login_msg","用户名或密码错误");
            // 跳转到login.jsp,请求转发页面上路径不变,不走网络,直接要跳转到位置即可
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }else {//用户登录成功,显示用户信息和进入里面.携带用户信息
            
           // 用户信息存入session中,方便后期过滤登录和页面使用用户信息
            HttpSession session = request.getSession();
            session.setAttribute("user",user);
            request.getRequestDispatcher("/brand.html").forward(request,response);
        }
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

细节回顾:

  1. 前端传来的用户名和密码里面可能会包含中文,接收数据前需要处理中文乱码。乱码数据不能正确和数据库进行比对。
request.setCharacterEncoding("utf-8");
  1. 在响应时,有中文字符,也需要处理响应中文乱码
 // 响应数据中文乱码处理
 response.setContentType("text/html;charset=utf-8");
  1. 判断用户名密码正确要进入页面时,需要用session保存下用户信息,

    (1) : 页面里面需要展示用户信息

    (2) : 后期优化过滤登录时做登录判断

// 用户信息存入session中,方便后期过滤登录和页面使用用户信息
HttpSession session = request.getSession();
session.setAttribute("user",user);

注册

思路分析:

  1. 验证码判断,验证码错误,直接返回注册页面,不判断用户信息

  2. 验证码通过,判断用户名是否存在,存在:提示用户名存在,重新注册。

​ 不存在:注册账号,返回登录页面。

需要一个查询语句(查询用户名是否存在),一个添加账号语句(除去查询,都需要提交事务)
在这里插入图片描述

  1. 用户在注册页面输入用户名和密码,验证码,提交请求给RegisterServlet
  2. 在RegisterServlet中接收请求和数据[用户名和密码和验证码]
  3. 在界面层判断验证码,过了进行下面判断,不过直接返回注册页面
  4. 在RegisterServlet中通过Mybatis实现调用UserMapper来根据用户名查询数据库表
  5. 将查询的结果封装到User对象中进行返回
  6. 在RegisterServlet中判断返回的User对象是否为null
  7. 如果为null,说明根据用户名可用,则调用UserMapper来实现添加用户
  8. 如果不为null,则说明用户不可以,返回"用户名已存在"数据给前端

代码实现

mapper

查询用户名和添加账号两个SQL直接写

public interface UserMapper {
    //    查询是否用户名存在
    @Select("select * from tb_user where username=#{username}")
    User selectName(String username);

    //   添加用户名,密码
    @Insert("INSERT into  tb_user(username,password) VALUES (#{username},#{password})")
    int insertNP(User user);
}

逻辑层

写两个方法,一个验证用户名,一个添加账号

public class UserService {
    //   获取数据库连接方式
    private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

    // 查询数据库用户名是否存在
    public User selectName(String username) {
//        获取数据库连接
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        return mapper.selectName(username);
    }


    //添加数据,注册账号
    public int inster(User user) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//        返回影响行数
        int i = mapper.insertNP(user);
        sqlSession.commit();// 提交事务
        return i;
    }
}

**代码分析:**添加数据方法返回int,添加成功 mapper.insertNP(user)返回影响行数,若是返回0,就是没有添加。

界面层

接收注册的用户名和密码,验证码,调用逻辑层代码进行判断。

把数据库里面的验证码和前端传来的验证码进行对比。

判断用户名是否存在,存在:直接返回注册页面重新注册,给出提示。

​ 不存在:添加账号,返回登录页面。

// 注册
@WebServlet("/registerServlet")
public class RegisterServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        request.setCharacterEncoding("utf-8");
        //1. 接收用户数据
        String username = request.getParameter("username");
        String password = request.getParameter("password");
        String checkCode = request.getParameter("checkCode");  //验证码

        // 先判断验证码是否正确,再进行用户名重复判断
        HttpSession session = request.getSession();
        String yzm = (String) session.getAttribute("yzm");
        if(!yzm.equalsIgnoreCase(checkCode)){// 如果不相等,直接结束判断,重新输入
            // 验证码错误,忽略大小写
            request.setAttribute("register_msg","验证码错误,请重新输入");
            // 转发到注册页面
            request.getRequestDispatcher("/register.jsp").forward(request,response);
            return;// 不再往下执行
        }
        
        
        //封装用户对象
        User user = new User();
        user.setUsername(username);
        user.setPassword(password);

        UserService service = new UserService();
        User user1 = service.selectName(username);
        if( user1 == null){
            // 用户名不存在,添加用户 返回提示信息和登录页面
            service.inster(user);
            request.setAttribute("login_msg","注册成功啦,请登录");
            // 转发到登录页面
            request.getRequestDispatcher("/login.jsp").forward(request,response);
        }else {
            // 用户名存在,给出提示信息
            request.setAttribute("register_msg","此用户名已存在,请重新注册");
            // 转发到注册页面
            request.getRequestDispatcher("/register.jsp").forward(request,response);
        }

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

代码分析:

  1. 请求有中文。处理中文乱码
 request.setCharacterEncoding("utf-8");
  1. 验证码输入正常业务场景需要省略大小写
  // 从数据库中取数据(验证码)
        HttpSession session = request.getSession();
        String yzm = (String) session.getAttribute("yzm");
        // 验证码对比,忽略大小写
        if(!yzm.equalsIgnoreCase(checkCode)){// 如果不相等,直接结束判断,重新输入  
           // 业务代码...
            return;// 不再往下执行
        }

工具类(验证码)

util中:

/**
 * 生成验证码工具类
 */
public class CheckCodeUtil {

    public static final String VERIFY_CODES = "123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    private static Random random = new Random();

    /**
     * 输出随机验证码图片流,并返回验证码值(一般传入输出流,响应response页面端,Web项目用的较多)
     *
     * @param width 图片宽度
     * @param height 图片高度
     * @param os  输出流
     * @param verifySize 数据长度
     * @return 验证码数据
     * @throws IOException
     */
    public static String outputVerifyImage(int width, int height, OutputStream os, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(width, height, os, verifyCode);
        return verifyCode;
    }

    /**
     * 使用系统默认字符源生成验证码
     *
     * @param verifySize 验证码长度
     * @return
     */
    public static String generateVerifyCode(int verifySize) {
        return generateVerifyCode(verifySize, VERIFY_CODES);
    }

    /**
     * 使用指定源生成验证码
     *
     * @param verifySize 验证码长度
     * @param sources    验证码字符源
     * @return
     */
    public static String generateVerifyCode(int verifySize, String sources) {
        // 未设定展示源的字码,赋默认值大写字母+数字
        if (sources == null || sources.length() == 0) {
            sources = VERIFY_CODES;
        }
        int codesLen = sources.length();
        Random rand = new Random(System.currentTimeMillis());
        StringBuilder verifyCode = new StringBuilder(verifySize);
        for (int i = 0; i < verifySize; i++) {
            verifyCode.append(sources.charAt(rand.nextInt(codesLen - 1)));
        }
        return verifyCode.toString();
    }

    /**
     * 生成随机验证码文件,并返回验证码值 (生成图片形式,用的较少)
     *
     * @param w
     * @param h
     * @param outputFile
     * @param verifySize
     * @return
     * @throws IOException
     */
    public static String outputVerifyImage(int w, int h, File outputFile, int verifySize) throws IOException {
        String verifyCode = generateVerifyCode(verifySize);
        outputImage(w, h, outputFile, verifyCode);
        return verifyCode;
    }



    /**
     * 生成指定验证码图像文件
     *
     * @param w
     * @param h
     * @param outputFile
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, File outputFile, String code) throws IOException {
        if (outputFile == null) {
            return;
        }
        File dir = outputFile.getParentFile();
        //文件不存在
        if (!dir.exists()) {
            //创建
            dir.mkdirs();
        }
        try {
            outputFile.createNewFile();
            FileOutputStream fos = new FileOutputStream(outputFile);
            outputImage(w, h, fos, code);
            fos.close();
        } catch (IOException e) {
            throw e;
        }
    }

    /**
     * 输出指定验证码图片流
     *
     * @param w
     * @param h
     * @param os
     * @param code
     * @throws IOException
     */
    public static void outputImage(int w, int h, OutputStream os, String code) throws IOException {
        int verifySize = code.length();
        BufferedImage image = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
        Random rand = new Random();
        Graphics2D g2 = image.createGraphics();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

        // 创建颜色集合,使用java.awt包下的类
        Color[] colors = new Color[5];
        Color[] colorSpaces = new Color[]{Color.WHITE, Color.CYAN,
                Color.GRAY, Color.LIGHT_GRAY, Color.MAGENTA, Color.ORANGE,
                Color.PINK, Color.YELLOW};
        float[] fractions = new float[colors.length];
        for (int i = 0; i < colors.length; i++) {
            colors[i] = colorSpaces[rand.nextInt(colorSpaces.length)];
            fractions[i] = rand.nextFloat();
        }
        Arrays.sort(fractions);
        // 设置边框色
        g2.setColor(Color.GRAY);
        g2.fillRect(0, 0, w, h);

        Color c = getRandColor(200, 250);
        // 设置背景色
        g2.setColor(c);
        g2.fillRect(0, 2, w, h - 4);

        // 绘制干扰线
        Random random = new Random();
        // 设置线条的颜色
        g2.setColor(getRandColor(160, 200));
        for (int i = 0; i < 20; i++) {
            int x = random.nextInt(w - 1);
            int y = random.nextInt(h - 1);
            int xl = random.nextInt(6) + 1;
            int yl = random.nextInt(12) + 1;
            g2.drawLine(x, y, x + xl + 40, y + yl + 20);
        }

        // 添加噪点
        // 噪声率
        float yawpRate = 0.05f;
        int area = (int) (yawpRate * w * h);
        for (int i = 0; i < area; i++) {
            int x = random.nextInt(w);
            int y = random.nextInt(h);
            // 获取随机颜色
            int rgb = getRandomIntColor();
            image.setRGB(x, y, rgb);
        }
        // 添加图片扭曲
        shear(g2, w, h, c);

        g2.setColor(getRandColor(100, 160));
        int fontSize = h - 4;
        Font font = new Font("Algerian", Font.ITALIC, fontSize);
        g2.setFont(font);
        char[] chars = code.toCharArray();
        for (int i = 0; i < verifySize; i++) {
            AffineTransform affine = new AffineTransform();
            affine.setToRotation(Math.PI / 4 * rand.nextDouble() * (rand.nextBoolean() ? 1 : -1), (w / verifySize) * i + fontSize / 2, h / 2);
            g2.setTransform(affine);
            g2.drawChars(chars, i, 1, ((w - 10) / verifySize) * i + 5, h / 2 + fontSize / 2 - 10);
        }

        g2.dispose();
        ImageIO.write(image, "jpg", os);
    }

    /**
     * 随机颜色
     *
     * @param fc
     * @param bc
     * @return
     */
    private static Color getRandColor(int fc, int bc) {
        if (fc > 255) {
            fc = 255;
        }
        if (bc > 255) {
            bc = 255;
        }
        int r = fc + random.nextInt(bc - fc);
        int g = fc + random.nextInt(bc - fc);
        int b = fc + random.nextInt(bc - fc);
        return new Color(r, g, b);
    }

    private static int getRandomIntColor() {
        int[] rgb = getRandomRgb();
        int color = 0;
        for (int c : rgb) {
            color = color << 8;
            color = color | c;
        }
        return color;
    }

    private static int[] getRandomRgb() {
        int[] rgb = new int[3];
        for (int i = 0; i < 3; i++) {
            rgb[i] = random.nextInt(255);
        }
        return rgb;
    }

    private static void shear(Graphics g, int w1, int h1, Color color) {
        shearX(g, w1, h1, color);
        shearY(g, w1, h1, color);
    }

    private static void shearX(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(2);

        boolean borderGap = true;
        int frames = 1;
        int phase = random.nextInt(2);

        for (int i = 0; i < h1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(0, i, w1, 1, (int) d, 0);
            if (borderGap) {
                g.setColor(color);
                g.drawLine((int) d, i, 0, i);
                g.drawLine((int) d + w1, i, w1, i);
            }
        }

    }

    private static void shearY(Graphics g, int w1, int h1, Color color) {

        int period = random.nextInt(40) + 10; // 50;

        boolean borderGap = true;
        int frames = 20;
        int phase = 7;
        for (int i = 0; i < w1; i++) {
            double d = (double) (period >> 1)
                    * Math.sin((double) i / (double) period
                    + (6.2831853071795862D * (double) phase)
                    / (double) frames);
            g.copyArea(i, 0, 1, h1, 0, (int) d);
            if (borderGap) {
                g.setColor(color);
                g.drawLine(i, (int) d, i, 0);
                g.drawLine(i, (int) d + h1, i, h1);
            }

        }

    }
}

web调用工具类:

@WebServlet("/checkCodeServlet")
public class CheckCodeServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        生成验证码
        ServletOutputStream os = response.getOutputStream();
        String s = CheckCodeUtil.outputVerifyImage(100, 50, os, 4);

//         存入session中,验证码是一存一取一验证
        HttpSession session = request.getSession();
        session.setAttribute("yzm",s);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

验证码是一刷新换一张,所以需要清理缓存;

在前端里面:刷新数据是带参数,形成新的页面。参数用时间显示,一秒一个。

<script>
    document.getElementById("changeImg").onclick = function () {
        document.getElementById("checkCodeImg").src = "/checkCodeServlet?" + new Date().getMilliseconds();
    }
</script>

查询所有数据:

思路分析:

账号验证后,进入页面,直接展示所有数据。就是登录界面层跳转到查询所有的界面层。

查询不需要前端请求参数,直接查询,在页面展示即可。

mapper层代码

因为实体类名称有些和数据库列名不一致

需要在对应的.xml文件标注

<resultMap id="brandResultMap" type="brand">
        <result column="brand_name" property="brandName"></result>
        <result column="company_name" property="companyName"></result>
    </resultMap>
public interface BrandMapper {
    //    查询所有数据返回到 List集合中
    @Select("select * from tb_brand")
    @ResultMap("brandResultMap")
    List<Brand> selectAll();

}

逻辑层

public class BrandService {
    private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

    //    查询所有数据,调用对应方法(数据库)
    public List<Brand> selectAll() {
//     调用工具类中获取mybatis连接的方法
        //获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);

        List<Brand> brands = mapper.selectAll();
        sqlSession.close();
        return brands;
    }   
}

页面层代码

  1. 正常应该是1,2,3步骤,先处理数据,然后数据转发到展示页面。

  2. 现在引入新技术asion结合html进行异步请求,所有是html展示,然后异步这个查询功能,直接响应数据即可,不用转发了。

  3. JSON是一种新的编码语言,下面详细写(需要坐标依赖)

@WebServlet("/selectAllServlet")
public class SelectAllServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//        查询所有表单
        //1. 调用BrandService完成查询
        BrandService service = new BrandService();
        List<Brand> brands = service.selectAll();

     
          // 设置编码,处理中文乱码问题text/json,针对json
        String s = JSON.toJSONString(brands);
        response.setContentType("text/json;charset=utf-8");
        //A. 响应数据  application/json   text/json
        response.getWriter().write(s);

        //2. 存入request域中
//        request.setAttribute("brands",brands);

        //3. 转发到brand.jsp
//        request.getRequestDispatcher("/brand.jsp").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request,response);
    }
}

添加数据

brand.jsp展示数据时,有添加按钮,会跳转到添加页面:addBrand.jsp。

addBrand.jsp会把请求参数传入后端。

思路分析:

后台接收请求数据,进行封装,然后给逻辑层,逻辑层调用mapper中对应的添加功能,完成添加。
在这里插入图片描述

上图是做 添加 功能流程。点击 新增 按钮后,会先跳转到 addBrand.jsp 新增页面,在该页面输入要添加的数据,输入完毕后点击 提交 按钮,需要将数据提交到后端,而后端进行数据添加操作,并重新将所有的数据查询出来。整个流程如下:

在这里插入图片描述

接下来我们根据流程来实现功能:(使用了Ajax的ASION工具+html)就直接跳转到查询,直接跳转到展示页面,Brand.html,html自己异步请求查询即可。

代码实现

mapper层
public interface BrandMapper {
 
    //    添加商品数据
    @Insert("INSERT into tb_brand VALUES(null,#{brandName},#{companyName},#{ordered},#{description},#{status})")
    @ResultMap("brandResultMap")
    void add(Brand brand);
}
逻辑层
public class BrandService {
    private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

    //     添加商品数据
    public void add(Brand brand){
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        mapper.add(brand);

        sqlSession.commit();// 提交事务
        sqlSession.close();
    }
}
界面层
@WebServlet("/addServlet")
public class AddServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//       处理中文乱码
        request.setCharacterEncoding("utf-8");
//        获取用户信息
        String brandName = request.getParameter("brandName");
        String companyName = request.getParameter("companyName");
        String ordered = request.getParameter("ordered");  //Integer
        String description = request.getParameter("description");
        String status = request.getParameter("status");  //Integer
        Integer orderedInteger = Integer.getInteger(ordered);
        Integer statusInteger = Integer.getInteger(status);

//        封装
        Brand brand = new Brand(null, brandName, companyName, orderedInteger, description, statusInteger);
        BrandService service = new BrandService();
        service.add(brand);

//     转发
            request.getRequestDispatcher("/brand.html").forward(request, response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

修改数据

根据id修改,修改时需要显示数据(数据回显)。然后修改提交。

有待提高:可以动态修改,全部不修改不调用修改功能

mapper:

根据id修改,不可以修改id

  1. 回显数据,查id,返回整条数据
  2. 根据id修改数据
public interface BrandMapper {

    //根据id回显数据
    @Select("select * from tb_brand where id = #{id}")
    @ResultMap("brandResultMap")
    Brand selectId(Integer id);

    //    根据id修改数据
    @Update("UPDATE tb_brand set brand_name = #{brandName} ,company_name = #{companyName} ," +
            "ordered=#{ordered},description=#{description},status=#{status} where id=#{id}")
    @ResultMap("brandResultMap")
    void updateBrand(Brand brand);

}

逻辑层

public class BrandService {
    private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

//    修改时的回显数据
    public Brand selectId(Integer id){

        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        Brand brand = mapper.selectId(id);

        return brand;
    }

    //    修改商品信息
    public void updateBrand(Brand brand) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        mapper.updateBrand(brand);
        sqlSession.commit();
        sqlSession.close();
    }
}

页面层

回显数据代码

//修改时的回显数据
@WebServlet("/selectByIdServlet")
public class SelectByIdServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id = request.getParameter("id");

        Integer idInteger = Integer.parseInt(id);

        BrandService service = new BrandService();
        Brand brand = service.selectId(idInteger);
        request.setAttribute("brand",brand);
        request.getRequestDispatcher("/update.jsp").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

修改数据代码

@WebServlet("/updateServlet")
public class UpdateServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
//处理POST请求的乱码问题
        request.setCharacterEncoding("utf-8");

        // 获取信息
        String id = request.getParameter("id");
        String brandName = request.getParameter("brandName");
        String companyName = request.getParameter("companyName");
        String ordered = request.getParameter("ordered");
        String description = request.getParameter("description");
        String status = request.getParameter("status");
        Integer idInteger = Integer.parseInt(id);
        Integer orderedInteger = Integer.parseInt(ordered);
        Integer statusInteger = Integer.parseInt(status);

        // 封装信息
        Brand brand = new Brand(idInteger, brandName, companyName, orderedInteger, description, statusInteger);
        BrandService service = new BrandService();
        service.updateBrand(brand);
        request.getRequestDispatcher("/brand.html").forward(request,response);
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

删除数据

根据id删除。

有待提高:给出提示,确认要删除吗,删除后可以查看已删除数据,永久删除等。

mapper

public interface BrandMapper {

//    根据id删除
    @Delete("DELETE from tb_brand where id=#{id}")
    @ResultMap("brandResultMap")
    int dlectId(Integer id);
}

逻辑层

public class BrandService {
    private SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();

    //    根据id删除商品数据
    public int deleteId(Integer id) {
        //2. 获取SqlSession对象,用它来执行sql
        SqlSession sqlSession = sqlSessionFactory.openSession();
        BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
        int i = mapper.dlectId(id);
        sqlSession.commit();
        sqlSession.close();
        return i;
    }
}

页面层

@WebServlet("/deleteIdServlet")
public class DeleteIdServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        String id = request.getParameter("id");
        Integer i = Integer.parseInt(id);
        BrandService service = new BrandService();
        int deleteId = service.deleteId(i);

        request.getRequestDispatcher("/brand.html").forward(request,response);


    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        doGet(request, response);
    }
}

请求响应常见方法

request对象:

常见方法

  • 获取所有参数Map集合
Map<String,String[]> getParameterMap()
  • 根据名称获取参数值(数组)
String[] getParameterValues(String name)
  • 根据名称获取参数值(单个值)
String getParameter(String name)

接下来,我们通过案例来把上述的三个方法进行实例演示:

1.修改req.html页面,添加爱好选项,爱好可以同时选多个

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<form action="/request-demo/req2" method="get">
    <input type="text" name="username"><br>
    <input type="password" name="password"><br>
    <input type="checkbox" name="hobby" value="1"> 游泳
    <input type="checkbox" name="hobby" value="2"> 爬山 <br>
    <input type="submit">

</form>
</body>
</html>

在这里插入图片描述

2.在Servlet代码中获取页面传递GET请求的参数值

2.1获取GET方式的所有请求参数

/**
 * request 通用方式获取请求参数
 */
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //GET请求逻辑
        System.out.println("get....");
        //1. 获取所有参数的Map集合
        Map<String, String[]> map = req.getParameterMap();
        for (String key : map.keySet()) {
            // username:zhangsan lisi
            System.out.print(key+":");

            //获取值
            String[] values = map.get(key);
            for (String value : values) {
                System.out.print(value + " ");
            }

            System.out.println();
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

获取的结果为:

在这里插入图片描述

2.2获取GET请求参数中的爱好,结果是数组值

/**
 * request 通用方式获取请求参数
 */
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //GET请求逻辑
        //...
        System.out.println("------------");
        String[] hobbies = req.getParameterValues("hobby");
        for (String hobby : hobbies) {
            System.out.println(hobby);
        }
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

获取的结果为:
在这里插入图片描述

2.3获取GET请求参数中的用户名和密码,结果是单个值

/**
 * request 通用方式获取请求参数
 */
@WebServlet("/req2")
public class RequestDemo2 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        //GET请求逻辑
        //...
        String username = req.getParameter("username");
        String password = req.getParameter("password");
        System.out.println(username);
        System.out.println(password);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
    }
}

获取的结果为:

在这里插入图片描述

处理中文乱码

  1. 解决乱码:POST,getReader()

        request.setCharacterEncoding("UTF-8");//设置字符输入流的编码
    
  2. 解决乱码:get,获取参数的方式:getQueryString

// 乱码原因:tomcat进行URL解码,默认的字符集ISO-8859-1
/* //3.1 先对乱码数据进行编码:转为字节数组
byte[] bytes = username.getBytes(StandardCharsets.ISO_8859_1);
//3.2 字节数组解码
username = new String(bytes, StandardCharsets.UTF_8);*/

username  = new String(username.getBytes(StandardCharsets.ISO_8859_1),StandardCharsets.UTF_8);

Request请求转发

  1. 请求转发(forward):一种在服务器内部的资源跳转方式。
    在这里插入图片描述

(1)浏览器发送请求给服务器,服务器中对应的资源A接收到请求

(2)资源A处理完请求后将请求发给资源B

(3)资源B处理完后将结果响应给浏览器

(4)请求从资源A到资源B的过程就叫请求转发

通俗将,朋友A找我借钱,我带着A找朋友B去借钱,然后B给A钱。

  1. 请求转发的实现方式:
req.getRequestDispatcher("资源B路径").forward(req,resp);
  1. 请求转发资源间共享数据:使用Request对象

此处主要解决的问题是把请求从/req5转发到/req6的时候,如何传递数据给/req6

需要使用request对象提供的三个方法:

  • 存储数据到request域[范围,数据是存储在request对象]中
void setAttribute(String name,Object o);
  • 根据key获取值
Object getAttribute(String name);
  • 根据key删除该键值对
void removeAttribute(String name);

接着上个需求来:
在这里插入图片描述

1.在RequestDemo5的doGet方法中转发请求之前,将数据存入request域对象中

2.在RequestDemo6的doGet方法从request域对象中获取数据,并将数据打印到控制台

3.启动访问测试

(1)修改RequestDemo5中的方法

@WebServlet("/req5")
public class RequestDemo5 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo5...");
        //存储数据
        request.setAttribute("msg","hello");
        //请求转发
        request.getRequestDispatcher("/req6").forward(request,response);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

(2)修改RequestDemo6中的方法

/**
 * 请求转发
 */
@WebServlet("/req6")
public class RequestDemo6 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("demo6...");
        //获取数据
        Object msg = request.getAttribute("msg");
        System.out.println(msg);

    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  1. 请求转发的特点
  • 浏览器地址栏路径不发生变化

    虽然后台从/req5转发到/req6,但是浏览器的地址一直是/req5,未发生变化
    在这里插入图片描述

  • 只能转发到当前服务器的内部资源

    不能从一个服务器通过转发访问另一台服务器

  • 一次请求,可以在转发资源间使用request共享数据

    虽然后台从/req5转发到/req6,但是这个只有一次请求

Response对象

  • Request:使用request对象来获取请求数据
  • Response:使用response对象来设置响应数据

Respones请求重定向

  1. 重定向方法:
resposne.sendRedirect("全部路径(模块名+路径名)");
//resposne.sendRedirect("/request-demo/resp2");

代码实现:

@WebServlet("/resp1")
public class ResponseDemo1 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        System.out.println("resp1....");
        //重定向
        resposne.sendRedirect("/request-demo/resp2")}

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  1. 重定向的特点
  • 浏览器地址栏路径发送变化

    当进行重定向访问的时候,由于是由浏览器发送的两次请求,所以地址会发生变化
    在这里插入图片描述

  • 可以重定向到任何位置的资源(服务内容、外部均可)

    因为第一次响应结果中包含了浏览器下次要跳转的路径,所以这个路径是可以任意位置资源。

  • 两次请求,不能在多个资源使用request共享数据

    因为浏览器发送了两次请求,是两个不同的request对象,就无法通过request对象进行共享数据

介绍完请求重定向请求转发以后,接下来需要把这两个放在一块对比下:

在这里插入图片描述
重定向需要全部路径,模块名,路径防止错误和修改可以直接使用方法

request.getContextPath();
    //简化方式完成重定向
    //动态获取虚拟目录
    String contextPath = request.getContextPath();
    response.sendRedirect(contextPath+"/resp2");

路径问题

问题1:转发的时候路径上没有加/request-demo而重定向加了,那么到底什么时候需要加,什么时候不需要加呢?
在这里插入图片描述

其实判断的依据很简单,只需要记住下面的规则即可:

  • 浏览器使用:需要加虚拟目录(项目访问路径)
  • 服务端使用:不需要加虚拟目录

对于转发来说,因为是在服务端进行的,所以不需要加虚拟目录

对于重定向来说,路径最终是由浏览器来发送请求,就需要添加虚拟目录。

掌握了这个规则,接下来就通过一些练习来强化下知识的学习:

  • <a href='路劲'>
  • <form action='路径'>
  • req.getRequestDispatcher(“路径”)
  • resp.sendRedirect(“路径”)

答案:

1.超链接,从浏览器发送,需要加
2.表单,从浏览器发送,需要加
3.转发,是从服务器内部跳转,不需要加
4.重定向,是由浏览器进行跳转,需要加。
  1. 问题2:在重定向的代码中,/request-demo是固定编码的,如果后期通过Tomcat插件配置了项目的访问路径,那么所有需要重定向的地方都需要重新修改,该如何优化?
    在这里插入图片描述
    可以在代码中动态去获取项目访问的虚拟目录,借助request对象中的getContextPath()方法,

重定向需要全部路径,模块名,路径防止错误和修改可以直接使用方法

request.getContextPath();
    //简化方式完成重定向
    //动态获取虚拟目录
    String contextPath = request.getContextPath();
    response.sendRedirect(contextPath+"/resp2");

Response响应字符数据

要想将字符数据写回到浏览器,我们需要两个步骤:

  • 通过Response对象获取字符输出流: PrintWriter writer = resp.getWriter();

  • 通过字符输出流写数据: writer.write(“aaa”);

接下来,我们实现通过些案例把响应字符数据给实际应用下:

  1. 返回一个简单的字符串aaa
/**
 * 响应字符数据:设置字符数据的响应体
 */
@WebServlet("/resp3")
public class ResponseDemo3 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("text/html;charset=utf-8");
        //1. 获取字符输出流
        PrintWriter writer = response.getWriter();
		 writer.write("aaa");
    }
    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

在这里插入图片描述

  1. 返回一串html字符串,并且能被浏览器解析
response.setHeader("content-type","text/html");
PrintWriter writer = response.getWriter();
//content-type,告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
response.setHeader("content-type","text/html");
writer.write("<h1>aaa</h1>");

在这里插入图片描述

==注意:==一次请求响应结束后,response对象就会被销毁掉,所以不要手动关闭流。

  1. 返回一个中文的字符串你好,需要注意设置响应数据的编码为utf-8
//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");
writer.write("你好");

在这里插入图片描述

总结:

响应

response.setContentType("text/html;charset=utf-8");
writer.write("aaa");

响应数据写html,识别html标签

//content-type,告诉浏览器返回的数据类型是HTML类型数据,这样浏览器才会解析HTML标签
response.setHeader("content-type","text/html");

响应中文数据,解决中文乱码

//设置响应的数据格式及数据的编码
response.setContentType("text/html;charset=utf-8");

Response响应字节数据

要想将字节数据写回到浏览器,我们需要两个步骤:

  • 通过Response对象获取字节输出流:
ServletOutputStream outputStream = resp.getOutputStream();
  • 通过字节输出流写数据:
outputStream.write(字节数据);

接下来,我们实现通过些案例把响应字符数据给实际应用下:

  1. 返回一个图片文件到浏览器
/**
 * 响应字节数据:设置字节数据的响应体
 */
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 读取文件
        FileInputStream fis = new FileInputStream("d://a.jpg");
        //2. 获取response字节输出流
        ServletOutputStream os = response.getOutputStream();
        //3. 完成流的copy
        byte[] buff = new byte[1024];
        int len = 0;
        while ((len = fis.read(buff))!= -1){
            os.write(buff,0,len);
        }
        fis.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}

上述代码中,对于流的copy的代码还是比较复杂的,所以我们可以使用别人提供好的方法来简化代码的开发,具体的步骤是:

(1)pom.xml添加依赖

<dependency>
    <groupId>commons-io</groupId>
    <artifactId>commons-io</artifactId>
    <version>2.6</version>
</dependency>

(2)调用工具类方法

//fis:输入流
//os:输出流
IOUtils.copy(fis,os);

优化后的代码:

/**
 * 响应字节数据:设置字节数据的响应体
 */
@WebServlet("/resp4")
public class ResponseDemo4 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1. 读取文件
        FileInputStream fis = new FileInputStream("d://a.jpg");
        //2. 获取response字节输出流
        ServletOutputStream os = response.getOutputStream();
        //3. 完成流的copy
      	IOUtils.copy(fis,os);
        fis.close();
    }

    @Override
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        this.doGet(request, response);
    }
}
  • 22
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Java三层架构是一种常用的软件架构,通常分为表现层(Presentation Layer)、业务逻辑层(Business Logic Layer)和数据访问层(Data Access Layer)。 在实现增删查改登录注册功能时,可以按照以下步骤进行: 1. 表现层:在表现层中,通常使用Java Web框架(如Spring MVC)进行实现,用于处理用户请求和响应。其中,登录和注册可以使用Java Servlet或者JSP页面实现,而增删查改可以通过RESTful API实现。 2. 业务逻辑层:在业务逻辑层中,通常编写Java代码实现具体的业务逻辑,例如验证用户输入的用户名和密码是否正确,根据用户输入的条件查询数据库等。 3. 数据访问层:在数据访问层中,通常使用ORM框架(如MyBatis)进行实现,用于与数据库进行交互。其中,可以定义DAO接口和Mapper文件实现数据的增删查改操作。 具体实现可以参考以下示例代码: 1. 用户登录 表现层(使用Spring MVC框架): ```java @Controller @RequestMapping("/login") public class LoginController { @Autowired private UserService userService; @PostMapping public String login(@RequestParam String username, @RequestParam String password, HttpSession session) { User user = userService.login(username, password); if (user != null) { session.setAttribute("user", user); return "redirect:/home"; } else { return "redirect:/login?error=1"; } } } ``` 业务逻辑层: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User login(String username, String password) { User user = userMapper.findByUsername(username); if (user != null && user.getPassword().equals(password)) { return user; } else { return null; } } } ``` 数据访问层(使用MyBatis框架): ```java public interface UserMapper { User findByUsername(@Param("username") String username); } ``` 2. 用户注册 表现层(使用Spring MVC框架): ```java @Controller @RequestMapping("/register") public class RegisterController { @Autowired private UserService userService; @PostMapping public String register(@RequestParam String username, @RequestParam String password, HttpSession session) { User user = new User(); user.setUsername(username); user.setPassword(password); boolean success = userService.register(user); if (success) { session.setAttribute("user", user); return "redirect:/home"; } else { return "redirect:/register?error=1"; } } } ``` 业务逻辑层: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public boolean register(User user) { User existUser = userMapper.findByUsername(user.getUsername()); if (existUser != null) { return false; } else { userMapper.insert(user); return true; } } } ``` 数据访问层(使用MyBatis框架): ```java public interface UserMapper { User findByUsername(@Param("username") String username); void insert(User user); } ``` 3. 查询用户 表现层(使用Spring MVC框架): ```java @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") @ResponseBody public User getUser(@PathVariable("id") Long id) { return userService.getById(id); } } ``` 业务逻辑层: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public User getById(Long id) { return userMapper.getById(id); } } ``` 数据访问层(使用MyBatis框架): ```java public interface UserMapper { User getById(@Param("id") Long id); } ``` 4. 更新用户 表现层(使用Spring MVC框架): ```java @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @PutMapping("/{id}") @ResponseBody public boolean updateUser(@PathVariable("id") Long id, @RequestBody User user) { return userService.update(id, user); } } ``` 业务逻辑层: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public boolean update(Long id, User user) { User existUser = userMapper.getById(id); if (existUser == null) { return false; } else { existUser.setUsername(user.getUsername()); existUser.setPassword(user.getPassword()); userMapper.update(existUser); return true; } } } ``` 数据访问层(使用MyBatis框架): ```java public interface UserMapper { User getById(@Param("id") Long id); void update(User user); } ``` 5. 删除用户 表现层(使用Spring MVC框架): ```java @Controller @RequestMapping("/user") public class UserController { @Autowired private UserService userService; @DeleteMapping("/{id}") @ResponseBody public boolean deleteUser(@PathVariable("id") Long id) { return userService.delete(id); } } ``` 业务逻辑层: ```java @Service public class UserServiceImpl implements UserService { @Autowired private UserMapper userMapper; @Override public boolean delete(Long id) { User existUser = userMapper.getById(id); if (existUser == null) { return false; } else { userMapper.delete(id); return true; } } } ``` 数据访问层(使用MyBatis框架): ```java public interface UserMapper { User getById(@Param("id") Long id); void delete(@Param("id") Long id); } ``` 以上示例代码仅为参考,实际实现还需要考虑安全性、异常处理等问题。 ### 回答2: Java三层架构是一种常用的软件开发架构,用于实现将应用程序分为表现层、业务逻辑层和数据访问层三个独立的模块。下面将介绍如何在这个架构下实现增加(Create)、删除(Delete)、查询(Retrieve)和修改(Update)功能以及登录(Login)和注册(Register)功能。 首先,在表现层(Presentation Layer),我们可以使用Java的Swing或JavaFX等界面库来设计用户界面,实现用户的输入与输出。对于登录和注册功能,可以设计登录界面和注册界面,通过用户输入的用户名和密码进行验证。 其次,在业务逻辑层(Business Logic Layer),我们可以编写Java类来处理具体的业务逻辑。针对增删查改功能,我们可以设计一个数据服务类,封装对数据库的操作。例如,对于增加功能,可以编写一个方法,接收用户输入的数据,调用数据访问层的方法将数据插入数据库;对于删除功能,可以编写一个方法,接收用户输入的主键信息,调用数据访问层的方法删除对应的数据;对于查询功能,可以编写一个方法,接收用户输入的查询条件,调用数据访问层的方法从数据库中查询数据;对于修改功能,可以编写一个方法,接收用户输入的修改数据,调用数据访问层的方法更新数据库中的数据。 最后,在数据访问层(Data Access Layer),我们可以使用Java的JDBC或Hibernate等技术与数据库进行交互。可以编写一个持久化类,封装数据库连接、查询、插入、更新和删除等操作的实现。该类可以提供各种与数据库操作相关的方法供业务逻辑层调用。 综上所述,使用Java三层架构可以很好地实现增删查改登录注册功能。通过合理划分不同模块的职责,并灵活运用相关技术,可以使代码结构清晰,逻辑清楚,提高开发效率和代码的可维护性。成功地构建这些功能有助于开发出健壮、可靠的应用程序。 ### 回答3: Java三层架构是一种常用的软件架构模式,将应用程序分为三个独立、可维护和可重用的层次,分别是表示层(展示层)、业务逻辑层和数据访问层。 在增删查改操作中,我们可以将其分别应用于对数据库的操作实现。例如对于登录注册功能,可以进行如下操作: 1. 数据访问层(DAO):该层负责与数据库的交互,执行增删查改的操作。在登录注册功能中,可以通过函数实现用户信息的增加(注册)、删除、查询和修改。对于登录操作,可以提供一个函数,通过用户名和密码查询用户信息是否存在并验证密码是否正确。对于注册操作,可以提供一个函数,将用户信息插入到数据库中。 2. 业务逻辑层(Service):该层负责处理业务逻辑,调用数据访问层进行数据操作。在登录注册功能中,可以在该层进行用户输入的合法性验证,比如判断用户名是否已存在于数据库中。同时,该层也可以处理登录成功后的业务逻辑,比如权限验证、跳转到特定页面等。 3. 表示层(Presentation):该层负责与用户进行交互,接收用户的请求并展示处理结果。在登录注册功能中,可以通过页面设计提供用户输入框和按钮,用户通过填写用户名和密码进行登录或注册操作。同时,该层还需要将用户输入的信息传递给业务逻辑层进行处理,并将处理结果以页面或其他方式反馈给用户。 以上是一种基本的Java三层架构设计思路,通过将不同的功能完成在不同的层级中,使得代码更加清晰、易于维护和扩展。在实际开发中,我们可以通过框架如Spring MVC来实现三层架构,简化开发流程,提高开发效率。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值