Java:Web工程介绍、重写单条、多条记录查询与实现、MySQL中float,double字段的查询

6 篇文章 0 订阅
1 篇文章 0 订阅

一、Web项目介绍

web项目:通俗的说就是在服务器上跑的项目,页面是通过服务器上的程序运算所得到的的结果
Javaweb项目:用Java代码写的web项目

二、Web工程中项目分层介绍

POJO —— 实体类 com.openlab.pojo
DAO —— 数据链路层 com.openlab.dao
Service —— 业务层 【接口】 com.openlab.service
Impl —— 业务层 【接口的实现】com.openlab.service
servlet —— 控制层 controller

在这里插入图片描述

三、问什么要分层

  1. 为了方便项目管理,PMP项目管理
  2. 顶多能给你的是就是接口
  3. 类和类之间的松耦合
  4. 非常方便分工处理 方便代码的维护和扩展
  5. 面向对象思想 主要的要求就是让每一个类的功能都是单一化
  6. 提高代码的重复利用率

四、Web工程例题

连接数据库,完成数据库查询业务

1. JDBCUtil新改写的类中

1.2 单条记录的查询

步骤:

  1. 由于查询语句最终需要返回一个语句,但不确定是什么类型。——所以我们将其返回值设置为 Object 类(万物都是Object);
  2. 照常进行connection与statement的连接;
  3. 将传入sql语句利用statement类的executeQuery()方法来下达select指令以查询数据库;
  4. 最后将有数据库相应的查询结果ResultSet类对象,转化为Object类进行最终返回。
  5. 无论是否返回错误,都要关闭资源(放在finally中),最终在try外进行返回
//单条记录的查询
public Object QueryByOne(String sql){
  Object obj = null;
  try {
        conn = getConnection();
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery(sql);
        obj = rsToObj(rs);
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        jdbcClose(conn,st);
    }
    return list;
}
1.2 多条记录的查询

步骤:

  1. 与单条查询相似,但返回值为LIst ArrayList;
  2. 注意ResultSet转化为List函数与单句查询不同。
  3. 无论是否返回错误,都要关闭资源(放在finally中),最终在try外进行返回
//多条记录的查询 List ArrayList
public List QueryByAll(String sql){
    List list = null;
    try {
        conn = getConnection();
        Statement st = conn.createStatement();
        ResultSet rs = st.executeQuery(sql);
        list = rsToList(rs);
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        jdbcClose(conn,st);
    }
    return list;
}
1.3 添加抽象方法
public abstract Object rsToObj(ResultSet rs);
public abstract List rsToList(ResultSet rs);

2. 确定需求后,建立工程

构建相应包
com.openlab.pojo
com.openlab.dao
com.openlab.service
com.openlab.service.impl

2.1 构建实体类 com.openlab.pojo

步骤:

  1. 创建自己的雇员实体类
  2. 实现其构造,get,set,Tostring方法
//领域对象层
public class Employee {
    private String username;
    private int age;
    private float salary;

    public Employee() {
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public float getSalary() {
        return salary;
    }

    public void setSalary(float salary) {
        this.salary = salary;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "username='" + username + '\'' +
                ", age=" + age +
                ", salary=" + salary +
                '}';
    }
}
2.2 创建业务接口 com.openlab.service

步骤:

  1. 编写业务将要实现的的方法接口
  2. 注意返回类型根据输出有所不同
  3. 传入参数类型无特殊要求,age的int也可改为String
//业务层接口
public interface EmployeeService{
    public Employee queryByusername(String username);
    public List queryByage(int age);
    public Employee queryBysalary(float salary);
}
2.3 数据链路层 com.openlab.dao

由于我们写的JDBCUtils 是抽象类,无法自身实现实例化,所以我们利用数据链路层进行实例化。

步骤:

  1. 继承JDBCUTils 实现其抽象方法
  2. 创建雇员对象
  3. 利用pojo中的方法,如果其有值,进行输出
  4. 注意返回值为Object与List,要进行转化
  5. 注意单条与多条查询,在判断有无值输出时,单条为 if 判断,多条为 while 判断
  6. 注意:在多记录查询中,List表的添加方式与单记录有所不同
//数据链路层
public class EmployeeServiceDao extends JDBCUtil{

    @Override
    public Object rsToObj(ResultSet rs) {
        Object obj = null;
        try {
            Employee emp = new Employee();
            if(rs.next()){
                emp.setUsername(rs.getString("username"));
                emp.setAge(rs.getInt("age"));
                emp.setSalary(rs.getFloat("salary"));
                obj = emp;
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return obj;
    }

    @Override
    public List rsToList(ResultSet rs) {
        List list = new ArrayList();
        try {
            Employee emp = new Employee();
            while(rs.next()){
                emp.setUsername(rs.getString("username"));
                emp.setAge(rs.getInt("age"));
                emp.setSalary(rs.getFloat("salary"));
                list.add(emp);
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return list;
    }
}
2.4 业务接口实现com.openlab.service.impl

步骤:

  1. 创建数据链路层对象,方便调用
  2. 完善SQL查询语句
  3. 调用数据链路层Dao中的方法进行ResultSet与Object之间的转换
  4. 最终根据所要输出的类型将Object转成所需对应类型,并进行返回
  5. 注意注意注意!!:float由于自身原因,无法进行精确查找,当查询语句为select * from tb1 where salary=23000.3;时查询结果为null,由于float无法进行精确查询,详情请看下文。
public class EmployeeServiceimpl implements EmployeeService {


    EmployeeServiceDao edao = new EmployeeServiceDao();
    @Override
    public Employee queryByusername(String username) {
        String sql = "select * from tb1 where username='"+username+"'";
        Object o = edao.QueryByOne(sql);
        Employee emp = (Employee) o;
        return emp;
    }

    @Override
    public List queryByage(int age) {
        String sql = "select * from tb1 where age='"+age+"'";
        List list = edao.QueryByAll(sql);
        return list;
    }

    @Override
    public Employee queryBysalary(float salary) {
        String sql = "select * from tb1 where salary like "+salary;
        Object o = edao.QueryByOne(sql);
        Employee emp = (Employee) o;
        return emp;
    }
}
2.5 测试 com.openlab.test
public class EmployeeServiceImplTest {

    EmployeeServiceimpl eimpl = new EmployeeServiceimpl();
    @Test
    public void test(){

        Employee e = eimpl.queryByusername("zhangsan");
        System.out.println(e);
        //或者运用该方法,前者为期望中的值,后者为实际中的值,将其进行比对
        TestCase.assertEquals("zhangsan",e.getUsername());
    }

    @Test
    public void test1(){
        List list = eimpl.queryByage(23);
        System.out.println(list);
        TestCase.assertEquals(2,list.size());
    }

    @Test
    public void test2(){
        Employee e = eimpl.queryBysalary(23000.3f);
        System.out.println(e);

    }
}

附: MySQL中的float,double字段,查询为null??

在MySQL中,字段类型为Float的字段,如果不指定FLoat的长度和小数位数,要根据float字段的值精确查找,结果会为空。

在这里插入图片描述

是由于类似于直接 “ = ” 这种精确查找,是查不到任何结果的。
原因:在MySQL中,float是福电视,MySQL存储的时候是近似值,所以用精确查找无法匹配;但是可以用like匹配。

在这里插入图片描述

select * from tb1 where salary like 23000.3;
select * from tb1 where salary like '23000.3';
select * from tb1 where salary like '%23000.3%';
select * from tb1 where salary like '23000.3%';

同理, 以上四种均可以查到结果。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 可以使用Java8的Stream API来实现这个功能。 假设ListB的元素对象为类B,有两个字段key和timestamp,其key表示某个实体的唯一标识,timestamp表示该实体的更新时间。 代码实现如下: ``` List<B> listB = ... Map<String, B> latestEntities = listB.stream() .collect(Collectors.toMap(B::getKey, Function.identity(), (entity1, entity2) -> entity1.getTimestamp() > entity2.getTimestamp() ? entity1 : entity2)); List<B> result = new ArrayList<>(latestEntities.values()); ``` 首先将ListB转换成一个Map,key为实体的唯一标识,value为实体对象。如果有多个实体对象的key相同,则使用lambda表达式指定如何选择最新的实体对象。最后将Map的值转换成List返回即可。 注意:使用Stream API时需要保证B类实现了equals和hashCode方法,以便在Map正确地识别唯一实体。 ### 回答2: 在Java8,可以通过使用Java Stream和Lambda表达式来实现对ListB多个key字段相同时只保留最新一条数据的操作。 假设ListB的元素类型为B,其B包含多个key字段。我们需要按照多个key字段来进行分组,并从每个分组只取出最新的一条数据。 首先,我们可以使用Stream的collect方法来对ListB进行分组,并将分组后的结果存储在Map。分组的依据是将B对象多个key字段的值作为一个新的对象作为Map的key。代码如下: ```java Map<KeyObject, List<B>> groupByKeys = listB.stream() .collect(Collectors.groupingBy(b -> new KeyObject(b.getKey1(), b.getKey2(), ...))); ``` 其KeyObject是一个自定义的对象类,用来作为Map的key。在KeyObject类,需要重写equals和hashCode方法,以确保相同的key字段值被认为是相等的对象。 接下来,我们可以使用Stream的map方法来对每个分组的元素按照某个时间字段进行排序,并将排序后的结果存储在一个新的List。代码如下: ```java List<B> result = groupByKeys.values().stream() .map(group -> group.stream() .sorted(Comparator.comparing(B::getTime).reversed()) // 按时间字段降序排序 .findFirst() .get()) .collect(Collectors.toList()); ``` 在map方法,首先使用sorted方法对每个分组的元素按照时间字段进行降序排序,然后使用findFirst方法获取排序后的第一个元素,即最新的一条数据。 最后,将得到的结果存储在一个新的List。 综上所述,通过使用Java8的Stream和Lambda表达式,我们可以很方便地实现对ListB多个key字段相同时只保留最新一条数据的操作。 ### 回答3: 在Java8,可以使用Stream的特性来实现ListB多个key字段相同时只保留最新一条数据的操作。 假设ListB的元素是一个自定义的实体类对象,包含多个字段,其也包含key字段用于判断唯一性和比较最新日期。 首先,我们可以通过Stream的groupingBy()方法将ListB按照key字段进行分组,这样就能将相同key的元素分到同一个组。 然后,我们可以使用Stream的max()方法结合Comparator.comparing()方法来找到每个分组最新的一条数据。例如,可以使用Lambda表达式来实现: ListB.stream() .collect(Collectors.groupingBy(Entity::getKey)) .values() .stream() .map(group -> group.stream().max(Comparator.comparing(Entity::getDate)).orElse(null)) .collect(Collectors.toList()); 上述代码首先将ListB根据key字段进行分组,然后将分组后的value集合进行Stream操作。对于每个分组的value集合,通过max()方法和Comparator.comparing()方法比较日期字段,找到最新的一条数据。然后通过map()方法将每个分组的最新数据提取出来,最后通过collect()方法将结果转换为List集合。 最后,得到的List集合就只保留了每个key字段最新的数据。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值