栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

DAO的内容

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

DAO的内容

1.dao定义

DAO (DataAccessobjects 数据存取对象)
是指位于业务逻辑和持久化数据之间实现对持久化数据的访问。
通俗来讲,就是将数据库操作都封装起来。

2.dao组成部分

  1. DAO接口:
    把对数据库的所有操作定义成抽象方法,可以提供多种实现。
  2. DAO 实现类:
    针对不同数据库给出DAO接口定义方法的具体实现。
  3. 实体类:用于存放与传输对象数据。
  4. 数据库连接和关闭工具类:
    避免了数据库连接和关闭代码的重复使用,方便修改。

3.baseDao工具类

package cn.kgc.util;
import java.sql.*;

//连接数据库的工具类
public class baseDao {
//    1.定义连接对象
    protected static Connection conn;
//    2.定义预编译对象
    protected static PreparedStatement ps;
//    3.定义结果集对象
    protected static ResultSet rs;

//    4.定义连接数据库的方法getConn()
    public static void getConn(){
        try {
//            5.注册驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
//            6.管理连接
            conn = DriverManager.getConnection
                    ("jdbc:mysql://localhost:3306/test?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&rewriteBatchedStatements=true",
                            "root","zjj");
//            7.测试连接对象
            System.out.println(conn);
        } catch (ClassNotFoundException | SQLException e) {e.printStackTrace();}
    }

//8.定义关闭连接数据库方法closeAll()
    public static void closeAll(){
        try {
//            9.关闭结果集对象
            if(rs!=null){rs.close();}
//            10.关闭预编译对象
            if(ps!=null){ps.close();}
//            11.关闭连接对象
            if(conn!=null){conn.close();}
        } catch (SQLException e) {e.printStackTrace();}
    }

//12.定义增删改的通用方法executeUpdate()
    public int executeUpdate(String sql,Object[] params){
        int flag = 0;
//        13.调用连接数据库的方法
        getConn();
        try {
//            14.调用prepareStatement(),发送sql语句给数据库
            ps = conn.prepareStatement(sql);
            if(params!=null){
//                15.循环将方法中的参数塞入结果集中
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i+1,params[i]);
                }
            }
//            16.执行处理(增删改)的方法
            flag = ps.executeUpdate();
            //当成功插入数据到数据库时候,这个会返回一个大于1的数字,来表明数据成功插入库之中
        } catch (SQLException e) {
            e.printStackTrace();
        } finally{
            closeAll();
        }
        return flag;
    }
//    17.定义通用的查询方法executeQuery()
public ResultSet executeQuery(String sql, Object[] params){
//Object[] params==》动态的传递参数
//        18.连接数据库
        getConn();
        try {
//            19.执行prepareStatement() 发送sql语句到数据库
            ps = conn.prepareStatement(sql);
            if(params!=null){
//                20.循环遍历参数,将参数塞入结果集中(所谓的?)
                for (int i = 0; i < params.length; i++) {
                    ps.setObject(i+1,params[i]);
                }
            }
//            21.执行处理(查询)的方法
            rs = ps.executeQuery();
        } catch (SQLException e) {
            e.printStackTrace();
        }
        //查询不能在里面调用closeAll 不然会报错 结果集一旦关闭了,后面就返回不了了 所以只能在findAll里面调
        return rs;
    }
//    入口函数的测试
    public static void main(String[] args) {getConn(); }
}

4.mvc(框架)

M是指业务模型,V是指用户界面,C则是控制器,
使用MVC的目的是将M和V的实现代码分离。

5.dao综合实战(servlet+dao+jsp)
(1)创建工程(web)

创建包(entity,util,dao,test,service,servlet)

util可以放在dao包里,最好还是区分。


(2)导入jar包

javax.servlet.jar,
jstl.jar,
mysql-connector-java-8.0.16.jar,
servlet-api.jar,
standard.jar

(3)创建数据库

(4) cn.kgc.entity/User

import java.io.Serializable;
public class User implements Serializable{
//告诉我们是个特殊的类  Serializable类里什么都没有
//Serializable接口是一个标记接口
    private Integer id;
    private String name;
    private String pwd;
//定义变量的getset方法
//定义类的无参构造,有参构造和name、pwd的有参构造。
}

什么是Serializable接口?
一个对象序列化的接口,
一个类只有实现了Serializable接口,
它的对象才能被序列化。

什么是序列化?

序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。

(5) cn.kgc.util/baseDao

导入baseDao并测试(有地址)就代表测试成功

com.mysql.cj.jdbc.ConnectionImpl@xxxx

(6) cn.kgc.dao
A. cn.kgc.dao/UserDao

package cn.kgc.dao;
import cn.kgc.entity.User;
import java.util.List;

public interface UserDao {
    //1.添加功能
    Integer addUser(User user);//alt 回车 导包
    //2.查询所有
    List findAll();
    //3.删除功能
    Integer delById(Integer id);
    //4.查询对象功能
    User findById(Integer id);
    //5.修改功能
    Integer updateUser(User user);
    //6. 模糊查询
	List findByName(String name);
	//7.登录功能
	User login(String name,String pwd);
}

B. cn.kgc.dao/UserDaoImpl

package cn.kgc.dao;
import cn.kgc.dao.UserDao;
import cn.kgc.entity.User;
import cn.kgc.util.baseDao;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
//UserDaoImpl是UserDao的实现类
public class UserDaoImpl extends baseDao implements UserDao {
    //添加功能
    @Override
    public Integer addUser(User user) {//封装起来
        String sql = "insert into t_user(`name`,pwd) values(?,?)";
        //传参
        Object[] params = new Object[]{user.getName(),user.getPwd()}; 
        //传参
        return super.executeUpdate(sql,params);
        //==>baseDao.executeUpdate
    }

    //查询所有
    @Override
    public List findAll() {
        ArrayList list = new ArrayList<>();
        String sql = "select * from t_user";
        Object[] params = null;
        rs = super.executeQuery(sql,params);
//        可以直接写 null 查询所有      
		//rs = super.executeQuery(sql,null);
        User user = null;
        try {
            while(rs.next()){
                user = new User(rs.getInt("id"),rs.getString("name"),rs.getString("pwd"));
                list.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            super.closeAll();
        }
        return list;
    }

    //删除功能
    @Override
    public Integer delById(Integer id) {
        String sql = "delete from t_user where id = ?";
        Object[] params = new Object[]{id};
        return super.executeUpdate(sql,params);
    }

    //查询对象功能
    @Override
    public User findById(Integer id) {
        User user = null;
        String sql="select * from t_user where id = ?";
        Object[] params = new Object[]{id};
        rs = super.executeQuery(sql,params);
        try {
            while (rs.next()){
                user = new User(rs.getInt("id"),rs.getString("name"),rs.getString("pwd"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            super.closeAll();
        }
        return user;
    }
//    return语句总是用在方法中,有两个作用,一个是返回方法指定类型的值
//   (这个值总是确定的),一个是结束方法的执行(仅仅一个return语句)。

    @Override
    public Integer updateUser(User user) {
        String sql = "update t_user set `name` = ?,pwd = ? where id = ?";
        Object[] params = new Object[]{user.getName(),user.getId(),user.getId()};
        return super.executeUpdate(sql,params);
    }
//"".equals(name) 和name.equals("") 的区别
//    两个都是比较“”的地址和name的地址是否指向同一个地址,即判断name是否为“”,
//    建议用前者,因为name可能是null,此时name.equals("")就会报错,而前者则会避免这个问题
//    避免了抛出空指针异常NullPointerException。

    @Override
    public List findByName(String name) {
        //        实例化list集合
        ArrayList list = new ArrayList<>();
//        由于StringBuffer可以修改字符串 所以将sql语句拼接到sql字符串中
        StringBuffer sql = new StringBuffer("select * from t_user where 1 = 1");
//        where 1=1 是为了避免where 关键字后面的第一个词直接就是 “and”而导致语法错误。
        if( !"".equals(name) && name !=null){
//            搜索栏不为空
            sql.append("    and  name like concat('%',?,'%')");
            //--->拼接的结果是select * from t_user where 1 = 1 and name like XXX
            Object[] params = new Object[]{name};
            rs = super.executeQuery(sql.toString(),params);
//        使用StringBuffer的toString()方法,可以将StringBuffer转换成String
        }
//         写where 1 = 1  如下原因,用密码来进行 搜索
//        else if(!"".equals(pwd) && pwd !=null){
        //假设密码也不为空
//            sql.append("    and  name like concat('%',?,'%')");
//      --->拼接的结果是select * from t_user and pwd like XXX
//        }

		else{
            rs = super.executeQuery(sql.toString(),null);
        }
        User user = null;        
		try {
            while (rs.next()){
                user = new User(rs.getInt("id"),rs.getString("name"),rs.getString("pwd"));
                list.add(user);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            super.closeAll();
        }
        return list;
    }
//    复制一遍,都是返回值一样  public User findById(Integer id)
@Override
    public User login(String name, String pwd) {
        String sql = "select * from t_user where name = ? and pwd = ?";
        Object[] params = new Object[]{name,pwd};
        rs = super.executeQuery(sql,params);
        User user = null;
        try {
            while (rs.next()){
                user = new User(rs.getInt("id"),rs.getString("name"),rs.getString("pwd"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            super.closeAll();
        }
        return user;
	}
}

String和StringBuffer拼接字符串的区别:(摘录)
String是final修饰的,不可以继承这个类、不能修改这个类
String类每次修改字符串,就会创建一个新的对象。
如果代码中有很多的”+”,就会每个”+”生成一次对象,
这种方式对内存是一种浪费,效率很不好。

为了提高效率节省空间,我们应该用StringBuffer类 。
StringBuffer拼接是直接在本身拼接,会即时刷新。
它是在底层维护了个char数组,每次append的时候就往char数组里放字符,
最终sb.toString()的时候,
用new String()方法把char数组里的内容都转成String,
这样,整个过程中只产生了一个StringBuilder对象与一个String对象,
非常节省空间。

StringBuffer和StringBuilder用法一模一样,
唯一的区别只是StringBuffer是线程安全的,它对所有方法都做了同步,
StringBuilder是线程非安全的,所以在不涉及线程安全的场景,
比如方法内部,尽量使用StringBuilder,避免同步带来的消耗。

(7) cn.kgc.test/UserDaoImplTest(可省略)

package cn.kgc.test;
import cn.kgc.entity.User;
import cn.kgc.dao.UserDaoImpl;
import org.junit.Test;


public class UserDaoImplTest {
    @Test//Test 就不用写main 可以测试多个
    public void testaddUser(){//测试一个 --> 增加方法
//      迭代测试(一步一步测试)
        UserDaoImpl userDao = new UserDaoImpl();
        User user = new User("asdf ","123");
//		id 主键 自增长
        userDao.addUser(user);
    }
}

(8)service

A. cn.kgc.service/UserService

package cn.kgc.service;
import cn.kgc.entity.User;
import java.util.List;

//中间层 Service
public interface UserService {
    //1.添加功能
    public  Integer addUser(User user);
    //2.查询所有
    public List findAll();
    //3.删除功能
    Integer delById(Integer id);
    //4.查询对象功能
    User findById(Integer id);
    //5.修改功能
    Integer updateUser(User user);
    //6. 模糊查询
	List findByName(String name);
	//7.登录功能
	User login(String name, String pwd);
}

B.service/UserServiceImpl

package cn.kgc.service;
import cn.kgc.dao.UserDao;
import cn.kgc.dao.UserDaoImpl;
import cn.kgc.entity.User;
import java.util.List;
//service调dao 所以一定要定义个dao
public class UserServiceImpl implements UserService {

private UserDao userDao = new UserDaoImpl();
//多态  父类的引用指向子类的对象
    @Override
    public Integer addUser(User user) {return userDao.addUser(user);}

    @Override
    public List findAll() {return userDao.findAll();}

    @Override
    public Integer delById(Integer id) {return userDao.delById(id);}

    @Override
    public User findById(Integer id) {return userDao.findById(id);}

    @Override
    public Integer updateUser(User user) {return userDao.updateUser(user);}

    @Override
    public List findByName(String name) {return userDao.findByName(name);}

	@Override
    public User login(String name, String pwd) {return userDao.login(name,pwd);
    }
}

(9)cn.kgc.servlet/UserServlet

A.UserServlet

package cn.kgc.servlet;
import cn.kgc.entity.User;
import cn.kgc.service.*; 
import javax.servlet.*;
import java.io.IOException;
import java.util.List;

public class UserServlet extends HttpServlet {
    protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        //1.给request对象,response对象设置中文字符集
        request.setCharacterEncoding("utf-8");
        response.setContentType("text/html;charset=utf-8");

        //2.获取请求 URL 后的参数(标识位)
        String action = request.getParameter("action");
        if(action.equals("toAdd")){
            //分支:跳转到添加页面
            //通过后台访问jsp
            request.getRequestDispatcher("add.jsp").forward(request,response);
        }else if(action.equals("add")){
            //分支:执行添加方法
            //1.从页面add.jsp获取两个参数name,pwd
            String name = request.getParameter("name");
            String pwd = request.getParameter("pwd");
            //2.实例化UserService对象
            UserService userService = new UserServiceImpl();
            //Servlet 调 Service, Service调 dao 一层一层递进。
            //3.实例化User对象
            User user = new User(name, pwd);
            //4.调用userServlet的添加方法,并判断,如果增加成功则跳转到index.jsp页面
            int flag = userService.addUser(user);
            if(flag>0){
                request.getRequestDispatcher("/UserServlet?action=listAll").forward(request,response);
            //不能写list.jsp 不然会没有数据 报错
            }
        }
//        else if(action.equals("list")){
//            UserService userService = new UserServiceImpl();
//            List list = userService.findAll();
//            将从数据库中查询出的list列表绑定到request请求域中啊
//            request.setAttribute("list",list);
//            request.getRequestDispatcher("list.jsp").forward(request,response);
//        }

//				list和下面的findByName合并成listAll

else if(action.equals("delById")){
//            从前端获取request请求域后的参数id对应的值
//            ?action=toUpdate&id=${user.id}后 id对应的value值 存储在idStr字符串中
            String idStr = request.getParameter("id");
//            实例化UserService对象
            UserService userService = new UserServiceImpl();
//            调用userService对象的delById()方法,执行删除功能,将返回值存储在flag变量中
            int flag = userService.delById(Integer.parseInt(idStr));
//判断如果flag大于0,则说明删除成功,则转发请求到后台列表的页面(后端请求):
//注意:不要直接转发到list.jsp,因为list.jsp有jstl,el表达式,需要通过后端才能访问list.jsp页面
            if(flag > 0){
                request.getRequestDispatcher("/UserServlet?action=listAll").forward(request,response);
//flag是成功了几条,就返回数字几
            }
        }else if(action.equals("findById")){
//            从前端获取request请求域后的参数id对应的值
//            ?action=findById&id=${user.id}"中的&后的id=后对应的value值 存储在idStr字符串中
            String idStr = request.getParameter("id");
            UserService userService = new UserServiceImpl();
//            调用userService对象的findById()方法,返回值存储在user对象中
            User user = userService.findById(Integer.parseInt(idStr));
//            绑定user对象到request请求域中
            request.setAttribute("user",user);//绑定值
//            转发到findById.jsp详情页面
            request.getSession().getAttribute("userSession");

request.getRequestDispatcher("findById.jsp").forward(request,response);

        }else if (action.equals("toUpdate")){
            String idStr = request.getParameter("id");
            UserService userService = new UserServiceImpl();
            User user = userService.findById(Integer.parseInt(idStr));
            request.setAttribute("user",user);
            request.getRequestDispatcher("update.jsp").forward(request,response);
        }else if(action.equals("update")){
//            获取update.jsp中表单中name对应的id对应的value值 存储在idStr字符串中
            String idStr = request.getParameter("id");
            String name = request.getParameter("name");
            String pwd = request.getParameter("pwd");
            UserService userService = new UserServiceImpl();
//            实例化User对象(加入从update.jsp页面中获取的三个参数)
            User user = new User(Integer.parseInt(idStr),name,pwd);
            int flag = userService.updateUser(user);
//          如果flag大于0,则说明修改成功,则转发到列表页面(通过后端请求转发到前端页面xxx.jsp)
            if(flag > 0){
                request.getRequestDispatcher("/UserServlet?action=listAll").forward(request,response);
            }

        }
//        else if (action.equals("findByName")){
//          获取list.jsp中从form表单中name属性对应的name对应的value值 存储到name变量中
//            String name = request.getParameter("name");
//            UserService userService = new UserServiceImpl();
//            调用userService对象的findByName()方法,返回值存储在list集合中
//            List list = userService.findByName(name);
//            绑定list集合到request域中的list对应的value中
//            request.setAttribute("list",list);
//            request.getRequestDispatcher("list.jsp").forward(request,response);
//        }
		else if(action.equals("listAll")){
            String name = request.getParameter("nameMsg");//nameMsg
            UserService userService = new UserServiceImpl();
            List list = userService.findByName(name);
            request.setAttribute("list",list);

            request.getSession().getAttribute("userSession");

            request.getRequestDispatcher("list.jsp").forward(request,response);
        }else if (action.equals("toLogin")){
            request.getRequestDispatcher("login.jsp").forward(request,response);
        }else if (action.equals("login")){
            String name = request.getParameter("name");
            String pwd = request.getParameter("pwd");
            UserService userService = new UserServiceImpl();
            User user = userService.login(name, pwd);
            if (!"".equals(user) && user!= null){
                //不为空字符串 如果以后返回值是字符串就有用,现在放在这没用 和不为空对象

                request.getSession().setAttribute("userSession",user);
//              request.getSession().setAttribute(“绑定名”,绑定值);
//              这段代码的意思就是:获取session对象,session只能在jsp中使用,所以要这样,然后把要绑定对象/值绑定到session对象上
//                request.setAttribute这个的生命周期就是request级别的
//                在一次请求的全过程中有效
//                request.getSession().setAttribute这个的生命周期是session级别的
//                用户全局变量,在整个会话期间都有效(只要页面不关闭就一直有效)
                //有session最好用重定向

                request.getRequestDispatcher("UserServlet?action=listAll").forward(request,response);
            }else{
                response.getWriter().println("");
//                可以输出html类型的标签,还可以输出一个对象
            }
        }else if (action.equals("toRegister")){
            request.getRequestDispatcher("register.jsp").forward(request,response);
        }else if (action.equals("register")){
            String name = request.getParameter("name");
            String pwd = request.getParameter("pwd");
            UserService userService = new UserServiceImpl();
            User user = userService.login(name, pwd);
            if (user!=null){
                response.getWriter().println("");
//          response.getwriter().println()可以输出html类型的标签,还可以输出一个对象。
            }else {
                User uu = new User(name,pwd);
                int flag = userService.addUser(uu);
                if (flag>0){
                    response.sendRedirect("UserServlet?action=toLogin");
                }else{
                    response.getWriter().println("");
                }
            }
        }
    }
}

B.web.xml

    
        UserServlet
        cn.kgc.servlet.UserServlet
    
    
        UserServlet
        /UserServlet


        index.jsp
    

(10)jsp

A.list.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


<%-- 只能写一个?其他用&代替--%>
欢迎您,${userSession.name}
<%-- colspan属性规定单元格可横跨的列数--%> <%-- rowspan属性规定单元格可横跨的列数--%>
用户id 用户名称 用户密码 操作
${user.id} ${user.name} ${user.pwd} 修改 删除


B.add.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


添加页面
用户名称:
用户密码:


C.update.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


修改页面
用户名称:
用户密码:


D.findById.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


详情页面
欢迎您,${userSession.name}
用户id:
用户名称:
用户密码:


E.login.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


登录页面
用户名称:
用户密码:


F.index.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>

  
    $Title$
    
<%--    当你打开localhost:8080时,会弹出login.jsp页面--%>
  
  
  


G.register.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>


    Title


注册页面
用户名称:
用户密码:


最终展示页面:
数据库

打开Web,输入http://localhost:8080
实际跳转到
(http://localhost:8080/UserServlet?action=toLogin)

如果没有,会报错,输出 您输入的用户名或者密码错误
如果选择注册,会跳到注册页面
http://localhost:8080/UserServlet?action=toRegister

接着上面的,点击登录,会跳到
http://localhost:8080/UserServlet?action=login

输入内容,然后点击搜索kl,会跳到
http://localhost:8080/UserServlet?action=listAll

点击添加,会跳到
http://localhost:8080/UserServlet?action=toAdd
点击用户1,会跳到
http://localhost:8080/UserServlet?action=findById&id=1

点击修改
http://localhost:8080/UserServlet?action=toUpdate&id=1

点击删除,会直接删掉。

题外话:
java虚拟机调优
idea
== > idea64.exe.vmoptions
-Xms128m
-Xmx750m

内存大的话 可以改成 2048 两个G

前端页面 后端页面
前端页面:门户网站
比如淘宝最开始的,不用输入账户也能浏览

后端页面
比如输入一个账户就能访问所有的内容

优化Java虚拟机总结(摘录)
https://www.jb51.net/article/132029.htm

表单内容:
submit() 方法把表单数据提交到 Web 服务器。
action 属性: 规定当提交表单时,向何处发送表单数据。

decimal类型(sql):
decimal类型在java中的用BigDecimal类型表示的。
decimal(10,3)表示共有7位整数3位小数,此例的精确度为10位。
BigDecimal:不可变的、任意精度的有符号十进制数。
String转换成BigDecimal类型==》
String price = request.getParameter(“price”);
BigDecimal bd=new BigDecimal(price);

数据库的大小写 不区分大小写

设置编码格式:
request.setCharacterEncoding(“utf-8”);
response.setContentType(“text/html;charset=utf-8”);

----2021.10.22&10.23&10.27 &10.28

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/358536.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号