JavaWeb的Cookie和Session

package study.web.cookie;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.*;
import java.io.IOException;

@WebServlet("/cookie/demo01")
public class demo01 extends HttpServlet {
    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {


    }

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

    /**
     * 客户端会话技术:Cookie
     * 实现原理:
     *      基于响应头set-cookie和请求头cookie实现
     * Cookie的特点和作用:
     *      cookie存储数据在客户端浏览器
     *      浏览器对于单个 cookie 的大小有限制在 4kb 以内, 对同一个域名下的总cookie数量也有限制(20个)
     * Cookie默认关闭客户端后失效
     * @param request
     * @param response
     */
    public static void CookieDemo(HttpServletRequest request, HttpServletResponse response) {
        //创建Cookie对象
        Cookie c = new Cookie("msg", "hello Cookie");

        //设置Cookie作用域范围(将作用域设置为根路径,同一个服务器的多个项目可以共享cookie)
        //该设置项默认为当前项目的作用域
        c.setPath("/");
        //设置Cookie过期时间
        //设置正数 表示x秒后过期
        //设置0,表示立即过期
        c.setMaxAge(300);
        //设置cookie的域名作用域(将作用域设置为域名,多个子域名可以共享cookie)
        //c.setDomain();
        //发送Cookie
        response.addCookie(c);

        //获取Cookie
        Cookie[] cook = request.getCookies();
        //获取数据,遍历Cookies
        if(cook != null){
            for (Cookie cs : cook) {
                String name = cs.getName();
                String value = cs.getValue();
                System.out.println(name+":"+value);
            }
        }
    }

    /**
     * 服务器端会话技术:Session
     * 实现原理:
     *      Session的实现是依赖于Cookie的。
     *  问题:
     *      当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
     *          默认情况下。不是。
     *          如果需要相同,则可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存。
     *
     *  当客户端关闭后,服务器不关闭,两次获取session是否为同一个?
     *             默认情况下。不是。
     *             如果需要相同,可以创建Cookie,键为JSESSIONID,设置最大存活时间,让cookie持久化保存
     *
     *  Session什么时候失效:
     *      服务器关闭
     *      调用session.invalidate()方法
     *      默认30分钟失效
     * @param request
     * @param response
     */
    public static void SessionDemo(HttpServletRequest request, HttpServletResponse response) {
        //使用Session共享数据

        //获取session
        HttpSession session = request.getSession();
        //存储数据
        session.setAttribute("msg","hello Session");

        //获取数据
        session.getAttribute("msg");

        //删除数据
        session.removeAttribute("msg");

        //期望客户端关闭后 session也能相同(持久化)
        Cookie c = new Cookie("JSESSINOID", session.getId());
        c.setMaxAge(60 * 60);//一小时
        //发送cookie
        response.addCookie(c);



    }
}

JavaWeb之getServletContext对象和文件下载

package study.web.response;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.util.Base64;


@WebServlet("/response/demo3")
public class Demo03 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        /**
         * ServletContext对象获取
         * 两种方式:
         *      通过request对象获取:
         *          ServletContext contentxt1 = req.getServletContext();
         *
         *      通过HttpServlet获取:
         *          ServletContext contentxt2 = this.getServletContext();
         *
         */

        /**
         * 获取文件的mime类型
         *  String file1 = "1.jpg";
         *  String mi = this.getServletContext().getMimeType(file1);
         *  System.out.println(mi);
         */


        //下载文件

        //文件名称
        String f1 = "052700005E68762CADA7B24DE20D3169.jfif";
        String f2 = "mda-ijpq9sxmv0ucizic.mp4";
        String f3= "绣春刀.mp4";

        try {
            download(req,resp,f3);
        } catch (Exception e) {
            e.printStackTrace();
        }

    }


    /**
     * 下载文件
     * @param req 请求对象
     * @param resp 响应对象
     * @param file 下载文件名称
     * @throws Exception
     */
    public void download(HttpServletRequest req, HttpServletResponse resp,String file) throws Exception {

        //1、使用字节输入流加载文件进内存
        //找到文件
        ServletContext context = this.getServletContext();
//        String realPath = context.getRealPath("C:\\Users\\admin\\Pictures\\" + file);

        File realPath = new File("C:\\Users\\admin\\Pictures\\" + file);
        System.out.println("C:\\Users\\admin\\Pictures\\" + file);


        //读取文件流
        FileInputStream fis = new FileInputStream(realPath);



        //设置响应header 的mime #响应的文件类型通过 getServletContext 获取
        resp.setContentType(context.getMimeType(file));

        //解决中文文件名称乱码的问题
        String agent = req.getHeader("user-agent");
        String filename = getFileName(agent, file);
        //设置响应保持的文件名称
        resp.setHeader("content-disposition","sttachment;filename="+filename);

        //将文件流写入到输出流中
        ServletOutputStream sos = resp.getOutputStream();
        byte[] buff = new byte[1024 * 8];
        int len = 0;
        while ((len = fis.read(buff)) != -1){
            sos.write(buff,0,len);
        }


    }

    /**
     * 解决文件名称中文乱码的问题
     * @param agent
     * @param filename
     * @return
     * @throws Exception
     */
    public static String getFileName(String agent, String filename) throws Exception {
        if (agent.contains("MSIE")) {
            // IE浏览器
            filename = URLEncoder.encode(filename, "utf-8");
            filename = filename.replace("+", " ");
        } else if (agent.contains("Firefox")) {
            // 火狐浏览器
            Base64.Encoder encoder = Base64.getEncoder();
            filename = "=?utf-8?B?" + encoder.encodeToString(filename.getBytes("utf-8")) + "?=";
        } else {
            // 其它浏览器
            filename = URLEncoder.encode(filename, "utf-8");
        }
        return filename;
    }
}

Java文件下载.png

NOTE:

  1. 获取文件的mime类型
  2. 文件流读取和输出
  3. 文件下载和中文名称乱码

JavaWeb之Response对象的基本操作和验证码

该对象和request都是由Tomcat创建

package study.web.response;

import javax.imageio.ImageIO;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.Random;

@WebServlet("/response/demo1")
public class Demo01 extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("demo1 ... get ...");
        /**
         * 重定向的两种方式:
         * 1、
         *  resp.setStatus(302);
         *  resp.setHeader("location","/WebServletDemo_war_exploded/response/demo2");
         *
         *  2、
         *  resp.sendRedirect("/WebServletDemo_war_exploded/response/demo2");
         */

        /**
         * 设置响应编码的两种方式:
         *
         * 1、
         * resp.setHeader("Content-Type","text/html;charset=utf-8");
         * 2、
         * resp.setContentType("text/html;charset=utf-8");
         */


        /**
         * 输出字符数据:
         * resp.getWriter().write("<h1>Hello Response! 你好,Response!</h1>");;
         */

        /**
         * 输出字节数据:
         * ServletOutputStream sos = resp.getOutputStream();
         * sos.write("你好".getBytes());
         */

        //验证码
        verification(resp);

    }

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


    /**
     * 验证码
     * @param resp
     */
    private static void verification(HttpServletResponse resp)
    {
        //创建图像
        int width = 100;
        int height = 50;
        BufferedImage image = new BufferedImage(width,height,BufferedImage.TYPE_INT_RGB);

        //美化图片
        Graphics g = image.getGraphics();//画笔对象
        g.setColor(Color.PINK);//设置画笔颜色
        g.fillRect(0,0,width,height);//填充

        //画边框
        g.setColor(Color.BLACK);
        g.drawRect(0,0,width,height);

        //验证码随机数
        String str = "AAZWSXEDCRFVTGBYHNUJMIKLOPqazwsxedcrfvtgbyhnujmiklop1234567890";
        Random ran = new Random();

        String code = "";
        for (int i = 1; i < 5;i++) {
            //获取字符串
            int index = ran.nextInt(str.length());
            char ch = str.charAt(index);//随机字符串

            //写验证码
            g.drawString(ch + "",width / 5 * i,height / 2);
            code = code + ch;
        }
        //画干扰线
        g.setColor(Color.GREEN);

        for (int i = 0; i< 10; i++) {
            //生成随机坐标点
            int x1 = ran.nextInt(width);
            int x2 = ran.nextInt(width);

            int y1 = ran.nextInt(height);
            int y2 = ran.nextInt(height);

            g.drawLine(x1,y1,x2,y2);
        }


        //输出图像
        try {
            System.out.println("验证码是:"+ code);
            ImageIO.write(image,"jpg",resp.getOutputStream());//ImageIO 输出文件对象
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

验证码:
屏幕截图 2021-01-19 155739.png

Servlet和HttpServer

Servlet 是Java Web开发中重要的一个类
该类是一个接口,使用 Servlet 需要实现其中的方法

package study.demo.web;

import javax.servlet.*;
import java.io.IOException;

/**
 * Servlet 是一个接口
 * 使用 Servlet 需要实现其中的方法
 */
public class Servers implements Servlet {

    /**
     * 初始化方法
     * 该方法 在Servlet被创建时执行 只会执行一次
     * 该方法可以指定创建时间:
     * 在 web.xml 中 <servlet>标签下 创建 <load-on-startup> 标签
     *  该标签的值为负数 表示 在第一次访问时创建
     *  该标签的值为正数 表示 在服务器启动后创建
     *
     *  注意:Servlet对象是单例模式,多个用户访问时可能会造成线程安全问题
     *  解决:尽量不要在Servlet中操作成员变量
     * @param servletConfig
     * @throws ServletException
     */
    @Override
    public void init(ServletConfig servletConfig) throws ServletException {
        System.out.println("init 执行成功");
    }

    /**
     * 获取ServletConfig对象
     * @return
     */
    @Override
    public ServletConfig getServletConfig() {
        return null;
    }

    /**
     * Servlet 入口方法
     * 每一次Servlet被执行时 都会执行
     * @param servletRequest
     * @param servletResponse
     * @throws ServletException
     * @throws IOException
     */
    @Override
    public void service(ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException {
        System.out.println("我是Servlet的入口方法");
    }

    /**
     * 获取Servlet的一些信息:版本、作者等等
     * @return
     */
    @Override
    public String getServletInfo() {
        return null;
    }

    /**
     * 销毁方法
     * 在服务器正常关闭时执行一次
     */
    @Override
    public void destroy() {
        System.out.println("Servlet 关闭了");
    }
}

根据web.xml配置的访问路径,可以对请求地址进行自定义

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <!--servlet的路径-->
    <servlet>
        <servlet-name>demo1</servlet-name>
        <servlet-class>study.demo.web.Servers</servlet-class>
    </servlet>
    <!--servlet访问的地址-->
    <servlet-mapping>
        <servlet-name>demo1</servlet-name>
        <url-pattern>/demo1</url-pattern>
    </servlet-mapping>
</web-app>

以上是使用Servlet的方法
但实际中一般使用Servlet的子类:HttpServlet

HttpServlet类继承自Servlet 并且重新了Servlet类的方法
并且 HttpServlet 封装了 HttpServletRequest类和HttpServletResponse类

package study.web.day01;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

/**
 * 通过注解 代替web.xml配置路由
 * @WebServlet() 该注解支持层级目录和通配目录
 * @WebServlet("/xxx/xxx") : 多层级目录
 * @WebServlet("/xxx/*")   :多层级目录,并且文件名可以匹配所有
 * @WebServlet("*.访问后缀") :匹配所有输入的路径,但是后缀需要定义,并且访问时需要匹配后缀
 */
@WebServlet("/demo1")
public class HttpServer extends HttpServlet {
    
    /**
     *
     * @param req HttpServletRequest 请求对象
     * @param resp HttpServletResponse 相应对象
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("get...");
    }

    /**
     *
     * @param req HttpServletRequest 请求对象
     * @param resp HttpServletResponse 相应对象
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        System.out.println("post...");
    }

    /**
     * 
     * @param req
     * @param resp
     * @throws ServletException
     * @throws IOException
     */
    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
    }
}

JdbcTemplate

JdbcTemplate是Spring框架对JDBC的封装

package study.jdbctemplate;

import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.RowMapper;
import study.datasoure.Druid;
import study.jdbc.Emp;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Date;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.List;
import java.util.Map;
import java.util.Properties;

/**
 * JdbcTemplae 是spring 框架的jdbc封装工具对象
 *
 * 使用步骤:
 * 1、导包
 * 2、创建JdbcTemlplate对象
 * 3、操作数据库
 */
public class JdbcTemplateDemo {
    public static void main(String[] args) throws Exception {
        //1、创建JdbcTemlplate对象
        JdbcTemplate jt = new JdbcTemplate(getConn());
        //2、调用方法

        //更新数据库
        String up = "update emp set mgr = ? where id = ?";
        //update(sql,参数1,参数2,...)
        int update = jt.update(up, 100, 1002);
        System.out.println(update);//1


        //查询数据库
        // queryForMap() 方法查询的结果集长度只能是1条
        String se = "select * from emp where id = ?";
        Map<String, Object> smap = jt.queryForMap(se, 1002);
        System.out.println(smap.get("ename"));

        // queryForList() 方法查询的结果集长度可以是多条数据
        String se1 = "select * from emp where id in (?,?)";
        List<Map<String, Object>> maps = jt.queryForList(se1, 1002, 1003);
        System.out.println(maps);

        //查询所有记录
        //query() 方法接受2个参数 ,将查询的结果封装为指定的对象
        String se2 = "select * from emp";
        //自定义实现数据封装对象
        /*List<Emp> query = jt.query(se2, new RowMapper<Emp>() {
            @Override
            public Emp mapRow(ResultSet res, int i) throws SQLException {
                Emp emp = new Emp();
                int id = res.getInt("id");
                String ename = res.getString("ename");
                int job_id = res.getInt("job_id");
                int mgr = res.getInt("mgr");
                Date joindate = res.getDate("joindate");
                double salary = res.getDouble("salary");
                double bonus = res.getDouble("bonus");
                int dept_id = res.getInt("dept_id");

                emp.setId(id);
                emp.setEname(ename);
                emp.setJob_id(job_id);
                emp.setMgr(mgr);
                emp.setJoindate(joindate);
                emp.setSalary(salary);
                emp.setBonus(bonus);
                emp.setDept_id(dept_id);
            }
        });*/
        //也可以使用 预定义的封装
        //BeanPropertyRowMapper(sql,new BeanPropertyRowMapper<类型>(类型.class))
        List<Emp> query = jt.query(se2, new BeanPropertyRowMapper<Emp>(Emp.class));
        System.out.println(query);

        //查询总记录数
        //queryForObject(sql,object.class) 该方法一般执行聚合查询
        String se3 = "select count(id) from emp";
        Object o = jt.queryForObject(se3,Long.class);
        System.out.println(o);


    }

    /**
     * 获取 Druid 连接池对象
     * @return
     * @throws Exception
     */
    public static DataSource getConn() throws Exception {
        Properties pro = new Properties();
        InputStream is = Druid.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);

        return ds;
    }
}

数据库连接池Druid

package study.datasoure;

import com.alibaba.druid.pool.DruidDataSourceFactory;

import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;

/**
 * 步骤:
 * 1、导入jar包:druid-1.0.9.jar
 * 2、定义配置文件:
 *      properties 形式的配置文件
 *      配置文件可以是任意名称,可以放在任意目录下
 * 3、获取数据库连接池对象:
 *    通过工厂类来获取:DruidDataSorceFactory
 * 4、获取连接:
 *    getConnection()
 *
 * 5、操作数据库
 *
 */
public class Druid {
    public static void main(String[] args) throws Exception {
        //1、获取连接池对象
        Properties pro = new Properties();
        InputStream is = Druid.class.getClassLoader().getResourceAsStream("druid.properties");
        pro.load(is);
        DataSource ds = DruidDataSourceFactory.createDataSource(pro);
        //2、获取连对象
        Connection conn = ds.getConnection();

        //3、使用
        //定义查询语句 使用?占位符
        String select = "select * from emp where id = ?";

        //获取执行SQL对象
        PreparedStatement pstm = conn.prepareStatement(select);
        //占位符参数
        pstm.setInt(1,1002);
        //执行查询语句
        ResultSet res = pstm.executeQuery();

        while (res.next()){
            System.out.println(res.getInt("id"));
            System.out.println(res.getString("ename"));
            System.out.println(res.getInt("job_id"));
            System.out.println(res.getInt("mgr"));
            System.out.println(res.getDate("joindate"));
            System.out.println(res.getDouble("salary"));
            System.out.println(res.getDouble("bonus"));
            System.out.println(res.getInt("dept_id"));
        }
    }
}

druid.png

数据库连接池C3P0

package study.datasoure;

import com.mchange.v2.c3p0.ComboPooledDataSource;

import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

/**
 * C3P0数据库连接池
 * 步骤:
 * 1、导入jar包 (c3p0-0.9.5.2.jar) 和 改该jar包的依赖包(mchange-commons-java-0.2.12.jar)
 * 2、定义配置文件
 *      配置名称:c3p0.properties 或者 c3p0-config.xml
 *
 * 3、创建核心对象 数据库连接池对象 ComboPooledDataSouce
 *      获取连接:getConnection()
 *      
 * 4、使用获取到的连接对象操作数据库
 */
public class C3p0 {
    public static void main(String[] args) throws SQLException {
        //1、创建数据库连接池对象
        //DataSource ds = new ComboPooledDataSource("otherc3p0");//可以使用指定的配置
        DataSource ds = new ComboPooledDataSource();
        //2、获取连接对象
        Connection conn = ds.getConnection();

        //3、使用
        //定义查询语句 使用?占位符
        String select = "select * from emp where id = ?";

        //获取执行SQL对象
        PreparedStatement pstm = conn.prepareStatement(select);
        //占位符参数
        pstm.setInt(1,1002);
        //执行查询语句
        ResultSet res = pstm.executeQuery();

        while (res.next()){
            System.out.println(res.getInt("id"));
            System.out.println(res.getString("ename"));
            System.out.println(res.getInt("job_id"));
            System.out.println(res.getInt("mgr"));
            System.out.println(res.getDate("joindate"));
            System.out.println(res.getDouble("salary"));
            System.out.println(res.getDouble("bonus"));
            System.out.println(res.getInt("dept_id"));
        }


        System.out.println(conn);
    }
}

c3p0.png

JDBCutils

通过上一篇文章知道了Java封装的JDBC类库用来连接各种数据库
但是其中还是有许多繁琐冗余的代码需要编写,因此,在上一篇文章的基础上,继续封装

JDBCutils类:

package study.jdbcutils;

import java.io.FileReader;
import java.io.IOException;
import java.net.URL;
import java.sql.*;
import java.util.Properties;

public class JDBCutils {
    private static String url;
    private static String user;
    private static String password;
    private static String driver;

    /**
     * 静态代码块
     * 静态代码块中的代码在类加载时只运行一次
     *
     * 读取配置文件,给对象属性赋值
     *
     * NOTE:
     * 1、静态代码块中的属性必须是静态
     * 2、静态代码块中的异常必须捕获,不能抛出
     */
    static{
        try {
            //读取资源文件 获取值
            //创建Properties集合
            Properties pro = new Properties();

            //获取配置文件的绝对路径
            ClassLoader classLoader = JDBCutils.class.getClassLoader();
            URL res = classLoader.getResource("jdbc.properties");

            String path = res.getPath();
            //加载文件进内存
            pro.load(new FileReader(path));

            //获取属性,并且赋值
            url = pro.getProperty("url");
            user = pro.getProperty("user");
            password = pro.getProperty("password");
            driver = pro.getProperty("driver");
            //注册驱动
            Class.forName(driver);
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }

    }


    /**
     * 获取连接对象
     * @return Connection
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,user,password);
    }


    /**
     * 关闭资源
     * @param pstm
     * @param conn
     */
    public static void colse(PreparedStatement pstm, Connection conn)
    {
        if (pstm != null){
            try {
                pstm.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if (conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }

    /**
     * 关闭资源
     * @param res
     * @param pstm
     * @param conn
     */
    public static void colse(ResultSet res,PreparedStatement pstm, Connection conn)
    {
        if (res != null){
            try {
                res.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (pstm != null){
            try {
                pstm.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

        if (conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
}

Demo类:

package study.jdbcutils;

import study.jdbc.Emp;

import java.sql.*;

public class Jdbc {
    public static void main(String[] args) {

        Connection conn = null;
        Statement stmt = null;
        ResultSet res = null;
        PreparedStatement pstm = null;
        try {
            //使用工具类
            conn = JDBCutils.getConnection();

            //定义查询语句 使用?占位符
            String select = "select * from emp where id = ?";

            //获取执行SQL对象
            pstm = conn.prepareStatement(select);
            //占位符参数
            pstm.setInt(1,1002);
            //执行查询语句
            res = pstm.executeQuery();

            while (res.next()){
                System.out.println(res.getInt("id"));
                System.out.println(res.getString("ename"));
                System.out.println(res.getInt("job_id"));
                System.out.println(res.getInt("mgr"));
                System.out.println(res.getDate("joindate"));
                System.out.println(res.getDouble("salary"));
                System.out.println(res.getDouble("bonus"));
                System.out.println(res.getInt("dept_id"));
            }

        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            //释放资源
            JDBCutils.colse(res,pstm,conn);
        }
    }
}

配置文件(jdbc.properties):

url=jdbc:mysql://127.0.0.1:3306/test
user=root
password=root
driver=com.mysql.jdbc.Driver

NOTE:
静态代码块的使用
配置文件的读取
PreparedStatement对象完成SQL的参数绑定,防止SQL注入

JDBC

package study.jdbc;

import com.mysql.jdbc.Driver;

import java.sql.*;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

/**
 * 1、导入驱动jar包
 * 复制相应的jar包到项目中
 * 将jar所在的目录添加为库(Iltellij IDE 选择jar所在目录右键添加为库)
 *
 * 2、注册驱动
 *  DriverManager:
 *      驱动管理对象
 *      功能:
 *          1、注册驱动
 *          2、获取数据库连接
 *  Connection:
 *      数据库连接对象
 *      功能:
 *          1、获取执行sql的对象
 *              * Statement ceateStatement()
 *              * PreparedStatement prepareStatement(string sql)
 *          2、管理事务
 *              * 开启事务:setAutoCommit(boolean autoCommit) 设置 false 开启事务
 *              * 提交事务:commit()
 *              * 回滚事务:rollback()
 *  Statement:
 *      用于执行静态SQL语句并返回其生成的结果的对象
 *      功能:
 *          1、执行sql语句
 *              * execute(string sql) 执行任意的SQL语句
 *              * int executeUpdate(string sql) 执行 DML(insert、update、delete) 语句、DDL(create、alter、drop)语句 ,该方法返值是影响行数
 *              * ResultSet executeQuery(string sql) 执行 DQL(select)语句
 *  ResultSet:
 *      结果集对象 表示数据库结果集的数据表,通常通过执行查询数据库的语句生成
 *
 */
public class Jdbc {
    public static void main(String[] args)  {
        /*
        //注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //获取数据库连接对象
        Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test", "root", "root");
        //定义sql语句
        String sql = "select * from emp";
        //获取SQL对象 Statement
        Statement stmt = conn.createStatement();
        //执行语句
        ResultSet result = stmt.executeQuery(sql);
        System.out.println(result);
        //释放资源
        stmt.close();*/

        Connection conn = null;
        Statement stmt = null;
        ResultSet res = null;
        //注册驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //获取Connection连接对象
            conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/test", "root", "root");
            //获取执行SQL对象
            stmt = conn.createStatement();

            //定义SQL
            //增
            String insert = "insert into emp(id,ename,job_id,mgr,joindate,salary,bonus,dept_id) values(1,'乔峰',2,1010,'2001-09-28',29750,1000,20)";
            //删
            String delete = "delete from emp where id = 1";
            //改
            String update = "update emp set id = 2 where id = 1001";
            //查
            String select = "select * from emp";

            //执行语句
            /*int i1 = stmt.executeUpdate(insert);//影响行数
            int i2 = stmt.executeUpdate(delete);//影响行数
            int i3 = stmt.executeUpdate(update);//影响行数
            System.out.println(i1);
            System.out.println(i2);
            System.out.println(i3);*/

            //执行查询语句
            //获取单个数据
            res = stmt.executeQuery(select);
            /*res.next();//指针向下移动一行 返回false表示已经到最后
            System.out.println(res.getInt(1));
            System.out.println(res.getString("ename"));
            System.out.println(res.getInt("job_id"));*/


            //遍历 将查询结果集封装为对象
            Emp emp = null;
            List<Emp> list = new ArrayList<>();
            while (res.next()){
                emp = new Emp();
                emp.setId(res.getInt("id"));
                emp.setEname(res.getString("ename"));
                emp.setId(res.getInt("job_id"));
                emp.setMgr(res.getInt("mgr"));
                emp.setJoindate(res.getDate("joindate"));
                emp.setSalary(res.getDouble("salary"));
                emp.setBonus(res.getDouble("bonus"));
                emp.setDept_id(res.getInt("dept_id"));

                list.add(emp);

            }

            Iterator<Emp> it = list.iterator();
            while (it.hasNext()) {
                System.out.println(it.next());
            }

        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }finally {
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }

            if (res != null) {
                try {
                    res.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }

    }

}

jdbc0.png

Junit

例如我有一个类,需要测试程序是否OK

被测试对象

package com.Junit;

/**
 * 计算器类
 * 定义了两个方法
 */
public class Calculator {
    /**
     * 加法
     * @param a
     * @param b
     * @return
     */
    public int add(int a,int b) {
        return a + b;
    }

    /**
     * 减法
     * @param a
     * @param b
     * @return
     */
    public int sub(int a,int b) {
        return a - b;
    }

}

测试JUnit类:

package com.test;
import com.Junit.Calculator;
import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;

public class CalculatorTest {

    /**
     * @Before  注解:
     * 测试方法中的初始化方法
     */
    @Before
    public void init(){
        System.out.println("init");
    }

    /**
     * @After 注解:
     * 测试方法中的后置方法
     */
    @After
    public void close(){
        System.out.println("close");
    }




    /**
     * @Test 注解:
     * 表示 该方法可以脱离main方法直接运行
     * 测试add方法
     */
    @Test
    public void testAdd()
    {
        //System.out.println("执行了");
        //创建测试对象
        Calculator c = new Calculator();
        int result = c.add(1, 2);

        //对应测试结果,使用断言功能
        //assertEquals() 第一个参数为期望值 第二个参数为结果值,程序将两个值进行比较
        Assert.assertEquals(3,result);
        System.out.println("测试完成");

    }
}

测试输出结果:
junit.png