Java Web JDBC JDBC驱动连接Mysql数据库8.0 MySQL 8.0 以上版本的数据库连接有所不同:
1、MySQL 8.0 以上版本驱动包版本 mysql-connector-java-8.0.16.jar 。
2、*com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver 。*
MySQL 8.0 以上版本不需要建立 SSL 连接的,需要显示关闭。
allowPublicKeyRetrieval=true 允许客户端从服务器获取公钥。
最后还需要设置 CST。
url = “jdbc:mysql:///teaching?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true”
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 public class jdbcdmo { public static void main (String[] args) throws Exception { Class.forName("com.mysql.cj.jdbc.Driver" ); **String url = "jdbc:mysql://127.0.0.1:3306/teaching?useSSL=false&serverTimezone=UTC" ;** String username = "root" ; String password = "Hck282018" ; Connection conn = DriverManager.getConnection(url, username, password); String sql = "update stu set age = 20 where id = 2;" ; Statement stmt = conn.createStatement(); int count = stmt.executeUpdate(sql); System.out.println(count); stmt.close(); conn.close(); } }
JDBC API Connection处理事务 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 public class jdbcdmo { public static void main (String[] args) throws Exception { String url = "jdbc:mysql:///teaching?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" ; String username = "root" ; String password = "Hck282018" ; Connection conn = DriverManager.getConnection(url, username, password); String sql1 = "update stu set age = 20 where id = 1" ; String sql2 = "update stu set age = 20 where id = 2" ; Statement stmt = conn.createStatement(); **try { conn.setAutoCommit(false ); int count = stmt.executeUpdate(sql1); System.out.println(count); int count1 = stmt.executeUpdate(sql2); System.out.println(count1); conn.commit(); } catch (Exception e) { conn.rollback(); throw new RuntimeException (e); }** stmt.close(); conn.close(); } }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @Test public void testjdbc1 () throws SQLException { String url = "jdbc:mysql:///teaching?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" ; String username = "root" ; String password = "Hck282018" ; Connection conn = DriverManager.getConnection(url, username, password); String sql1 = "create database db2" ; Statement stmt = conn.createStatement(); int count = stmt.executeUpdate(sql1); System.out.println(count); if (count > 0 ){ System.out.println("修改成功!" ); } else { System.out.println("修改失败!" ); } stmt.close(); conn.close(); }
ResultSet执行查询语句 ResultSet.next()会返回一个布尔值,为是否查询到数据。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 @Test public void testjdbc () throws SQLException { String url = "jdbc:mysql:///teaching?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" ; String username = "root" ; String password = "Hck282018" ; Connection conn = DriverManager.getConnection(url, username, password); String sql = "select * from stu" ; Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery(sql); while (rs.next()){ System.out.println(rs.getInt(1 )); System.out.println(rs.getString(2 )); System.out.println(rs.getInt(3 )); System.out.println(rs.getString(4 )); System.out.println("======================" ); } rs.close(); stmt.close(); conn.close(); }
PreparedStatement 作用:预编译sql语句,防止sql注入
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 @Test public void testjdbc2 () throws SQLException { String url = "jdbc:mysql:///teaching?useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true" ; String username = "root" ; String password = "Hck282018" ; Connection conn = DriverManager.getConnection(url, username, password); String name = "mayun" ; String address = "hangzhou" ; String sql = "select * from stu where name = **?** and address = **?**" ; PreparedStatement pstmt = conn.prepareStatement(sql); **pstmt.setString(1 ,name); pstmt.setString(2 ,address);** ResultSet rs = pstmt.executeQuery(); if (rs.next()){ System.out.println("登录成功" ); }else { System.out.println("登陆失败!" ); } rs.close(); pstmt.close(); conn.close(); }
数据库连接池 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 public class druidDemo { public static void main (String[] args) throws Exception { Properties properties = new Properties (); properties.load(new FileInputStream ("E:\\Java_IDEA\\jdbc\\jdbc-demo\\src\\druid.properties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); System.out.println(connection); } }
SQL实例 查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 public class brandTest { @Test public void testSelectAll () throws Exception { Properties properties = new Properties (); properties.load(new FileInputStream ("E:\\Java_IDEA\\jdbc\\jdbc-demo\\src\\druid.properties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); String sql = "select * from tb_brand" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); ResultSet rs = preparedStatement.executeQuery(); Brand brand = null ; List<Brand> brandList = new ArrayList <>(); while (rs.next()){ int id = rs.getInt("id" ); String brand_name = rs.getString("brand_name" ); String company_name = rs.getString("company_name" ); int ordered = rs.getInt("ordered" ); String description = rs.getString("description" ); int status = rs.getInt("status" ); brand = new Brand (id, brand_name, company_name, ordered, description, status); **brandList.add(brand);** System.out.println(brand); } System.out.println(brandList); rs.close(); preparedStatement.close(); connection.close(); } }
添加 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @Test public void testSelectAll () throws Exception { String brandName = "香飘飘" ; String companyName = "香飘飘" ; int ordered = 1 ; String description = "绕地球一圈" ; int status = 1 ; Properties properties = new Properties (); properties.load(new FileInputStream ("E:\\Java_IDEA\\jdbc\\jdbc-demo\\src\\druid.properties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); String sql = "insert into tb_brand(brand_name, company_name, ordered, description, status) values(?,?,?,?,?)" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1 ,brandName); preparedStatement.setString(2 ,companyName); preparedStatement.setInt(3 ,ordered); preparedStatement.setString(4 ,description); preparedStatement.setInt(5 ,status); int count = preparedStatement.executeUpdate(); System.out.println(count > 0 ); preparedStatement.close(); connection.close(); }
修改 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 @Test public void testUpdate () throws Exception { String brandName = "香飘飘" ; String companyName = "香飘飘" ; int ordered = 1 ; String description = "销量不好" ; int status = 1 ; int id = 3 ; Properties properties = new Properties (); properties.load(new FileInputStream ("E:\\Java_IDEA\\jdbc\\jdbc-demo\\src\\druid.properties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); **String sql = "update tb_brand " + "set brand_name = ?," + " company_name = ?," + " ordered = ?," + " description = ?," + " status = ? " + "where id = ?" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setString(1 ,brandName); preparedStatement.setString(2 ,companyName); preparedStatement.setInt(3 ,ordered); preparedStatement.setString(4 ,description); preparedStatement.setInt(5 ,status); preparedStatement.setInt(6 ,id); int count = preparedStatement.executeUpdate(); System.out.println(count > 0 ); preparedStatement.close(); connection.close(); }
删除 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Test public void testDelete () throws Exception { int id = 3 ; Properties properties = new Properties (); properties.load(new FileInputStream ("E:\\Java_IDEA\\jdbc\\jdbc-demo\\src\\druid.properties" )); DataSource dataSource = DruidDataSourceFactory.createDataSource(properties); Connection connection = dataSource.getConnection(); String sql = "DELETE FROM tb_brand WHERE id = ?" ; PreparedStatement preparedStatement = connection.prepareStatement(sql); preparedStatement.setInt(1 ,id); int count = preparedStatement.executeUpdate(); System.out.println(count > 0 ); preparedStatement.close(); connection.close(); }
Maven 是一套专门用于管理和构建Java项目的工具
Maven还提供了一套标准化的构建流程和依赖管理。
可以非常方便的打包构建项目与导入jar包。
Maven坐标 1 2 3 <groupId > org.example</groupId > <artifactId > maven-demo</artifactId > <version > 1.0-SNAPSHOT</version >
IDEA导入Maven项目 Maven依赖管理 1 2 3 4 5 6 7 <dependencies > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.30</version > </dependency > </dependencies >
引入依赖需要刷新,才能在远程库下载。
MyBatis 持久层框架,用于简化JDBC开发。
持久层:保存到数据库的操作代码
JavaEE开发:表现层,业务层,持久层
使用流程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class MybatisDemo { public static void main (String[] args) throws Exception{ String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); List<Brand> brandList = sqlSession.selectList("**test.selectAll**" ); System.out.println(brandList); } }
1 2 3 4 5 6 7 8 9 10 11 12 <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd" > <mapper namespace ="test" > <select id ="selectAll" resultType ="com.itheima.Brand" > select * from tb_brand; </select > </mapper >
注意:MyBatis返回的对象中实体类对应属性名必须与数据库字段名完全相同: 1 2 3 4 5 6 7 8 public class Brand { private int id; private String brand_Name; private String company_Name; private int ordered; private String description; private int status; }
也可用ResultMap定义结果映射:
1 2 3 4 5 6 7 8 <resultMap id ="brandResultMap" type ="com.hit.pojo.Brand" > **<result column ="brand_name" property ="brand_Name" /> <result column ="company_name" property ="company_Name" /> ** </resultMap > <select id ="selectAll" resultMap ="brandResultMap" > select * from tb_brand; </select >
Mapper代理开发 注意:必须放在同一文件包内,UserMapper.java与UserMapper.xml,且命名空间要写对路径。 下图为同一路径,另外在resource文件中不能建立软件包,只能用com/itheima/mapper方式建立文件夹结构间接建立包目录。
1 2 3 4 5 <mapper namespace ="**com.itheima.mapper.UserMapper**" > <select id ="selectAll" resultType ="com.itheima.Brand" > select * from tb_brand; </select > </mapper >
UserMapper.java
1 2 3 4 5 6 7 8 9 10 11 12 package com.itheima.mapper;import com.itheima.Brand;import java.util.List;public interface UserMapper { List<Brand> selectAll () ; }
主程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 public class MybatisDemo2 { public static void main (String[] args) throws Exception{ String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); **UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<Brand> brands = userMapper.selectAll();** System.out.println(brands); sqlSession.close(); } }
MyBatisX插件无法识别: 1 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
改成上面这行就ok。
MyBatis执行流程:
编写接口方法
编写sql
执行
MyBatis占位符 需要用#{} 否则会有sql注入风险。
1 2 3 4 <select id ="searchById" resultMap ="brandResultMap" > select * from tb_brand where id = **#{id}**; </select >
特殊字符处理: 可用转义字符和CDATA 。
1 2 3 4 5 6 7 8 <select id ="searchById" resultMap ="brandResultMap" > select * from tb_brand <![CDATA[ < ]]> 10; </select >
MyBatis条件查询 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 @Test public void selectByCondition () throws IOException { int status = 1 ; String companyName = "华为" ; String brandName = "华为" ; companyName = "%" + companyName + "%" ; Map map = new HashMap (); map.put("status" ,status); map.put("company_Name" ,companyName); map.put("brand_Name" ,brandName); String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<Brand> brands = userMapper.selectByCondition(map); System.out.println(brands); sqlSession.close(); }
映射:
1 2 3 4 5 6 7 <select id ="selectByCondition" resultMap ="brandResultMap" > select * from tb_brand where status = #{status} and company_name like #{company_Name} and brand_name like #{brand_Name}; </select >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 public interface UserMapper { List<Brand> selectAll () ; Brand searchById (int id) ; List<Brand> selectByCondition (@Param("status") int status, @Param("company_Name") String company_Name, @Param("brand_Name") String brand_name) ; }
动态查询 会随外部输入而变化的查询
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="selectByCondition" resultMap ="brandResultMap" > select * from tb_brand where <if test ="status != null" > status = #{status} </if > # **此处判断的变量为取到值的实体类中变量名,非sql字段名** <if test ="company_Name != null and company_Name != ''" > and company_name like #{company_Name} </if > <if test ="brand_Name != null and brand_Name != ''" > and brand_name like #{brand_Name}; </if > </select >
此时三个参数可不全传参,都可完全查询。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <select id ="selectByCondition" resultMap ="brandResultMap" > select * from tb_brand **where 1=1** <if test ="status != null" > and status = #{status} </if > # 此处判断的变量为取到值的实体类中变量名,非sql字段名 <if test ="company_Name != null and company_Name != ''" > and company_name like #{company_Name} </if > <if test ="brand_Name != null and brand_Name != ''" > and brand_name like #{brand_Name}; </if > </select >
上面写法好看点。
也可用**MyBatis关键字**(最好用的办法):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 <select id ="selectByCondition" resultMap ="brandResultMap" > select * from tb_brand **<where > <if test ="status != null" > and status = #{status} </if > # 此处判断的变量为取到值的实体类中变量名,非sql字段名 <if test ="company_Name != null and company_Name != ''" > and company_name like #{company_Name} </if > <if test ="brand_Name != null and brand_Name != ''" > and brand_name like #{brand_Name}; </if > </where > ** </select >
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 <select id ="selectByConditionSingle" resultMap ="brandResultMap" > select * from tb_brand where <choose > <when test ="status!=null" > status = #{status} </when > <when test ="brand_Name != null and brand_Name != ''" > brand_name like #{brand_Name}; </when > <when test ="company_Name != null and company_Name != ''" > company_name like #{company_Name} </when > <otherwise > 1=1 </otherwise > </choose > </select >
也可用Where标签:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 <select id ="selectByConditionSingle" resultMap ="brandResultMap" > select * from tb_brand <where > <choose > <when test ="status!=null" > status = #{status} </when > <when test ="brand_Name != null and brand_Name != ''" > brand_name like #{brand_Name}; </when > <when test ="company_Name != null and company_Name != ''" > company_name like #{company_Name} </when > </choose > </where > </select >
添加字段 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 @Test public void add () throws IOException { int status = 1 ; String companyName = "波导手机" ; String brandName = "波导" ; String description = "好手机" ; int ordered = 100 ; companyName = "%" + companyName + "%" ; Brand brand = new Brand (); brand.setStatus(status); brand.setBrand_Name(brandName); brand.setCompany_Name(companyName); brand.setDescription(description); brand.setOrdered(ordered); String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); UserMapper userMapper = sqlSession.getMapper(UserMapper.class); userMapper.add(brand); **sqlSession.commit();** sqlSession.close();
映射文件
1 2 3 4 <insert id ="add" > insert into tb_brand (**brand_name, company_name, ordered, description, status**) values (#{brand_Name},#{company_Name},#{ordered},#{description},#{status} ) </insert >
主键返回 1 <insert id ="add" useGeneratedKeys ="true" keyProperty ="id" >
修改字段 1 2 3 4 5 6 7 8 9 10 <update id ="update" > update tb_brand set brand_name = #{brand_Name}, company_name = #{company_Name}, ordered = #{ordered}, description = #{description}, status = #{status} where id = #{id} </update >
修改动态字段 相当于update加if标签:
用set标签可避免最后一个字段没有参数导致逗号出现在最后,造成语法错误
删除字段 1 2 3 <delete id ="deleteById" > delete from tb_brand where id = #{id} </delete >
1 2 3 4 5 6 7 8 9 10 <delete id ="deleteByIds" > delete from tb_brand where id in ( **<foreach collection ="array" item ="id" separator ="," open ="(" close =")" > ** #{id} </foreach > ); </delete >
1 <foreach collection ="array" item ="id" separator ="," open ="(" close =")" >
此句拼接sql参数,默认接收数组参数为array,可用注解改变。
separator分割不同数组,open和close拼接语句首尾。
MyBatis参数传递 Web核心 Tomcat 使用骨架会谜之报错,貌似是这个原因 。
IDEA集成本地Tomcat比较麻烦,但健壮性好于用tomcat maven插件。
注:在配置tomcat部署前需要用maven run package打包生成snap.war文件
Servlet 开发流程 使用插件要注意端口不能被占用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 package com.hit.web;import javax.servlet.*;import javax.servlet.annotation.WebServlet;import java.io.IOException;@WebServlet("/demo1") public class ServletDemo1 implements Servlet { @Override public void service (ServletRequest servletRequest, ServletResponse servletResponse) throws ServletException, IOException { System.out.println("hello world!" ); } @Override public String getServletInfo () { return null ; } @Override public void destroy () { } @Override public void init (ServletConfig servletConfig) throws ServletException { } @Override public ServletConfig getServletConfig () { return null ; } }
Servlet由web服务器创建和调用方法
destroy方法在销毁时执行:
HttpServlet 1 2 3 4 5 6 7 8 9 10 11 12 @WebServlet("/demo4") public class ServletDemo4 extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("get..." ); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post...." ); } }
xml配置servlet: 1 2 3 4 5 6 7 8 9 10 11 <servlet > <servlet-name > demo6</servlet-name > <servlet-class > com.hit.web.ServletDemo6</servlet-class > </servlet > <servlet-mapping > <servlet-name > demo6</servlet-name > <url-pattern > /demo6</url-pattern > </servlet-mapping >
远不如注解方便。
Request与Response 1 2 3 4 5 6 7 8 9 10 11 @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("post...." ); BufferedReader br = req.getReader(); String line = br.readLine(); System.out.println(line); } }
Request通用获取请求参数 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 @WebServlet("/demo7") public class ServletDemo7 extends HttpServlet { @Override protected void doGet (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { System.out.println("get......." ); Map<String, String[]> map = req.getParameterMap(); for (String key : map.keySet()) { System.out.print(key + ":" ); String[] values = map.get(key); for (String value : values) { System.out.print(value + " " ); } System.out.println(); } System.out.println("==================" ); String[] hobbies = req.getParameterValues("hobby" ); for (String hobby : hobbies) { System.out.println(hobby); } String username = req.getParameter("username" ); System.out.println(username); } @Override protected void doPost (HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this .doGet(req, resp); } }
请求中文乱码 Get和Post都存在中文乱码问题。
post用
1 request.setCharacterEncoding("UTF-8" );
即可。
GET乱码原因:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @WebServlet("/req") public class ServletDemo extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("UTF-8" ); String username = request.getParameter("username" ); byte [] bytes = username.getBytes(StandardCharsets.ISO_8859_1); String s = new String (**bytes, StandardCharsets.UTF_8**); System.out.println(s); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
Request请求转发 请求转发:在服务器内部实现资源跳转。
1 request.getRequestDispatcher("/demo7" ).forward(request,response);
可实现流水线数据处理
Response对象 重定向 1 2 3 4 5 6 7 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { System.out.println("demo1....." ); **response.setStatus(302 ); response.setHeader("Location" , "/resp2" );** }
也可简化:
1 response.sendRedirect("/resp2" );
重定向为两次请求,可重定向至外部资源。
Response响应字符字节数据 1 2 3 4 5 6 7 8 9 10 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setHeader("content-type" , "text/html" ); PrintWriter writer = response.getWriter(); writer.write("aaaa" ); System.out.println("aaa" ); writer.write("<h1>aaaa</h1>" ); }
解决中文乱码:
1 2 3 4 5 6 7 8 @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=utf-8" ); PrintWriter writer = response.getWriter(); writer.write("aaaa" ); System.out.println("aaa" ); writer.write("<h1>你好</h1>" ); }
字节输出流:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 public class ResponseDemo4 extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { FileInputStream fileInputStream = new FileInputStream ("C:\\Users\\Yoruko\\Pictures\\Saved Pictures\\ACG\\4.png" ); ServletOutputStream outputStream = response.getOutputStream(); IOUtils.copy(fileInputStream, outputStream); fileInputStream.close(); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
案例 注册 SqlSessionFactory优化 1 2 3 String resource = "mybatis-config.xml" ;InputStream is = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(is);
上面获取sqlSessionFactory对象的代码重复多次,可用静态代码块优化。
写个工具类:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 public class SqlSessionFactoryUtils { private static SqlSessionFactory sqlSessionFactory; static { try { **String resource = "mybatis-config.xml" ; InputStream is = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder ().build(is); } catch (Exception e) { throw new RuntimeException (e); } } public static SqlSessionFactory getSqlSessionFactory () { return sqlSessionFactory; } }
再调用该工具类即可。
JSP 1 2 3 4 5 6 7 8 9 10 11 12 <%@ page contentType="text/html;charset=UTF-8" language="java" %> <html > <head > <title > Title</title > </head > <body > <h1 > Hello jsp</h1 > <% System.out.println("Hello jsp!!"); %> </body > </html >
JSP本质是一个servlet,由tomcat封装调用。
MVC入门 三层架构 Model-View-Controller
jsp内标签名与数据字段名不同时需用ResultMap映射:
会话追踪技术 原因:HTTP请求是无状态的。
实现方式:
客户端:Cookie
服务端:Session
Cookie 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @WebServlet("/aservlet") public class aservlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie cookie = new Cookie ("username" ,"zs" ); response.addCookie(cookie); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
接受cookie:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 @WebServlet("/BServlet") public class BServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { Cookie[] cookies = request.getCookies(); for (Cookie cookie : cookies) { String name = cookie.getName(); if ("username" .equals(name)){ String value = cookie.getValue(); System.out.println(name + ":" + value); break ; } } } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
注: request.getCookies()只能获取浏览器所有cookie,因此需要遍历寻值。
Seesion 实际基于cookie。
1 2 HttpSession session = request.getSession();session.setAttribute("username" ,"zs" );
获取:
1 2 3 4 5 HttpSession session = request.getSession();Object username = session.getAttribute("username" );System.out.println(username);
cookie与session区别 cookie不安全,session安全。
cookie可长期存储,但session默认30分钟销毁。
cookie最大3kb,session无限制。
cookie多存储长期数据,session保存登陆后的临时数据
Filter——JavaWeb三大组件之二 入门:
定义Filter类,实现接口方法
配置拦截器路径,加@WebFilter注解(”*”过滤所有)
在doFilter方法内执行逻辑和放行
1 2 3 4 5 public void doFilter (ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { System.out.println("FilterDemo...." ); **filterChain.doFilter(servletRequest,servletResponse);** }
执行流程: 放行前的代码 ⇒ 过滤的页面显示 ⇒ 放行后逻辑
一般流程为:放行前对request进行处理,放行后对response做处理。
注:过滤器只能拦截资源。
过滤器链 注意:需要无条件放行与登录相关的资源文件
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 @WebFilter("/*") public class LoginFilter implements Filter { public void init (FilterConfig config) throws ServletException { } public void destroy () { } @Override public void doFilter (ServletRequest request, ServletResponse response, FilterChain chain) throws ServletException, IOException { HttpSession session = ((HttpServletRequest) request).getSession(); Object user = session.getAttribute("user" ); if (user != null ){ chain.doFilter(request, response); }else { request.setAttribute("login_msg" ,"您尚未登录!" ); request.getRequestDispatcher("index.html" ).forward(request,response); } } }
Listener 监听服务器变化并调用相关方法。
AJAX 前端
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 <!DOCTYPE html> <html lang ="en" > <head > <meta charset ="UTF-8" > <title > Title</title > </head > <body > <script > var xhttp; if (window .XMLHttpRequest ) { xhttp = new XMLHttpRequest (); } else { xhttp = new ActiveXObject ("Microsoft.XMLHTTP" ); } xhttp.open ("GET" ,"http://localhost/ajax" ); xhttp.send (); xhttp.onreadystatechange = function ( ) { if (this .readyState === 4 && this .status === 200 ) { alert (this .responseText ); } }; </script > </body > </html >
后端
1 2 3 4 5 6 7 8 9 10 11 12 13 @WebServlet("/ajax") public class AjaxServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.getWriter().write("hello ajax!!" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
实例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 <script> function inputonblur (e ) { let username = e; var xhttp; if (window .XMLHttpRequest ) { xhttp = new XMLHttpRequest (); } else { xhttp = new ActiveXObject ("Microsoft.XMLHTTP" ); } xhttp.open ("GET" ,"http://localhost/selectUserServlet?username=" + username); xhttp.send (); xhttp.onreadystatechange = function ( ) { if (this .readyState === 4 && this .status === 200 ) { if (this .responseText === "true" ){ document .getElementById ("username_err" ).style .display = '' ; }else { document .getElementById ("username_err" ).style .display = 'none' ; } } }; } </script>
Axios 简化Ajax代码
1 2 3 4 5 6 7 8 9 <script> axios ({ method : "GET" , url : "http://localhost/axios" , data : "username=zhangsan" }).then (function (resq ){ alert (resq.data ); }) </script>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 public class AxiosServlet extends HttpServlet { @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { String username = request.getParameter("username" ); System.out.println(username); response.getWriter().write("hello axios!!" ); } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }
JSON 用于数据传输,可存储对象数据。
Fastjson 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 import com.alibaba.fastjson.JSON;public class JsonTest { public static void main (String[] args) { User user = new User (); user.setId(1 ); user.setUsername("zhangsan" ); user.setPassword("123" ); String s = JSON.**toJSONString(user);** System.out.println(s); User user1 = JSON.**parseObject**("{\"id\":1,\"password\":\"123\",\"username\":\"zhangsan\"}" , User.class); System.out.println(user1); } }
实例:json与axios代替jsp Brand.html
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <a href="addBrand.html"><input type="button" value="新增"></a><br> <hr> <table id="brandTable" border="1" cellpadding="0" width="100%"> <!-- <tr>--> <!-- <th>序号</th>--> <!-- <th>产品名称</th>--> <!-- <th>企业</th>--> <!-- <th>排序</th>--> <!-- <th>介绍</th>--> <!-- <th>状态</th>--> <!-- <th>操作</th>--> <!-- </tr>--> <!-- <tr align="center">--> <!-- <td>1</td>--> <!-- <td>1</td>--> <!-- <td>1</td>--> <!-- <td>1</td>--> <!-- <td>1</td>--> <!-- <td>1</td>--> <!-- <td>1</td>--> <!-- </tr>--> </table> <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script> <script> **window.onload = function()**{ //1.页面加载完成后调用函数 axios({ //2.发送ajax请求 method:"get", url:"http://localhost/selectAllServlet1" }).then(function (resp){ let data = resp.data; let tabledata = "<tr>\n" + " <th>序号</th>\n" + " <th>产品名称</th>\n" + " <th>企业</th>\n" + " <th>排序</th>\n" + " <th>介绍</th>\n" + " <th>状态</th>\n" + " <th>操作</th>\n" + " </tr>"; for (let i = 0; i < data.length; i++) { let brand = data[i]; tabledata += "<tr align=\"center\">\n" + " <td>" + (i+1) + "</td>\n" + " <td>" + brand.brand_Name +"</td>\n" + " <td>" + brand.company_Name +"</td>\n" + " <td>" + brand.ordered +"</td>\n" + " <td>" + brand.description +"</td>\n" + " <td>" + brand.status +"</td>\n" + "\n" + " <td><a href=\"#\">修改</a> <a href=\"#\">删除</a></td>\n" + " </tr>"; } //设置表格数据 document.getElementById("brandTable").innerHTML = tabledata; }) } </script> </body> </html>
后端Servlet生成数据
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @WebServlet("/selectAllServlet1") public class SelectAllServlet extends HttpServlet { private final BrandService brandService = new BrandService (); @Override protected void doGet (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { List<Brand> brands = brandService.selectAll(); String s = JSON.toJSONString(brands); **response.setContentType("text/json;charset=utf-8" ); response.getWriter().write(s);** } @Override protected void doPost (HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { this .doGet(request, response); } }