Servlet项目之销售合同项目(三)

Bean(实体类)

做好了基本的准备工作,我们先从最简单的包开始下手,这个比较简单,我就直接上代码了,大家可以根据自己的需求自行添加字段到数据库,然后完善我们的JavaBean

User

@Table(value="u_user")
public class User {
	@Column(value="id")
	private int id;
	@Column(value="user_name")
	private String userName;
	@Column(value="password")
	private String password;
	@Column(value="real_name")
	private String realName;
	
	public User() {

	}	
	public User(int id, String userName, String password, String realName) {
		super();
		this.id = id;
		this.userName = userName;
		this.password = password;
		this.realName = realName;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getPassword() {
		return password;
	}
	public void setPassword(String password) {
		this.password = password;
	}
	public String getRealName() {
		return realName;
	}
	public void setRealName(String realName) {
		this.realName = realName;
	}

	@Override
	public String toString() {
		return "User [id=" + id + ", userName=" + userName + ", password=" + password + ", realName=" + realName + "]";
	}
	
}

Customer

@Table(value="c_customer")
public class Customer {
	@Column(value="id")
	private int id;
	@Column(value="cust_name")
	private String custName;
	@Column(value="cust_comp")
	private String custComp;
	
	public Customer() {
		super();
	}

	public Customer(int id, String custName, String custComp) {
		super();
		this.id = id;
		this.custName = custName;
		this.custComp = custComp;
	}

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getCustName() {
		return custName;
	}

	public void setCustName(String custName) {
		this.custName = custName;
	}

	public String getCustComp() {
		return custComp;
	}

	public void setCustComp(String custComp) {
		this.custComp = custComp;
	}

	@Override
	public String toString() {
		return "Customer [id=" + id + ", custName=" + custName + ", custComp=" + custComp + "]";
	}
	
}

Constract

@Table(value="c_contract")
public class Contract {
	@Column(value="id")
	private int id;
	@Column(value="sale_id")
	private int saleId;
	@Column(value="cust_id")
	private int custId;
	@Column(value="content")
	private String content;
	@Column(value="create_time")
	private String createTime;
	
	public Contract() {
		super();
	}
	
	public Contract(int id, int saleId,  int custId, String content, String createTime) {
		super();
		this.id = id;
		this.saleId = saleId;
		this.custId = custId;
		this.content = content;
		this.createTime = createTime;
	}

	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public int getSaleId() {
		return saleId;
	}
	public void setSaleId(int saleId) {
		this.saleId = saleId;
	}
	public int getCustId() {
		return custId;
	}
	public void setCustId(int custId) {
		this.custId = custId;
	}
	public String getContent() {
		return content;
	}
	public void setContent(String content) {
		this.content = content;
	}
	public String getCreateTime() {
		return createTime;
	}
	public void setCreateTime(String createTime) {
		this.createTime = createTime;
	}

	@Override
	public String toString() {
		return "Contract [id=" + id + ", saleId=" + saleId + ", custId=" + custId + ", content=" + content
				+ ", createTime=" + createTime + "]";
	}
}

另外我们还需要建一个com.marco.crs.vo包中新建一个ContractVO里面多添加两条字段
String saleName和String custName,这个主要是为了后期在我们页面上显示使用到的一个特殊类
vo包也就是value object,因为我们存入的对象可能跟后期展示出来的并不一定是同一个,vo中类的属性一般比bean中的更多,换句话来说vo中类查出来的信息就是多表联合查询出来的信息整理出来的新对象。


Dao(Data Access Object)

接下来就是我们的Dao层,这一层主要和数据库打交道,并且只用完成获取数据的操作

Dao接口
定义接口的目的是为了约定某种规范,然后由实现类具体的去实现它的方法,说白了,接口就好比XXX公司老板,它大致规划了公司的章程或者公司的发展规划,那么他底下的员工们就应当严格遵守他的规章制度,不同的部门可以完善他指定的规则,可能每个部门的规则不会完全一样,但是基本的骨架是一样的,这样的话就可以达成某种一致性,而且也便于管理。

public interface UserDao {
	/*分页查询*/
	PageQueryInfo listUsers(Map<String, Object> map);
	/*添加用户*/
	boolean addUser(User user) throws SQLException;
	/*删除用户*/
	boolean delUser(List<Integer> ids);
	/*修改用户*/
	boolean editUser(User user) throws SQLException;
	/*用id查询用户*/
	User queryById(int id);
}
public interface CustomerDao {
	/*分页查询*/
	PageQueryInfo listCustomers(Map<String, Object> map);
	/*添加客户*/
	boolean addCustomer(Customer customer) throws SQLException;
	/*删除客户*/
	boolean delCustomer(List<Integer> ids);
	/*编辑客户*/
	boolean editCustomer(Customer customer) throws SQLException;
	/*根据客户id查询客户*/
	Customer queryById(int id);
}
public interface ContractDao {
	/*分页查询*/
	PageQueryInfo listContracts(Map<String, Object> map);
	/*添加合同*/
	boolean addContract(Contract contract) throws SQLException;
	/*删除合同*/
	boolean delContract(List<Integer> ids) throws SQLException;
	
}

为了使JDBC的操作能够统一,我将此前封装的JDBC通用操作全部封装到BaseDao中,便于DaoImpl实现类能直接调用

public abstract class BaseDao {
	
	public  <T> List<T>  queryData(Connection conn,Class<T> clz, String sql, Object...param) {
		//创建连接对象
		try {
			PreparedStatement ps = conn.prepareStatement(sql);//创建操作数据库对象
			//设置条件判断中的值
			for(int i = 0; i < param.length; i++) {
				ps.setObject(i+1, param[i]);
			}
			ResultSet rs = ps.executeQuery();//获取结果集对象
			ResultSetMetaData meta = rs.getMetaData();//获取数据集元信息
			int column = meta.getColumnCount();//获取所搜寻的字段个数或者列数
			List<T> list = new ArrayList<>();//创建用于储存构建出来的对象的容器
			while(rs.next()) {
				Map<String,Object> map = new HashMap<>();//创建用于储存保存类的属性的map集合
				for(int i = 0; i < column; i++) {
					String columnName = meta.getColumnLabel(i+1);//得到每一列的或者每一个字段的名称
					Object obj = rs.getObject(columnName);//根据字段名称获取每一行对应的字段值
					map.put(columnName, obj);
				}
				if(!map.isEmpty()) {	
					T obj = clz.newInstance();//通过传入的类的Class对象创建这个类的对象
					Set <Entry <String,Object>> entryset = map.entrySet();
					for (Entry<String, Object> entry : entryset) {
						String atribute = entry.getKey();//提取这个类中的属性名称
						Object value = entry.getValue();//提取这个类中属性的值
						Field attribute = clz.getDeclaredField(atribute);
						attribute.setAccessible(true);//注意要设置权限为开放
						attribute.set(obj, value);//通过反射给对象赋值
					}
					list.add(obj);//将赋值完成的对象放入ArrayList容器中
				}				
			}
			ConnPool.realse(rs, ps);
			return list;
		} catch (SQLException | InstantiationException | IllegalAccessException e) {
			e.printStackTrace();
		} catch (NoSuchFieldException e) {
			e.printStackTrace();
		} catch (SecurityException e) {
			e.printStackTrace();
		}
		return null;
	}
	
	private  Map<String,Object> getAnnotations(Object obj) {
		Map<String,Object> map = new HashMap<>();	
		Field[] declaredFields = obj.getClass().getDeclaredFields();
		for (Field field : declaredFields) {
			Column anno = field.getAnnotation(Column.class);
			if(anno!=null){
				String attribute = anno.value();
				try {
					field.setAccessible(true);
					Object value = field.get(obj);
					map.put(attribute, value);
				} catch (IllegalArgumentException e) {
					e.printStackTrace();
				} catch (IllegalAccessException e) {
					e.printStackTrace();
				}
				
			}
			
		}
		return map;
	}

	public   <T> Boolean addData(Connection conn,T obj) throws SQLException {
		Map<String, Object> map = getAnnotations(obj);
		StringBuffer sql = new StringBuffer("insert into ");
		int size = 0;//需要查询的字段的总长度
		int index = 1;
		Class<? extends Object> clz = obj.getClass();
		sql.append(clz.getAnnotation(Table.class).value());
		sql.append("(");
		Set<Entry<String, Object>> entryset = map.entrySet();
		Iterator<Entry<String,Object>> it = entryset.iterator();
		while(it.hasNext()) {
			Entry<String,Object> entry = it.next();
			String attribute = entry.getKey();
			sql.append(attribute);
			sql.append(",");
			size++;
		}	
		sql.setCharAt(sql.lastIndexOf(","), ')');
		sql.append("values(");
		for (int i = 0; i < size; i++) {
			sql.append("?");
			sql.append(",");
		}
		sql.setCharAt(sql.lastIndexOf(","), ')');
		PreparedStatement ps = conn.prepareStatement(sql.toString());
		System.out.println(sql.toString());
		Set<Entry<String, Object>> entryset2 = map.entrySet();
		Iterator<Entry<String,Object>> it2 = entryset2.iterator();
		while(it2.hasNext()) {
			Entry<String,Object> entry = it2.next();
			ps.setObject(index++, entry.getValue());	
		}
		if(ps.executeUpdate()!=-1) {	
			ConnPool.realse(ps);
			return true;
		} else {	
			return false;
		}
	}	
	
	public <T> Boolean  deleteData(Connection conn,String tableName,String keyword, List<Integer> list) {
		PreparedStatement ps = null;
		String sql = "delete from "+ tableName + " where " + keyword + " = ?";
		try {
			conn.setAutoCommit(false);
			ps = conn.prepareStatement(sql);
			for (Integer id : list) {
				ps.setObject(1, id);
				ps.addBatch();
			}
			ps.executeBatch();
			conn.commit();
			return true;
		} catch (SQLException e) {
			e.printStackTrace();
			return false;
		} finally {
			ConnPool.realse(ps);
		}	
		
	}
	
	protected <T> PageQueryInfo queryPage(int currentPage, int limit, String sql, Class<T> clz, Connection conn) throws SQLException {
		//每一页从哪一条开始
		int count = this.countPage(sql, conn);
		//当前页的第一行是在总行数的第几行
		int startPage = (currentPage - 1)*limit;
		sql += " limit " + startPage + "," + limit;
		System.out.println(sql);
		List<T> data = this.queryData(conn, clz, sql);
		PageQueryInfo info = new PageQueryInfo();
		//总页数
		int totalPage = count%limit == 0?count/limit:(count/limit + 1);
		info.setData(data);
		info.setLimit(limit);
		info.setTotalPage(totalPage);
		info.setCount(count);
		return info;
	}
	
	protected String trimSql(String sql) {
		if(sql.endsWith("and")) {
			int andIndex = sql.lastIndexOf("and");
			sql = sql.substring(0, andIndex);
		} else if(sql.endsWith("where")) {
			int whereIndex = sql.lastIndexOf("where");
			sql = sql.substring(0, whereIndex);
		}
		return sql;
	}
	/*计算满足条件的数据一共有多少条*/
	private int countPage(String sql, Connection conn) throws SQLException {
		int fromIndex = sql.indexOf("from");
		sql = sql.substring(fromIndex);
		String countSql = "select count(1) " + sql;
		PreparedStatement ps = conn.prepareStatement(countSql);
		ResultSet rs = ps.executeQuery();
		rs.next();
		int count = rs.getInt(1);
		ConnPool.realse(rs, ps);
		return count; 
	}
}

DaoImpl实现类
这一层比较特殊,不仅实现了Dao层接口,并且还继承了BaseDao抽象类,这样实现类不仅实现了Dao接口方法,并且可以直接调用父类的方法,而不需要以构造器传实参的方式调用,比较调用起来会比较简单。

public class UserDaoImpl extends BaseDao implements UserDao{
	ConnPool connPool = new ConnPool();
	
	@Override
	public PageQueryInfo listUsers(Map<String, Object> params) {
		Connection conn = connPool.getConnection();
		String sql = "select id as id, user_name as userName, password as password, real_name as realName from u_user where";
		if(!CheckParamUtil.isBlank(params.get("userName"))) {
			sql += " user_name like '" + params.get("userName") + "%' and";
		}
		if(!CheckParamUtil.isBlank(params.get("realName"))) {
			sql += " real_name like '" + params.get("realName") + "%' and";
		}
		sql = this.trimSql(sql);//这里的this调用的是BaseDao中封装的方法,主要是为了将where和and截取掉
		Object pageNo = params.get("page");
		Object size = params.get("limit");
		int currentPage = 1;
		int limit = 10;
		if(!CheckParamUtil.isBlank(pageNo)) {
			currentPage = Integer.parseInt(""+pageNo);
		}
		if(!CheckParamUtil.isBlank(size)) {
			limit = Integer.parseInt(""+ size);
		}
		try {
			
			PageQueryInfo pageInfo = this.queryPage(currentPage, limit, sql, User.class, conn);
			return pageInfo;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			connPool.realse(conn);
		}
		return new PageQueryInfo();
	}

	@Override
	public boolean addUser(User user) throws SQLException {
		Connection conn = connPool.getConnection();
		Boolean flag = this.addData(conn, user);
		connPool.realse(conn);
		if(flag) {
			return true;
		}
		return false;
	}

	@Override
	public boolean delUser(List<Integer> ids) {
		Connection conn = connPool.getConnection();
		Boolean flag = this.deleteData(conn, "u_user", "id", ids);
		connPool.realse(conn);
		if(flag) {
			return true;
		}
		return false;
	}
	
	@Override
	public User queryById(int id) {
		Connection conn = connPool.getConnection();
		String sql = "select id as id, user_name as userName, password as password, real_name as realName from u_user where id = ?";
		List<User> users = this.queryData(conn, User.class, sql, id);
		connPool.realse(conn);
		return users.size() > 0 ? users.get(0) : null;
	}

	@Override
	public boolean editUser(User user) throws SQLException {
		Connection conn = connPool.getConnection();
		String sql = "update u_user set user_name = ?,password = ?, real_name = ? where id= ?";
		PreparedStatement ps =  conn.prepareStatement(sql);
		ps.setString(1, user.getUserName());
		ps.setString(2, user.getPassword());
		ps.setString(3, user.getRealName());
		ps.setInt(4, user.getId());
		if(ps.executeUpdate() > 0) {
			connPool.realse(conn);
			return true;
		}
		connPool.realse(conn);
		return false;
	}

}

以上的代码是UserDao的实现类,CustomerDao的实现类的方法也都大同小异,大家就当练手,可以自己尝试写出来。ContractDao的实现类就不太一样了,它涉及到了三表联合查询,还是上代码

public class ContractDaoImpl extends BaseDao implements ContractDao {
	ConnPool connPool = new ConnPool();
	
	@Override
	public PageQueryInfo listContracts(Map<String, Object> params) {
		Connection conn = connPool.getConnection();
		String sql = "select ct.id as id, cc.cust_name as custName,cc.id as custId, uu.real_name as saleName, uu.id as saleId, ct.content as content, date_format(ct.create_time,'%Y-%m-%d') as createTime from u_user uu, c_customer cc, c_contract ct where uu.id = ct.sale_id and ct.cust_id = cc.id ";
		if(!CheckParamUtil.isBlank(params.get("saleName"))) {
			sql += "and uu.real_name like '" + params.get("saleName") + "%' and";
		}
		if(!CheckParamUtil.isBlank(params.get("custName"))) {
			sql += "and cc.cust_name like '" + params.get("custName") + "%' and";
		}
		if(!CheckParamUtil.isBlank(params.get("startDate"))) {
			sql += "and ct.create_time >= '" + params.get("startDate") + "' and";
		}
		if(!CheckParamUtil.isBlank(params.get("endDate"))) {
			sql += " ct.create_time < '" + params.get("endDate") + "' and";
		}
		sql = this.trimSql(sql);//这里的this调用的是BaseDao中封装的方法,主要是为了将where和and截取掉
		Object pageNo = params.get("page");
		Object size = params.get("limit");
		int currentPage = 1;
		int limit = 10;
		if(!CheckParamUtil.isBlank(pageNo)) {
			currentPage = Integer.parseInt(""+pageNo);
		}
		if(!CheckParamUtil.isBlank(size)) {
			limit = Integer.parseInt(""+ size);
		}
		try {
			PageQueryInfo pageInfo = this.queryPage(currentPage, limit, sql, ContractVO.class, conn);
			return pageInfo;
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			connPool.realse(conn);
		}
		return new PageQueryInfo();
	}

	@Override
	public boolean addContract(Contract contract) throws SQLException {
		Connection conn = connPool.getConnection();
		Boolean flag = this.addData(conn, Contract.class);
		connPool.realse(conn);
		if(flag) {
			return true;
		}
		return false;
	}

	@Override
	public boolean delContract(List<Integer> ids) throws SQLException {
		Connection conn = connPool.getConnection();
		Boolean flag = this.deleteData(conn, "c_contract", "id", ids);
		connPool.realse(conn);
		if(flag) {
			return true;
		}
		return false;
	}

}

那么Dao层就讲到这儿,下一节我们继续完善我们的Service层

你可能感兴趣的:(Servlet)