JavaBean简介和项目分包

1.JavaBean是什么?

当一个POJO可序列化,有一个无参的构造函数,使用get和set方法来访问属性时,他就是一个JavaBean。

2.JavaWeb项目。

一个简单的Web项目,它的框架大概分为领域对象层pojo、数据链路层Dao、业务层Service和ServiceImpl、控制层Servlet、以及Jsp。下边简单说一下pojo、Dao、Service和ServiceImpl的浅含义。

  • Pojo:刚开始我的理解是pojo其实就是JavaBean,但是实际上不是的。pojo具备业务逻辑的处理能力,只是存在private修饰的属性和set和get访问属性的方法,它不能理解为JavaBean,并且它不能继承父类以及不能实现接口。但是呢,当外界调用pojo时,给予了pojo的JavaBean规则,那么它就成为JavaBean了。
  • Dao:1.封装数据库的的增删查改操作。2.接收业务层接口实现的数据,将pojo转换为po。
  • Po:将对象与关系数据库进行绑定,用对象来表示关系数据库的数据。
  • Service:理解为业务层的接口。
  • ServiceImpl:单词字面上看意为业务层接口的实现。

3.一个简单的JavaWeb项目。

首先,先在数据库创建表并且载入数据,然后通过项目分层以及代码实现,最终获取想要的数据,下边我以我的数据库作为项目数据。这个项目最终我要实现的业务是ID查询和姓名查询。

3.1领域对象层pojo:pojo的含义前边也说过了,按数据库的数据来说,我们需要在pojo里边创建字段,也就是属性的private。以及set和get方法来访问字段。

package com.pojo;//领域对象层
public class Employee {
	//字段或属性
	private String id;
	private String username;
	private double salary;
	private int age;
	private String depart;

	//无参构造
	public Employee() {
		// TODO Auto-generated constructor stub
	}

    //set和get方法访问属性
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	public String getUsername() {
		return username;
	}
	public void setUsername(String username) {
		this.username = username;
	}
	public double getSalary() {
		return salary;
	}
	public void setSalary(double salary) {
		this.salary = salary;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getDepart() {
		return depart;
	}
	public void setDepart(String depart) {
		this.depart = depart;
	}

    //toString方法
	@Override
	public String toString() {
		return "Employee [id=" + id + ", username=" + username + ", salary=" + salary + ", age=" + age + ", depart="
				+ depart + "]";
	}
	
	

}

3.2工具类Utils:上一篇文章我将JDBC的部分代码已经封装好了,现在添入查找的功能。在数据库中,我们查找的要么是一个对象,要么是多个对象。所以这里的查找封装,我们需要使用到单条查询或者多条查询。

3.2.1单条查询封装:首先我们单条查询要获得的是一个对象,那么我们需要使用到的是Object,就以ID查询来说,一般而言ID是一个指定的字段,不会存在重复的ID,那么也就是说ID查询获得的结果是单个对象。当我们连接数据库并且获得Resultset对象后,需要获取Resultset对象里边的数据,进而按照项目分层来说,我们下一步到达数据链路层Dao进而获取到Resultset对象里边的数据。

	public Object queryByOne(String sql){
		Object obj = null;
		try {
			conn = getConnection();      //获取连接对象
			st = conn.createStatement(); //获取statement对象
			ResultSet rs = st.executeQuery(sql); //sql语句查询后获取的Resultset对象
			obj = rsToObj(rs);           //跳转到数据链路层解释Resultset对象数据
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			jdbcClose(conn, st);         //资源释放
		}
		return obj;
	}

3.2.2多条查询封装:按照事先的业务需求,当我们使用姓名来进行查询时。一般而言,姓名是会出现重复的,也就是说,使用姓名查询获得的对象数据它会有可能是多条的,所以我们需要使用到List链表类型。那么我们进行多条查询的封装,大概的步骤和单条查询一致,只要获取到的对象数据不一致。同样的,最终获取到的Resultset对象我们需要转移到数据链路层Dao将里边的对象数据获取出来。

	public List queryByAll(String sql){	
		List list = null;
		try {
			conn = getConnection();        //获取连接对象
			st = conn.createStatement();   //获取statement对象
			ResultSet rs = st.executeQuery(sql);  //sql语句查询
			list = rsToList(rs);           //解释Resultset对象的数据进而获取
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			jdbcClose(conn, st);           //释放创建的对象资源
		}	
		return list;
	}

3.2.3工具类Utils代码

package com.utils;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

public abstract class JDBCUtils {
	
	private String driver = "com.mysql.jdbc.Driver";
	private static String url = "jdbc:mysql://localhost:3306/demo";
	private static String username = "root";
	private static String password = "113846";
	private Connection conn = null;
	private Statement st = null;
	private ResultSet rs = null;
	
	
	//因为加载驱动这件事情 在程序启动的时候就被加载且只执行一次
	static{
		try {
			Class.forName("com.mysql.jdbc.Driver");
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	/**
	 * 获取连接对象
	 * @return
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException{
		return DriverManager.getConnection(url, username,password);
	}
	
	
	/**
	 * 添加,修改,删除
	 */
	
	public void update(String sql){
		try {
			conn = getConnection();
			st = conn.createStatement();
			int bRet = st.executeUpdate(sql); //语句更新的方法
			
			if(bRet>0){
				System.out.println("数据更新成功,更新记录数:"+bRet+"条");
			}else{
				System.out.println("数据更新失败,更新记录数:"+bRet+"条");
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			jdbcClose(conn, st);
		}
	}
	
	/**
	 * 多条记录的查询  List  ArrayList
	 */
	
	public List queryByAll(String sql){	
		List list = null;
		try {
			conn = getConnection();        //获取连接对象
			st = conn.createStatement();   //获取statement对象
			ResultSet rs = st.executeQuery(sql);  //sql语句查询
			list = rsToList(rs);           //解释Resultset对象的数据进而获取
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			jdbcClose(conn, st);           //释放创建的对象资源
		}	
		return list;
	}
	/**
	 * 单条记录的查询 Object
	 */
	
	public Object queryByOne(String sql){
		Object obj = null;
		try {
			conn = getConnection();      //获取连接对象
			st = conn.createStatement(); //获取statement对象
			ResultSet rs = st.executeQuery(sql); //sql语句查询后获取的Resultset对象
			obj = rsToObj(rs);           //跳转到数据链路层解释Resultset对象数据
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			jdbcClose(conn, st);         //资源释放
		}
		return obj;
	}
	/**
	 * 释放资源 connection、statement、Resultset对象
	 * mysql的连接资源 比较珍稀的资源
	 * 尽晚的获取连接,尽早释放资源
	 * @param conn
	 * @param st
	 * @param rs
	 */
	public static void jdbcClose(Connection conn,Statement st,ResultSet rs){
		
		try {
			rs.close();
			if(rs != null){
				rs = null;
		    }
			
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			
			try {
				st.close();
				if(st!=null){
					st = null;
				}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}finally{
				try {
				conn.close();
				if(conn!=null){
					conn = null;
				}
				} catch (SQLException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		}
	}
	//释放资源 connection、statement对象
	public static void jdbcClose(Connection conn,Statement st){
		
		try {
			st.close();
			if(st!=null){
				st = null;
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally{
			try {
			conn.close();
			if(conn!=null){
				conn = null;
			}
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}
//因为这是一个工具类,当我们需要查询的表字段不一时候,我们每次需要操作的属性也就不一样,所以查询Resultset对象数据获取定义为抽象方法
	public abstract Object rsToObj(ResultSet rs);
	public abstract List rsToList(ResultSet rs);
}

3.3数据链路层Dao:这一层是为了解析提取Resultset对象的数据,所以继承工具类Utils从而实现定义的抽象方法rsToObj(单条查询数据获取)、rsToList(多条查询数据获取)。

3.3.1rsToObj(单条查询数据获取):实现这一抽象方法,领域对象层pojo已经创立好了,这时候我们需要的是将获取的Resultset对象数据进行解析,解析提取后的数据形成一个对象(也就是pojo包层创建的类Employee),之后将这一个对象返回。

    public Object rsToObj(ResultSet rs) {
		Object obj = null;
		try {
			Employee emp = new Employee();                //创建一个对象变量
			if(rs.next()){     //不为空,意思是还有数据
				emp.setId(rs.getString("id"));            //获取字段id数据
				emp.setUsername(rs.getString("username"));//获取字段username数据
				emp.setSalary(rs.getDouble("salary"));    //获取字段salary数据 
				emp.setAge(rs.getInt("age"));             //获取字段age数据
				emp.setDepart(rs.getString("depart"));    //获取字段depart数据
				obj = emp;    //获取的数据导入了创建的对象emp中
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}

3.3.2rsToList(多条查询数据获取):实现这一抽象方法,领域对象层pojo已经创立好了,这时候我们需要的是将获取的Resultset对象数据进行解析,与单条查询不同的是,解析的对象不止一个,也就是Resultset对象中每一个对象数据提取完后到达下一个对象,直到下一个对象数据为空停止。每一次Resultset对象中的对象解析的数据形成一个对象(也就是pojo包层创建的类Employee),然后将形成的对象放入链表List中,最后将链表返回。

    public List rsToList(ResultSet rs) {
		List list = new ArrayList();
		try {
			Employee emp = new Employee();                //创建一个对象变量
			while(rs.next()){                             //不为空,意思是还有数据
				emp.setId(rs.getString("id"));            //获取字段id数据
				emp.setUsername(rs.getString("username"));//获取字段username数据
				emp.setSalary(rs.getDouble("salary"));    //获取字段salary数据 
				emp.setAge(rs.getInt("age"));             //获取字段age数据
				emp.setDepart(rs.getString("depart"));    //获取字段depart数据
				list.add(emp);    //获取的数据导入了创建的对象emp中,然后将对象emp放入链表
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}

3.3.3数据链路层代码:

package com.openlab.dao;//数据链路层

import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import com.pojo.Employee;
import com.utils.JDBCUtils;

public class EmployeeServcieDao extends JDBCUtils{

	@Override
    public Object rsToObj(ResultSet rs) {
		Object obj = null;
		try {
			Employee emp = new Employee();                //创建一个对象变量
			if(rs.next()){     //不为空,意思是还有数据
				emp.setId(rs.getString("id"));            //获取字段id数据
				emp.setUsername(rs.getString("username"));//获取字段username数据
				emp.setSalary(rs.getDouble("salary"));    //获取字段salary数据 
				emp.setAge(rs.getInt("age"));             //获取字段age数据
				emp.setDepart(rs.getString("depart"));    //获取字段depart数据
				obj = emp;    //获取的数据导入了创建的对象emp中
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return obj;
	}

	@Override
    public List rsToList(ResultSet rs) {
		List list = new ArrayList();
		try {
			Employee emp = new Employee();                //创建一个对象变量
			while(rs.next()){                             //不为空,意思是还有数据
				emp.setId(rs.getString("id"));            //获取字段id数据
				emp.setUsername(rs.getString("username"));//获取字段username数据
				emp.setSalary(rs.getDouble("salary"));    //获取字段salary数据 
				emp.setAge(rs.getInt("age"));             //获取字段age数据
				emp.setDepart(rs.getString("depart"));    //获取字段depart数据
				list.add(emp);    //获取的数据导入了创建的对象emp中,然后将对象emp放入链表
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return list;
	}
}

3.4业务层Service:前边已经说了,业务需求是ID查询和姓名查询,所以这一层要创建一个接口来包含两个查询方法。

package com.service;// 业务层接口

import java.util.List;

import com.pojo.Employee;

public interface EmployeeService {
	public Employee queryById(String id);         //ID查询获取的是单个对象数据
	public List queryByUserName(String username); //姓名查询获取的是多个对象数据
}

3.5业务层ServiceImpl:对业务层Service接口的实现。

package com.service.impl; //业务层接口实现

import java.util.List;

import com.dao.EmployeeServcieDao;
import com.pojo.Employee;
import com.service.EmployeeService;

public class EmployeeServiceImpl implements EmployeeService{

	EmployeeServcieDao edao = new EmployeeServcieDao();  //创建链路数据层对象edao

    //ID查询
	@Override
	public Employee queryById(String id) {
		String sql = "select * from user where id='"+id+"'"; //user:我的表名
		Object obj = edao.queryByOne(sql);  //子类对象调用父类方法
		Employee em =(Employee) obj;        //Utils中的方法返回类型是Objec,强转
		return em;
	}

    //姓名查询
	@Override
	public List queryByUserName(String username) {
		String sql ="select * from user where username='"+username+"'";
		List list =  edao.queryByAll(sql);   //子类对象调用父类方法
		return list;
	}

}

3.7测试类:ID查询、姓名查询测试。

package com.test;

import java.util.List;

import org.junit.Test;

import com.pojo.Employee;
import com.service.impl.EmployeeServiceImpl;

import junit.framework.TestCase;

public class EmployeeServiceImplTest {
    //接口实现,因为要调用里边的查询方法,创建对象
	EmployeeServiceImpl eimpl = new EmployeeServiceImpl();
    //ID查询测试
	@Test
	public void testQueryById() {
		Employee e = eimpl.queryById("006");        //ID:006查询
		System.out.println(e);                      //查询结果输出
        //.assertEquals方法:如果预期值与真实值相等,则运行success,反之Failure
		TestCase.assertEquals("zhangsan", e.getUsername());	
	}
	//姓名查询测试
	@Test
	public void testQueryByUserName(){
		List list = eimpl.queryByUserName("zhangsan");//姓名:zhangsan查询
		System.out.println(list);                     //查询结果输出
		TestCase.assertEquals(2, list.size());//2:2条数据  list.size():链表长度 
	}

}

3.8项目的业务实现总结:

3.8.1最重要的一点首先要明确业务需求,从业务需求展开,层层深入完成项目构建。

3.8.2建议观看顺序:pojo->test->impl(service接口实现)->dao->utils,个人感觉从测试开始往回看比较清晰。

3.8.3项目开发实现的步骤:pojo->utils->dao->impl(service接口实现)->test。

3.8.4Resultset对象解析获取数据放入创建的Employee对象,放入对象的含义是我创建的pojo里边的类,也就是Employee类然后new一个对象用来存储解析的Resultset对象里边的数据。Resultset对象这个里边不止含有数据库的数据记录,除了数据记录还有其他的东西。

3.8.5Resultset.next()方法:当前指针位于第一行的前一行,也就是第一个数据的上一个结点,按链表来说就是位于虚拟头结点位置。所以dao层中解析Resultset对象需要先判断.next()是否为空。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值