JAVA集中学习第四周学习记录(一)

系列文章目录

第一章 JAVA集中学习第一周学习记录(一)
第二章 JAVA集中学习第一周项目实践
第三章 JAVA集中学习第一周学习记录(二)
第四章 JAVA集中学习第一周课后习题
第五章 JAVA集中学习第二周学习记录(一)
第六章 JAVA集中学习第二周项目实践
第七章 JAVA集中学习第二周学习记录(二)
第八章 JAVA集中学习第二周课后习题
第九章 JAVA集中学习第二周学习记录(三)
第十章 JAVA集中学习第二周学习记录(四)
第十一章 JAVA集中学习第三周学习记录(一)
第十二章 JAVA集中学习第三周小组项目开发
第十三章 JAVA集中学习第四周学习记录(一)



前言

以员工管理系统举例,介绍了数据库,如何在java中对数据库进行操作,如何进行多表查询,如何提取对数据库的操作成为DBHelper类,如何实现分页。


一、员工管理系统

1. 创建数据库、表,添加测试数据:

2. 熟记每张表中每个字段的意思

emp员工表
empno:4位整数的员工编号(自增)
ename:汉字(四个)
job:岗位名称
mgr:经理编号(也是经理员工编号)
hiredate:入职时间
sal:工资
comm:奖金
deptno:部门编号

dept部门表:
deptno:部门编号
dname:部门名称
loc:部门所在地

salgrade工资等级表:
grade:工资等级
losal:同等级的最低工资
hisal:同等级的最高工资

bonus局部信息表(封装数据):
ename:员工名字
job:岗位名称
sal:工资
comm:奖金

3. 创建java项目

导入连接数据库的jar包

4. 介绍sql语句:

sql结构化(面向过程)查询语言
作用: 对数据库里的数据做管理
sql组成部分: DQL、DML、TCL、DCL、DDL

4.1 DQL数据查询语言(查询)

select 字段名1, 表名.字段名2, (所有数据为*(不能用索引)一般不用)
from 表名1, 表名2
where 字段1 = 值 and/or 字段2 = 值(分组前的删选条件)
group by 字段名
having 字段 = 值 and/or 字段2 = 值(分组后的筛选条件)
order by 字段名 [desc/不写为正序] 排序

4.2 DML数据管理语言(增删改)

4.2.1 新增

一次增加多行:不常用
一次增加一行:
insert into 表名(列1, 列2, 列3) values(值1, 值2, 值3)
1、列允许为空,添加的时候可以不给值;不允许为空,必须给值
2、列设为自增:values(null, )自动增加一
3、列设置为默认值:values(default, )
4、如果给表里的所有字段都添加,可以写成insert into 表 values(值1, 值2, 值3)

4.2.2 删除

delete from 表名 where empno = ?

4.2.3 修改

update 表 set 列 = 值, 列 = 值 where 主键 = ?

4.3 TCL事务的控制语言

java程序中的TCL,主要学习什么是事务

4.4 DCL数据控制语言

授予、撤回权限、角色

4.5 DDL数据的定义语言

创建、删除、修改一切数据库对象

5. PreparedStatement执行对象:

executeQuery():执行查询语句,返回类型为ResultSet
executeUpdate():执行增删改语句,返回类型为int(受影响的行数,0为没有受影响)
execute():执行sql语句,返回类型为boolean(sql语句是否正确执行)

原来叫Statement,有隐患“sql注入”,现在都用PreparedStatement

CallableStatement()方法:执行存储过程

为sql命令的?参数赋值:set[类型]
preparedStatement.setString(1, dname);

6. ResultSet结果集对象:

对象.next():判断是否有数据
对象.getString():获取属性值

7. 多表查询的不同种类

1、任务:使用dname查询该部门下员工的所有信息(全部字段)
2、分析字段所处的表:
…dname在dept表
…8个字段在emp表
3、多表查询:

3.1 普通查询:

select e.*, d.dname
from emp e, dept d
where e.deptno = d.deptno and dname = ‘SALES’

3.2 内连接多表查询:

select e.*, d.dname
from emp e inner join dept d on e.deptno = d.deptno(inner join内连接,on表关联)
where dname = ‘SALES’
内连接的两张表,没有主次之分,
所有数据根据关联字段进行判断显示

3.3 外连接多表查询

外连接的两张表有主次之分
主表的数据一定会都显示出来
次表的数据只会显示值对等的
外连接
再查询语句里,出现的第一个表名为左表,第二本表为右表
左外连接:左表是主表,左表数据全显示,右表显示值相等的数据
select e., d.dname
from emp e left join dept d on e.deptno = d.deptno
右外连接:右表是主表,右表数据全显示,左表显示值相等的数据
select e.
, d.dname
from emp e right join dept d on e.deptno = d.deptno

3.4 关联

关联表中,关联列名字要相同才可以用:
select e.*, d.dname
from emp e inner join dept d using (deptno)
where dname = ‘SALES’

3.5 自然关联

关联表中,关联列名字要相同、类型要相同、字段长度要相同才可以用:
select e.*, d.dname
from emp e natural join dept d
where dname = ‘SALES’

8.Java程序中的对象

实体类对象:entry(不叫pojo了)包里的类,都是对应数据库表的
业务类对象:做参数封装与结果集封装,放在dto包下
dto包下只放业务类对象

9. DBHelper的反射

当我们需要一个对象,但有可能是不同类型时;
当我们需要调用对象的属性,为属性赋值时;
当我们需要调用对象的方法,执行方法时;
我们使用反射,把代码向上提取成一套通用的模板对象

在DBHelper中,我们可能对不同表进行操作,为了不用每个表都要写一个DBHelper方法,我们使用反射来实现DBHelper的多态

1. 使用反射的原理

字节码文件可以视为Class类的对象
我们可以对这个对象进行操作

获得变量类型的4种方式:

Class.forName("全局限定名");
类名.Class;
对象名.getClass();
利用加载器

获得对象: 变量类型对象.newInstance();
获得方法: 变量类型对象.newInstance(方法名);
使用方法: 方法名.invoke(o);

2. 使用全局限定名拿到Class类型对象


        Class classOne = Class.forName("entry.Emp");
        System.out.println(classOne);
        Class classTwo = Emp.class;
        System.out.println(classOne==classTwo);
        Class classThree = new Emp().getClass();
        ClassLoader classLoader = Test.class.getClassLoader();

        Class ClassFour=classLoader.loadClass("entry.Emp");
        System.out.println(classOne == classTwo);
        System.out.println(classTwo == classThree);
        System.out.println(classThree == ClassFour);

3. 获得classOne的构造器

        Constructor[] constructors = classOne.getConstructors();
        Constructor[] declaredConstructors = classOne.getDeclaredConstructors();
        Constructor constructor = classOne.getConstructor();
        Constructor declaredConstructor = classOne.getDeclaredConstructor();
        for (Constructor c :
                constructors) {
            System.out.println(c);
        }
        for (Constructor c :
                declaredConstructors) {
            System.out.println(c);
        }
        System.out.println(constructor);
        System.out.println(declaredConstructor);
        Constructor declaredconstructor = classOne.getDeclaredConstructor(Integer.class);
        declaredconstructor.setAccessible(true);//暴力破解
        Object o1 = declaredconstructor.newInstance(6);
        System.out.println(o1);

        //如果只想使用共有的无参构造
        Object o2 = classOne.newInstance();
        System.out.println(o2);

4. 获得classOne的变量

		Class classOne = Class.forName("entry.Emp");
        Field[] declaredFields = classOne.getDeclaredFields();
        System.out.println(Arrays.toString(declaredFields));
        Field empno = classOne.getDeclaredField("empno");
        System.out.println(empno.getType());
        System.out.println(empno.getModifiers());
        System.out.println(empno.getName());
        empno.setAccessible(true);//告诉虚拟机不用检查修饰符
        Object object = classOne.newInstance();
        empno.set(object, 3355);
        System.out.println(object);

5. 获得classOne的方法

        Class classOne = Class.forName("entry.Emp");
        Method[] methods = classOne.getMethods();
        for (Method m :
                methods) {
            System.out.println(m);
        }
        Method toString = classOne.getMethod("toString");
        System.out.println(toString.invoke(classOne.newInstance()));

6. 做出通用任何表的DBHelper

//12
    public Connection getConcection() {
        Connection connection = null;
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            String url = "jdbc:mysql://127.0.0.1:3308/employee?useSSL=false&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true";
            String username = "root";
            String password = "";
            connection = DriverManager.getConnection(url, username, password);
        } catch (ClassNotFoundException e) {
            //e.printStackTrace();
            System.out.println("mysq1 驱动类地址不对,没有导入jar,ur1路径不对");
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return connection;
    }
    //7
    public void closeAll(ResultSet resultSet, PreparedStatement preparedStatement, Connection connection){
        if (resultSet != null) {
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (preparedStatement != null) {
            try {
                preparedStatement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    //45(1-7汇总)传入3,返回6
    public ArrayList selectInfo(String sql, Class classOne, Object... objects){
        ArrayList list = new ArrayList();
        try {
            Connection connection = getConcection();
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            for (int i = 0; i < objects.length; i++) {
                preparedStatement.setObject(++i, objects[i]);
            }
            ResultSet resultSet = preparedStatement.executeQuery();
            while (resultSet.next()){
                //根据classOne获得该字节码的对象
                Object o = classOne.newInstance();
                //给所有对象属性赋值
                Field[] declaredFields = classOne.getDeclaredFields();
                for (Field f :
                        declaredFields) {
                    f.setAccessible(true);
                    f.set(o, resultSet.getString(f.getName()));
                }
                list.add(o);
            }

            return list;
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        return null;
    }
    }

模糊查询:
select * from emp where ename like ‘%M%’
%表示前面可以有,后面也可以有
select * from emp where ename like ‘__M%’
_表示前面有一位,M排在第三位

单行函数: 不做介绍
多行函数:(求总和sum()、求平均数avg()、求最大值max()、求最小值min()、求总个数count()),聚合函数,分组函数

10. 分页查询

1. 分页的方法介绍

sql语句:
SELECT e.*, d.dname FROM emp e NATURAL JOIN dept d where 1 = 1 LIMIT 3, 3
重点是LIMIT 3, 3:第一个3代表从下标为3的元素开始,第二个3表示只显示三个 (其实不是分页的作用,但能实现分页功能)
五要素:
1、每页显示几条数据
2、一共多少条数据
3、一共能分几页
4、当前是第几页
5、当前页的显示的数据集合

2. 分页的代码实现

PageHelper分页工具类:

public class PageHelper {
    private Integer showData = 3;//每页显示几条数据
    private Integer countData;//一共有多少条数据,需要查数据库
    private Integer countPage;//一共能分多少页
    private Integer indexPage = 1;//当前是第几页,默认为第一页
    private ArrayList<EmpDname> list;//当前页的数据集合

    public PageHelper(Integer showData, Integer countData, Integer countPage, Integer indexPage, ArrayList<EmpDname> list) {
        this.showData = showData;
        this.countData = countData;
        this.countPage = countPage;
        this.indexPage = indexPage;
        this.list = list;}
    public PageHelper() {}
    
    public Integer getShowData() {return showData;}
    
    public void setShowData(Integer showData) {this.showData = showData;}
    
    public Integer getCountData() {return countData;}

    public void setCountData(Integer countData) {
        this.countData = countData;//直到总条数之后,立刻能知道总页数了
        getCountPage();}

    public Integer getCountPage() {
        countPage = countData % showData == 0 ?
                countData / showData :
                countData / showData + 1;
        return countPage;}

/*    public void setCountPage(Integer countPage) {
        this.countPage = countPage;
    }*/

    public Integer getIndexPage() {return indexPage;}

    public void setIndexPage(Integer indexPage) {this.indexPage = indexPage;}

    public ArrayList<EmpDname> getList() {return list;}

    public void setList(ArrayList<EmpDname> list) {this.list = list;}
}

Dao层应用(动态查询):

    @Override
    public ArrayList<EmpDname> getEmpsByDname(QueryEmpDept queryEmpDept, PageHelper pageHelper) {
        //根据部门名称,查询该部门下所有员工信息
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        StringBuffer sql = new StringBuffer("select e.*, d.dname from emp e natural join dept d where 1 = 1");
        ArrayList list = new ArrayList();
        if (queryEmpDept.getEmpno() != null){
            sql.append(" and empno = ?");
            list.add(queryEmpDept.getEmpno());
        }if (queryEmpDept.getEname() != null){
            sql.append(" and ename like ?");
            list.add("%" + queryEmpDept.getEname() + "%");
        }if (queryEmpDept.getDname() != null){
            sql.append(" and dname = ?");
            list.add(queryEmpDept.getDname());
        }if (queryEmpDept.getBegindate() != null){
            sql.append(" and ? <= hiredate");
            list.add(sdf.format(queryEmpDept.getBegindate()));
        }if (queryEmpDept.getEnddate() !=null){
            sql.append(" and hiredate <= ?");
            list.add(sdf.format(queryEmpDept.getEnddate()));
        }
        sql.append(" limit ?, ?");
        list.add((pageHelper.getIndexPage() - 1) * pageHelper.getShowData());
        list.add(pageHelper.getShowData());
        return (ArrayList<EmpDname>) dbHelper.selectInfo(sql.toString(), EmpDname.class, list.toArray());
    }

Service层应用:

    @Override
    public ArrayList<EmpDname> getEmpsByDname() throws ParseException {
        QueryEmpDept queryEmpDept = getQuery();
        PageHelper pageHelper = new PageHelper();
        pageHelper.setCountData(empDao.selectEmpsSize(queryEmpDept));
        ArrayList<EmpDname> empsByDname1 = empDao.getEmpsByDname(queryEmpDept, pageHelper);
        Iterator<EmpDname> iterator1 = empsByDname1.iterator();
        while (iterator1.hasNext())
            System.out.println(iterator1.next());
        int i = 1, a;
        while (i != 0){
            System.out.println("是否显示下一页,输入0退出");
            a = scanner.nextInt();
            if (a != 0){
                pageHelper.setIndexPage(i);
                ArrayList<EmpDname> empsByDname = empDao.getEmpsByDname(queryEmpDept, pageHelper);
                Iterator<EmpDname> iterator = empsByDname.iterator();
                while (iterator.hasNext())
                    System.out.println(iterator.next());
                i++;
            }
            else break;
        }
        return null;
    }

总结

本文以员工管理系统为例,介绍了数据库SQL语言的组成部分、基础使用,介绍了如何进行多表查询,如何使用反射构建所有表通用的DBHelper类,如何构建PageHelper类实现分页功能。想要去ൠ♄§星的人抓紧定票,不要赶不上200年后ൠ♄§星与地球之间的首次通车。

  • 12
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值