一文搞懂Java开发岗位和技术+案例分析

文档工具

  1. Typora(本地存储)
  2. 语雀(云存储)
  3. 有道云

开发工具

  1. idea (java)
  2. vscode (大前端)
  3. HBuilderx (网页设计)
  4. WebStorm
  5. MySql/Navicat
  6. JDK8
  7. Maven(Gradle),NPM

开发岗位

  • 方向: 全栈, java后端方向, 大前端方向(Web前端)
  • 岗位分类: java开发工程师(后端), 大前端开发工程师(web前端)
  • 岗位方向: 实习岗, java实训工程师, 高级工程师, 项目经理, 技术总监, 总裁, 自主创业(boss)

岗位技术栈

java技术栈

  1. idea, linux(CentOS, Ubuntu), 云服务

  2. Linux终端: Xshell, 宝塔, SercureCRT

  3. javaSE(核心基础)

  4. JDBC(数据源/连接池), Servlet, javaWeb

  5. 数据库:MySql, Oracle,

  6. NoSql: Redis, MongoDB, Mencached, Zookeeper

  7. 框架:Spring, SpringMVC, SpringBoot, SpringCloud, SpringClouldAlibaba

  8. 持久层框架: MyBaits, MyBatisPlus, SpingData JPA

  9. 安全(权限)框架: SpringSecurity, Shiro, OAuth2.0

  10. 项目管理工具: Maven, Gradle, NPM

  11. 版本控制: Git, Github, Gitee

  12. 消息队列: Kafka, RabbitMQ, RocketMQ

  13. Driud, SpringBootAdmin, SkyWalking

  14. 开发架构: 单体框架, 垂直架构, 分布式架构, SOA(面向服务的架构), 微服务架构

  15. 辅助工具: Xmind, draw.io, ProcessOn

  16. 运维部署: Docker, k8s

  17. 性能优化: SQL优化, JVM优化, Jmeter

  18. 服务器: Tomcat, 云服务, Nginx, Apache


前端技术栈

  1. HTML/H5, css3, JavaScript, JQuery(Ajax)

  2. Es6(原型, 原型链,作用域 ,闭包, 异步, this, 函数, js新特性), TS(TypeScript)

  3. js框架: Vue2/Vue3, React.js, Augular, servlet

  4. 异步请求:Jquery(Ajax), Axios, fetch

  5. 跨域: 跨域问题, 同源问题, JSONP, CORS, Xss

  6. H5, App, 微信小程序, UniApp

  7. 大前端的后端技术栈: Node.js, Express, Koa, Egg.js

  8. 数据库: MySql, MongoDB

  9. 版本控制: Git/Gitee, SVM

  10. 自动化构建工具: 脚手架(Vue-cli), webpack

  11. UI组件: ElementUI, Bootstrap, Layui

  12. 服务器渲染框架: Next.js(React.js), Nuxt.js(Vue.js)

项目实训技术架构

  1. IDEA
  2. JDK8以上
  3. MySql8
  4. Tomcat9
  5. Maven
  6. Servlet/jsp, EL表达式, JSTL标签
  7. JDBC, DbUtils, 数据源(Druid)
  8. UI模板, JQuery, LayUI
  9. HuTool

MySql

1.概念

数据库是"按照数据结构来组织, 存储, 管理数据的仓库", 上一个可以持久化长期存储在计算机类的, 有组织的, 有共享的, 可以统一管理的数据集合

2.数据库分类

  • 网状结构数据库
  • 层次结构数据库
  • 关系结构数据库(Oracle, MySql, DB2, SQL Server)
  • 非关系型数据库: MongDB, Redis, 使用哈希表, 表中以键值(Key-Value)的方式实现特定的键和指针指向的特定数据

3. 数据库管理系统

数据库管理系统(DBMS): 管理和操作数据库的系统, 用于建立, 使用, 维护数据库, 谁数据库进行统一的管理和控制, 保证数据库的安全性和完整性

常用的数据库系统:

  • Oracle

  • DB2

  • SQL Server

  • SQLLite

  • MySql

4.SQL语句

SQL: 是结构化查询语言, 用于存储数据, 更新, 想查询和管理关系类型数据库系统的程序设计语言

通常用于对数据库的数据操作进行CRUD(增(Create), 删(Delete), 改(Update), 查(Retrieve))操作

对于数据库的操作, 在MySql的环境下进行指令操作, 都是使用";"结束

  1. 登录数据库

    mysql -u -root -p # 回车键
    Enter password: #输入密码即可Enter
    
  2. 查看MySql数据库中所有的数据库

    show databases;
    
  3. 创建数据库

    # create database (数据库名)
    create database mysql; #创建名为mysql的数据库
    
    # 创建数据库的缩放指定数据库的字符集
    create database mysql character set utf-8;
    
    
    
  4. 删除数据库

    # drop database (数据库名)
    drop database mysql;
    
  5. 查看数据库创建信息

    show create database mysql;
    
  6. 修改数据库编码信息

    # 修改数据库msql的字符集为gbk
    alter database mysql character set gbk;
    
  7. 使用数据库

    use mysql; # 当前环境下选中mysql数据库
    
  8. 查看当前使用的数据库

    select database(); # 查看当前使用的数据库
    
  9. 退出DBMS

    exit;
    

    备注: DBMS不区分大小写, MySql命令以";"作为结束符

5.数据库表

任何一张表都是由行和列组成:

  • 行(row): 称为一行记录/一条数据
  • 列(column): 表字段

数据库表每个字段: 字段名, 数据类型, 约束等属性

  • 字段名: 就是一个普通的名字, 定义要做的见名知意, 不要使用和顾问中文和关键字
  • 数据类型: 字符(char), 字符串(varchar), 数字类型(int, double, float), 日期等
  • 约束: 数据库约束有很多, 常用的约束有: 主键约束, 唯一约束, 非空约束

对表的操作就是对表的定义(DDL): create, drop, alter等

5.1 创建表

语法格式:

craete table 表名(
	字段名1 数据类型,
	字段名2 数据类型,
	字段名3 数据类型,
	约束条件
)

说明:如果数据库表由多个单词组成, 建议"_"连接, eg: cz_emp

表名禁止使用数字或者关键字或者特殊符号命名

数据库在windows系统下不区分大小写, 但在linux系统下是严格区分大小写的, 所以在数据库名, 表名, 字段名说都做到统一, 避免据节外生枝

需求:

创建一个学生表, 学号, 性别, 年龄, 电话, 出生日期, 地址

//创建数据库
create database ch_db;

//选中数据库
use ch_db;

//创建表
create table ch_student(
	id int(10) primary key not null auto_increment,
	username varchar(20) not null,
	sex char(20),
	age int (10),
	phone varchar(11),
    address varchar(40)
);

//查看表结构
desc ch_student;

注意:

  • 在同一张表中, 字段名不能相同
  • 数据类型长度和约束条件为可选参数, 字段名和字段类型是必须的
5.2 更新表

向ch_student表在添加列(字段)

语法:

 # alter table table_name(表名) add column 列名(字段) 字段名
 
 alter table ch_student add column classes varchar(20);
 
  alter table ch_student add column birthday date;
5.3 删除列

语法:

//alter table table_name(表名) drop column 列名

//删除年龄字段
alter table ch_student drop column age;

注意:

在实际开发过程中 需求一旦确定, 表一旦设计好之后, 是很少对表的结构进行修改操作的, 因为修改的成本很高, 表的结构改了, 对应和业务逻辑的java代码也要进行大量的修改

5.4字段的约束

在创建表的时候, 可以改表的字段添加相应的约束, 添加约束的目的是为了保证表中的数据的合法性, 有效性, 完整性

  • 非空约束 (not null): 约束的字段不能为空
  • 唯一约束 (unique): 约束的字段值不能重复
  • 主键约束 (primary key): 约束的字段既不能为空, 也不能重复 (PK)
  • 外键 (foreign key) : 外键字段的约束 (FK)

6. DML操作

所谓DML操作, 就是对表记录进行读写(CRUD)的操作

6.1 添加语句

语法

insert into 表名(字段1, 字段2, 字段3, ....., 字段n) values(1,2,3, ....., 值n);

//字段和值是一一对应, 数据类型也要相同
insert into ch_student (username, sex, age, phone, birthday, address, classes)
values ("法外狂徒张三", "男", "6", "12365478910", "2023-12-26", "翻斗花园", "翻斗幼儿园");

//添加操作时, 还可以不给表字段, 但需要给每一个字段赋值
insert into ch_student
values (0, "法外狂徒张三", "男", "6", "12365478910",  "翻斗花园", "翻斗幼儿园", "2023-12-26");


insert into ch_student
values 
(0, "法外狂徒张三一", "男", "6", "12365478910",  "翻斗花园", "翻斗幼儿园", "2023-12-26"),
(0, "法外狂徒王五", "男", "6", "12365478910",  "翻斗花园", "翻斗幼儿园", "2023-12-26"),
(0, "法外狂徒张二麻", "男", "6", "12365478910",  "翻斗花园", "翻斗幼儿园", "2023-12-26"),
(0, "法外狂徒张三五", "男", "6", "12365478910",  "翻斗花园", "翻斗幼儿园", "2023-12-26"),
(0, "法外狂徒张三六", "男", "6", "12365478910",  "翻斗花园", "翻斗幼儿园", "2023-12-26");
6.2 修改语法

语法

update 表名 set 字段名1 =1, 字段名2 =2, 字段名3 =3, ..., 字段名n = 值n where id = 1;

update ch_student set classes = "翻斗小学" where id = 1;

update ch_student set username = "法外狂徒李四",  classes = "翻斗小学" where id = 2;
6.3 删除语句

语法

//删除所有记录(清空)
delete from 表名;

//根据条件删除
delete from 表名 where 条件;

delete from ch_student where id = 1;
6.4 查询操作
//查询所有记录
select * from 表名;

//查询单个字段的值
select 字段名1 from 表名;

select username from ch_student;

//查多个字段的值
select 字段名1 , 字段名2 from 表名;

select username, age from ch_student;

备注:

  • 任何一条sql语句都是以";"结束
  • sql语句不区分大小写

在sql语句中可以使用as关键字起别名, 当然在语句中as关键字可以默认省略

select username as "姓名" from ch_student;

//或者省略as关键字
select username "姓名" from ch_student;

//或者
select username 姓名 from ch_student;

备注:

在sql语句中不使用引号也不会报错, 但按照语法来说, 还是给定义的别名使用单引号

6.5 排序查询

语法

select 列名 from 表名 order by 排序列名 [排序规则]

排序规则:

  1. asc: 升序排序 (默认排序)

  2. desc: 降序排序

    //但进行升序排列时, 排序规则可以不显示声明, 默认为升序排序规则
    select * from ch_student order by id asc; //升序
    select * from ch_student order by id desc; //升序
    
6.6 条件查询

语法

//where条件: 在查询结果中筛选符合条件的记录
select * from 表名 where 条件
  1. 等值判断(=)

    select * from ch_student where username = '法外狂徒李四';
    
  2. 不等值判断(>, < , >=, <=, !=, <>)

    select * from ch_student where username != '法外狂徒李四'; 
    //或者
    select * from ch_student where username <> '法外狂徒李四';
    
  3. 逻辑判断(and , or, not)

    //查询工资为[5000, 10000]的员工信息
    select * from emp where salary>= 5000 and salary <= 10000;
    
    //查询工资为5000或者10000的员工信息
    select * from emp where salary= 5000 or salary = 10000;
    
    //查询除了工资是10000的员工信息
    select * from emp where salary not  salary=10000;
    
  4. 区间判断(between, and)

    //区间判断: 包含区间边界的两个值[5000, 10000];
    select * from emp where salary between  5000 and 10000;
    

    注意: between and 要遵循between 小值 and 大值

  5. 枚举查询(in (值1, 值2, 值3))

    //查询工资为5000, 6000, 7000的员工
    select * from emp where salary in (5000, 6000, 7000);
    
  6. 模糊查询like(_, %)

    语法:

    // like _ (表示单个任意字符)
    // like % (表示任意长度的任意字符)
    
    //查询结尾为四的字符串 尾匹配
    select * from ch_student where username like '%四';
    
    //查询以李开头的字符串 头匹配
    select * from ch_student where username like '法%';
    
    //查询包含四的字符串
    select * from ch_student where username like '%四%';
    
    //查询第二个字符为外的字符串
    select * from ch_student where username like '_外';
    
  7. 分页limit

    在进行数据库表查询操作中, 一般都知道使用select语句进行查询, 但是当数据量较大时, selet查询就表示很方便, 这时分页查询就派上了用场,

    在MySql中使用limit关键字来进行分页. limit实现分页的方式是读取数据库表中的部分数据

    语法:

    //pageNum页码, pageSize每页显示记录
    select * from ch_student limit 0, 3;  //第一页(1-1) * 3 = 0
    select * from ch_student limit 3, 3;  //第二页(2-1) * 3 = 3
    select * from ch_student limit 6, 3;  //第三页(3-1) * 3 = 6
    select * from ch_student limit 9, 3;  //第三页(4-1) * 3 = 9
    

    分页通用公式:

    //pageNum: 当前页,  pageSize: 每页显示的记录数
    select * from 表名 limit (pageNum - 1) * pageSize, pageSize;
    
  8. count()函数

    作用: 获取数据库表的总记录

    //数据库表 总记录
    select  count(*) from 表名;
    
    //根据字段查询总记录数
    select  count(username) from 表名;
    

Maven

Apache Maven是一个(特别是Java编程)项目管理及自动构建工具,由Apache软件基金会所提供。基于项目对象建模(缩写:POM)概念,Maven利用一个中央信息片断能管理一个项目的构建、报告和文档等步骤。

下载地址: Maven – Download Apache Maven

解压路径: 随意

配置环境变量:

在path中配置: 解压路径下\apache-maven\bin

测试: mvn -v

配置maven镜像

  1. 设置镜像资源存储路径

    在setting.xml中settings标签里面配置存储地址

    //设置本地仓库
    <localRepository>在这里配置</localRepository>
    
  2. 配置阿里的镜像地址

    //在mirror标签中配置      
    	<mirror>
              <id>alimaven</id>
              <name>aliyun maven</name>
              <url>
                  http://maven.aliyun.com/nexus/content/groups/public/
              </url>
              <mirrorOf>all</mirrorOf>
          </mirror>
          <mirror>
              <id>aliyunmaven</id>
              <mirrorOf>*</mirrorOf>
              <name>阿里云公共仓库</name>
              <url>https://maven.aliyun.com/repository/public</url>
          </mirror>
    

JDBC数据库连接操作

JDBC(java数据库连接) 是一种用于执行sql语句的javaAPI, 可以为多种关系数据库做统一的操作, 其由一组java语言编写的类分和接口组成

在这里插入图片描述

JDBC本质: java官方提供的一套规划(接口), 用于帮助开发人员快速实现不同关系型数据库的连接

JDBC是由多个接口和类进行功能实现

类型名称描述
classDriverManager管理多个数据库驱动类, 提供了获取数据库连接的方法
接口Connection表示数据库连接
接口Statement发送sql语句到数据库的工具
接口ResultSet保存sql查询语句的结果数据(结果集)
classSQLException处理数据库应用程序时所发生的异常
  1. Connection对象

    JDBC实现MySql连接数据库

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    
    public class DbTest {
        private static final String URL = "jdbc:mysql://localhost:3306/ch_db";
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接对象
            Connection connection = DriverManager.getConnection(URL, "root", "1234");
            if(connection != null){
                System.out.println("数据库连接成功!");
            }else {
                System.out.println("数据库连接失败!");
            }
        }
    }
    
    
  2. Statement对象

    通过Connection对象获取Statement对象, 用于对数据库进行通用访问

    PreparedStatement pre = connection.prepareStatement(sql); //传入sql语句
    

    preparedstatement()方法传入sql语句可以预防sql注入

    优点: 防止sql注入, 提高代码可读性, 运行效率

    preparedstatement接口提供了两个方法进行数据库表的操作:

    • executeQuery(): 主要用于执行查询操作, 此方法返回ResultSet对象
    • executeUpdate(): 主要用于执行(添加, 修改, 删除)的操作, 执行完成之后返回int类型的结果值, 这个值是受影响的行
  3. ResultSet对象

    在执行查询sql后, 存放查询得到的结果集数据

    ResultSet resultSet = statement.executeQuery(sql);
    

    遍历ResultSet中的数据

    ResultSet以表结构进行临时结果的存储, 需要通过JDBC API将其中的数据进行 依次获取

    • 数据行指针(resultSet.next()): 初始化位置在第一行数据前, 每调用一次boolean返回值类型的next()方法, 指针向下移动一行, 结果为true表示当前行有数据
    • resultSet.getXXX(“列名”): 根据列名获取数据
    package com.example;
    
    
    import java.sql.*;
    
    public class DbTest {
        private static final String URL = "jdbc:mysql://localhost:3306/ch_db";
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            //加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //获取连接对象
            Connection connection = DriverManager.getConnection(URL, "root", "1234");
            if(connection != null){
                System.out.println("数据库连接成功!");
            }else {
                System.out.println("数据库连接失败!");
            }
    
            //获取Statement对象
            assert connection != null;
            Statement statement = connection.createStatement();
            //执行sql操作
            String sql = "select * from ch_db.ch_student";
            ResultSet resultSet = statement.executeQuery(sql);
    
            //处理结果集
            while (resultSet.next()){ //判断结果集中是否有下一行
                int id = resultSet.getInt("id");
                String username = resultSet.getString("username");
                String sex = resultSet.getString("sex");
                String phone = resultSet.getString("phone");
                Date birthday = resultSet.getDate("birthday");
                String classes = resultSet.getString("classes");
                System.out.println(id + "\t" + username+ "\t"+ sex+ "\t"+ phone+ "\t"+ birthday+ "\t"+ classes);
            }
            //释放资源: 后进先出
            resultSet.close();
            statement.close();
            connection.close();
        }
    }
    
    
    
  4. 小结:

    JDBC实现MySql数的步骤据库连接的步骤

    • 导入数据库驱动(数据库依赖)
    • 注册驱
    • 获取数据库连接对象(Connection)
    • 获取执行对象(PreparedStatement对象)
    • 执行sql语句并返回结果
    • 处理结果
    • 释放资源

    综合案例:

    1. 修改id = 8 的用户信息(修改电话, 地址信息)

       public static void executeUpdateTest() throws ClassNotFoundException, SQLException {
              //加载驱动
              Class.forName("com.mysql.cj.jdbc.Driver");
              //获取连接对象
              Connection connection = DriverManager.getConnection(URL, "root", "1234");
              if (connection != null) {
                  System.out.println("数据库连接成功!");
              } else {
                  System.out.println("数据库连接失败!");
              }
      
              //获取Statement对象
              assert connection != null;
              Statement statement = connection.createStatement();
              //执行sql操作
              String sql = "insert into ch_db.ch_student(username, sex,  phone, birthday,  classes)" +
                      "values ('马克斯', '男', '123556532', '1988-12-3', '软件1班')";
              int result = statement.executeUpdate(sql);
      
              if (result > 0) {
                  System.out.println("执行成功!");
              } else {
                  System.out.println("执行失败!");
              }
      
          }
      
    2. 根据用户名来查询某条记录(李四)

    3. 添加一条记录

    4. 模糊查询(查询名字中带"三"的用户)

    5. 根据电话和班级查询某个用户信息

      public static void executeQueryByUsername() throws ClassNotFoundException, SQLException {
              Class.forName("com.mysql.cj.jdbc.Driver");
              //获取连接对象
              Connection connection = DriverManager.getConnection(URL, "root", "1234");
              if(connection != null){
                  System.out.println("数据库连接成功!");
              }else {
                  System.out.println("数据库连接失败!");
              }
      
              String sql = "select * from ch_db.ch_student where username = ? and classes = ?";
              assert connection != null;
              PreparedStatement pre = connection.prepareStatement(sql);
      
              pre.setString(1, "李四");
              pre.setString(2, "21软件1");
      
              ResultSet resultSet = pre.executeQuery();
              while (resultSet.next()){ //判断结果集中是否有下一行
                  int id = resultSet.getInt("id");
                  String username = resultSet.getString("username");
                  String sex = resultSet.getString("sex");
                  String phone = resultSet.getString("phone");
                  Date birthday = resultSet.getDate("birthday");
                  String classes = resultSet.getString("classes");
                  System.out.println(id + "\t" + username+ "\t"+ sex+ "\t"+ phone+ "\t"+ birthday+ "\t"+ classes);
              }
          }
      

数据库连接池

常用的数据库连接池有: DBCP, C3PO, Druid, HikariCP(SpringBoot)

Druid连接池

Druid: 阿里开源数据库连接池, 功能强大, 是java语言最好的数据库连接池之一, 同时加入了日志监控, 可以很好的监控数据库连接qing’k和sql语句的执行情况

使用步骤:

  • 导入Druid依赖

     <dependency>
              <groupId>com.alibaba</groupId>
              <artifactId>druid</artifactId>
              <version>1.1.20</version>
          </dependency>
    
  • 定义连接数据库的配置文件

    在resource文件夹中, 创建druid.properties

    driverClassName = com.mysql.cj.jdbc.Driver
    url = jdbc:mysql://localhost3306/ch_db
    username = root
    password = 1234
    
  • 加载配置文件

  • 获取连接池

  • 通过连接池获取连接

单元测试

  @Test
    public void jdbcTest() throws Exception {
        //获取配置文件流对象
        InputStream inputStream = DruidTest.class.getClassLoader().getResourceAsStream("druid.properties");

        //创建Properties对象加载配置文件
        Properties properties = new Properties();
        properties.load(inputStream);

        //获取连接池对象
        DataSource dataSource = DruidDataSourceFactory.createDataSource(properties);
        //获取连接对象
        Connection connection = dataSource.getConnection();
        System.out.println(connection);
        if (connection != null){
            System.out.println("连接数据库成功!");
        }else {
            System.out.println("连接数据库失败!");
        }
    }

DBUtils工具类

如果只使用JDBC进行开发, 通过其学习和实验发现进行相关CRUD操作时, 存在大量冗余代码, 为了简化JDBC是实使用和开发, 可以采用Apache common组件: DBUtils工具类实现.

DBUtils对JDBC的操作进行优化和封装, 其提供了三个核心功能

  • QueryRunner: 提供了对sql语句操作的API
  • ResultSetHandler: 用于定义select操作后结果集的处理
  • DBUtils类: 关闭资源和事物处理的方法

加载DBUtils工具类的依赖

 <dependency>
      <groupId>commons-dbutils</groupId>
      <artifactId>commons-dbutils</artifactId>
      <version>1.7</version>
    </dependency>
1. Update
 public int update(java.lang.String sql, java.lang.Object... params) throws java.sql.SQLException { /* compiled code */ }

备注:

  • update()方法用于执行DML(增, 删, 改)的操作
  • Object… params: 动态参数(动态数组)

测试案例:

    @Test
    public void queryRunnerUpdate() throws SQLException {
        QueryRunner queryRunner = new QueryRunner( DruidUtils.getDataSource());
        String sql = "update ch_db.ch_student set username = ?, age = ? where id = ?";
        Object[] object = {"胡爷爷", 59, 11};
        int result = queryRunner.update(sql, object);
        if (result > 0){
            System.out.println("更新成功!");
        }else {
            System.out.println("更新失败");
        }

    }

QueryRunner类基于update()的通用性操作封装的方法

public class BaseDao {

    static QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());

    /**
     *
     * @param sql
     * @param objects
     * @return 增删改的结果集
     * @throws SQLException
     */
    public static int update(String sql, Object... objects) throws SQLException {
        return queryRunner.update(sql, objects);
    }
}

2. query()
public <T> T query(java.lang.String sql, org.apache.commons.dbutils.ResultSetHandler<T> rsh) throws java.sql.SQLException { /* compiled code */ }

通过对底层源代码的分析, query()方法的结果是, 其通过ResultSetHandler接口的实现对结果进行预处理

开发过程中常用的实现方式有:

  1. ArrayListHandler: 将结果集中的每一条记录封装到一个Object[]数组中, 再将这些数组再次封装到List集合中
  2. BeanListHandler: 加结果集中的每一条记录封装到一个指定的JavaBean中, 再将JavaBean封装到List集合
  3. ScalarHandler: 用于单数据, 可以用于获取中记录数

单元测试:

  @Test
    public void queryArrayListHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner( DruidUtils.getDataSource());
        String sql = "select * from ch_db.ch_student";
        //将结果集的封装到Object数组中
        List<Object[]> list = queryRunner.query(sql, new ArrayListHandler());

        for (Object[] objects:list){
            System.out.println(Arrays.toString(objects));
        }
    }

    @Test
    public void queryBeanListHandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner( DruidUtils.getDataSource());
        String sql = "select * from ch_db.ch_student";
        List<Student> list = queryRunner.query(sql, new BeanListHandler<Student>(Student.class));

        for (Student student : list){
            System.out.println(student.toString());
        }
    }

    @Test
    public void queryScalarhandler() throws SQLException {
        QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());
        String sql = "select count(*) from ch_db.ch_student";
        long count = queryRunner.query(sql, new ScalarHandler<>());
        System.out.println("总记录数:" + count);
    }

总结:

使用Druid和DBUtils简化JDBC的操作, 封装了通用性的实现类, 但在实际开发过程中, 涉及到的业务和模块非常复杂, 为了更好的进行业务开发和后期的维护和迭代, 其需要进一步统一化的操作和分层组织:

企业开发过程中的一些行为规划:

  • 项目名称: 全部字母小写, 不要使用中文, 数组, 特殊符号等相关来命名
  • 包名: com.项目名称(公司名称) .具体名称 eg:com.ch.bean
  • 类名: 类名首字母大写, 采用大驼峰命名规则: eg: StudentDao
  • 方法名: 首字母小写, 采用小驼峰命名规则: eg: findById()
  • 变量名: 采用小驼峰命名规则, 不要包含中文, 数组, 特殊符号等
  • 常量: 每个单词都是大写

分层架构

在软件体系架构设计中, 分层式架构是最常见, 也是最重要的一种架构, 分层架构一般分为三层, 从下至上分别为:

  • 数据访问层: 为业务逻辑层和表示层提供数据
  • 业务逻辑层: 主要针对具体的问题的操作, 也可以理解为对数据层的操作
  • 表示层: 展示数据

在这里插入图片描述

在实际项目中的分层结构如下:

  • com.ch.dao: Dao包(接口包) /接口实现
  • com.ch.utils: 工具包
  • com.ch.bean: 实体包
  • com.ch.servlet: 业务包

封装通用的Dao接口

public class BaseDao {

    static QueryRunner queryRunner = new QueryRunner(DruidUtils.getDataSource());

    /**
     *
     * @param sql
     * @param objects
     * @return 增删改的结果集
     * @throws SQLException
     */
    public static int update(String sql, Object... objects) throws SQLException {
        return queryRunner.update(sql, objects);
    }

    /**
     *
     * @param type
     * @param sql
     * @param objects
     * @return 返回单个对象
     * @param <T>
     * @throws SQLException
     */
    public <T>T query(Class<T> type, String sql, Object... objects) throws SQLException {
        return queryRunner.query(sql, new BeanHandler<T>(type), objects);
    }

    /***
     *
     * @param type
     * @param sql
     * @param objects
     * @return 列表
     * @param <T>
     * @throws SQLException
     */
    public <T> List<T> queryAll(Class<T> type, String sql, Object... objects) throws SQLException {
        return queryRunner.query(sql, new BeanListHandler<>(type), objects);
    }

    /**
     *
     * @param sql
     * @param objects
     * @return 返回行数据
     * @param <T>
     * @throws SQLException
     */
    public <T> List<T> selectCount(String sql, Object... objects) throws SQLException {
        return queryRunner.query(sql, new ScalarHandler<>(), objects);
    }
}

案例项目分析

案例引入

1. 商城类型:

  • B2B: 商家对商家 eg: 阿里巴巴, 慧聪网
  • B2C: 商家对客户 eg: 当当网, 京东
  • C2C: 客户对客户 eg: 淘宝, 拼多多
  • O2O: 线上线下相结合 eg: 美团, 滴滴

2. 常见模块

  • 商品管理: 后台商品库存管理, 上货, 出货, 编辑商品和商品分类管理等
  • 订单管理
  • 支付管理
  • 物流管理
  • 会员模块
  • 广告管理

3. 项目功能介绍

本系统主要分为前台和后台功能两个大模块

其中前台功能主要的模块有: 商品列表, 商品分类查看, 我的购物信息, 个人信息, 广告位

后台管理主要模块有: 商品信息管理, 用户信息管理, 管理员个人中心

在这里插入图片描述

管理员: 管理是商品, 管理用户, 个人信息, 广告位, 数据中心

用户用例图

在这里插入图片描述

前置条件: 用户注册成功

后置条件: 用户登录成功

重点: 查看商品信息, 把商品加入购物车, 对商品进行结算和支付

主要事件流程:

  1. 加入登录界面
  2. 登陆成功, 用例开始
  3. 登陆成功跳转到首页
  4. 分类列表查看商品信息
  5. 点击"商品图片"查看商品详细信息
  6. 点击"加入购物车"把商品记录购物车
  7. 点击"我的购物车"把商品查看购物车商品信息
  8. 点击"结算"即可结算商品
  9. 点击"我的订单"可以查看结算商品的信息
  10. 点击"支付"即可对商品进行支付
  11. 点击删除购物车中的商品
  12. 点击"个人信息"查看或者修改

4. 数据库设计

  • 用户表 (tb_user)

    字段类型主键约束备注
    idint自增序号
    usernamevarchar(20)not null用户昵称
    passwordvarchar(60)not null用户密码
    emailvarchar(60)not null
    gendervarchar(2)性别
    flagint默认值状态标记: 0未激活, 1激活, 2无效
    roleint角色: 0管理员, 1会员
    codevarchar(100)激活码
    picturevarchar(50)图像
    createtimevarchar(50)注册时间
  • 商品表 (tb_goods)

    字段类型主键约束备注
    idint自增主键
    namevarchar(50)not null类型名称
    pubdatevarchar(20)not null时间
    picturevarchar(20)not null图片
    pricedouble(7, 2)not null价格
    stardouble(2, 1)评分
    infovarchar(60)商品信息
    typeidint外键商品类型
    gunmint默认1024商品数量[库存]
    gstateint默认0商品状态: 0上架, 1下架
    createtimevarchar(50)not null入库时间
  • 商品类型表 (tb_goods_type)

    字段类型主键约束备注
    idint自增主键
    namevarchar(50)not null类型名称
    niocvarchar(20)not null图标
    levelintnot null类型级别
    parentintnot null上一级序号: 默认0
  • 购物车表 (tb_cart)

    字段类型主键约束备注
    idint自增主键
    pidint外键商品序号
    numintnot null数量
    moneydouble(8,2)金额
  • 订单表 (tb_order)

    字段类型主键约束备注
    idvarchar(80)自增订单编号
    uidint外键用户序号
    moneydouble(8,2)not null订单总金额
    ordertimedatatimenot null订单时间
    statusint订单状态
    aidint外键收货地址序号
  • 订单详情表 (tb_orderdetail)

    字段类型主键约束备注
    idint自增主键
    oidint外键订单id
    pidint外键商品id
    numintnot null购买数量
    moneydouble(8,2)not null金额
  • 地址表 (tb_address)

    字段类型主键约束备注
    idint自增主键
    detailvarchar(80)not nulll详细地址
    namevarchar(20)not null收件人姓名
    phonevarchar(20)not null手机号码
    levelintnot null地址顺序 1是最高
    creatimevarchar(20)创建时间

Hutool工具集

Hutool是一个小而全的Java工具类库,通过静态方法封装,降低相关API的学习成本,提高工作效率,使Java拥有函数式语言般的优雅,让Java语言也可以“甜甜的”。

官网API: 简介 | Hutool

验证码测试:

//URL: http://localhost:8080/chMaven_war/ServletCapthcha
@WebServlet(value = "/ServletCapthcha", name = "ServletCapthcha")
public class ServletCaptcha extends HttpServlet {
    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
    }

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

        //定义图形验证码的长、宽、验证码字符数、干扰线宽度
        ShearCaptcha captcha = CaptchaUtil.createShearCaptcha(200, 100, 4, 4);

        OutputStream out = resp.getOutputStream();

        //写到浏览器
        captcha.write(out);

        //获取生成的验证码
        String code = captcha.getCode();
        System.out.println("====> 验证码: " + code);

        //验证图形验证码的有效性, 返回boolean值
        //验证码验证是否正确, 建议忽略大小写
        System.out.println(captcha.verify(code));
        out.close();
    }
}

  • 18
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值