摘要:前言为了巩固开发的流程,我们再拿一个客户关系管理系统来练手成果图我们完成的就是下面的项目搭建配置环境配置导入开发包建立开发用到的程序包在数据库创建相对应的表开发实体开发实体十分简单,对照着数据库的表就行了各种开发获取数据库连接池的导入配置文
前言
为了巩固开发的流程,我们再拿一个客户关系管理系统来练手...!成果图
我们完成的就是下面的项目!
搭建配置环境配置Tomcat
导入开发包
建立开发用到的程序包
在数据库创建相对应的表
CREATE TABLE customer ( id VARCHAR(40) PRIMARY KEY, name VARCHAR(20) NOT NULL, gender VARCHAR(10) NOT NULL, birthday DATE, cellphone VARCHAR(30) NOT NULL, email VARCHAR(30), preference VARCHAR(200), type VARCHAR(20), description VARCHAR(255) );开发实体
开发实体十分简单,对照着数据库的表就行了!
private String id; private String name ; private String gender ; private Date birthday ; private String cellphone ; private String eamil ; private String preference ; private String type ; private String description; //....各种setter、getter开发获取数据库连接池的Utils 导入配置文件
开发提供数据连接池的工具类com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/zhongfucheng root root 5 10 5 20 com.mysql.jdbc.Driver jdbc:mysql://localhost:3306/zhongfucheng root root 5 10 5 20 oracle.jdbc.driver.OracleDriver jdbc:oracle:thin:@//localhost:1521/事例名... 用户名 密码 5 10 5 20
public class Utils2DB { private static ComboPooledDataSource comboPooledDataSource = null; static { //它会自动寻找配置文件,节点为mysql的数据库(默认就是Mysql) comboPooledDataSource = new ComboPooledDataSource(); } public static DataSource getDataSource() { return comboPooledDataSource ; } public static Connection connection() { try { return comboPooledDataSource.getConnection(); } catch (SQLException e) { e.printStackTrace(); throw new RuntimeException("数据库初始化失败了!"); } } }开发UUID工具类
public class WebUtils { public static String makeId() { return UUID.randomUUID().toString(); } }开发DAO
DAO应该提供增加客户和查询用户的功能
增加用户public void addCustomer(Customer customer) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "INSERT INTO customer (id,name, gender, birthday, cellphone, preference, type, description) VALUES (?, ?, ?, ?, ?, ?, ?, ?,?)"; //得到用户传递进来的数据 String id = customer.getId(); String name = customer.getName(); String gender = customer.getGender(); String cellphone = customer.getCellphone(); String email = customer.getEmail(); String preference = customer.getPreference(); String type = customer.getType(); String description = customer.getDescription(); //对于日期,要转换一下 Date date = customer.getBirthday(); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd"); String birthday = simpleDateFormat.format(date); try { //向数据库插入数据 queryRunner.update(sql, new Object[]{id, name, gender, birthday, cellphone, email, preference, type, description}); //插入记录成功! } catch (SQLException e) { //如果出现了异常,就抛出Dao异常吧(自定义的异常) e.printStackTrace(); throw new DaoException("添加用户出错了!"); } }测试增加用户
写完一个功能,不要急着去写其他的功能,先测试一下!
@Test public void add() { //为了测试的方便,直接使用构造函数了! Customer customer = new Customer("1", "zhongfucheng", "男", new Date(), "1234", "aa@sina.com", "打代码", "高贵的用户", "我是个好人"); CustomerDao customerDao = new CustomerDao(); customerDao.addCustomer(customer); }
好的,没有报错!再看看数据库-----------只要是中文的数据,都乱码了!
解决的办法,看我另外一篇博文:https://zhongfucheng.bitcron....
查询用户将所有的客户查询出来就行了!
//得到所有的用户 public List测试查询用户getAll() { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer"; try { List customers = (List ) queryRunner.query(sql, new BeanListHandler(Customer.class)); //如果集合大于个数大于0,就返回集合,不大于0,就返回null return customers.size() > 0 ? customers : null; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("获取所有的用户出错了!"); } }
@Test public void find() { CustomerDao customerDao = new CustomerDao(); List修改用户信息customers = customerDao.getAll(); for (Customer customer : customers) { System.out.println(customer.getName()); } }
修改用户信息首先要知道用户的信息,在web端,只有id能唯一标识用户,我们需要通过id,获取用户全部信息(也就是Customer对象)
public Customer find(String id) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "SELECT * FROM customer WHERE id = ?"; try { Customer customer = (Customer) queryRunner.query(sql, new BeanHandler(Customer.class), new Object[]{id}); return customer; } catch (SQLException e) { e.printStackTrace(); throw new DaoException("查找用户失败了"); } }
修改用户都是外边传递个对象进来,Dao层取出对象的数据,从而对数据库的数据进行修改!
public void update(Customer customer) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "UPDATE customer set name=?,gender=?,birthday=?,cellphone=?,email=?,preference=?,type=?,description=? WHERE id = ?"; try { queryRunner.update(sql, new Object[]{customer.getName(), customer.getGender(), customer.getBirthday(),customer.getCellphone(), customer.getEmail(), customer.getPreference(), customer.getType(), customer.getDescription(), customer.getId()}); } catch (SQLException e) { e.printStackTrace(); throw new DaoException("更新失败"); } }测试修改用户
@Test public void update() { CustomerDao customerDao = new CustomerDao(); //我们已经知道了某id,通过id获取得到用户信息(Customer) String id = "043f7cce-c6f1-4155-b688-ba386cae1636"; Customer customer = customerDao.find(id); //修改用户信息 customer.setName("看完博客要点赞"); customerDao.update(customer); }
原来该用户的名字是d
测试完之后:
删除用户通过外界传递进来的id,就可以删除数据库表中的记录了
public void delete(String id) { QueryRunner queryRunner = new QueryRunner(Utils2DB.getDataSource()); String sql = "DELETE from customer WHERE id = ?"; try { queryRunner.update(sql, new Object[]{id}); } catch (SQLException e) { e.printStackTrace(); throw new DaoException("删除用户失败了"); } }测试删除用户
@Test public void delete() { CustomerDao customerDao = new CustomerDao(); //我们已经知道了某id,通过id删除数据库中的记录 String id = "043f7cce-c6f1-4155-b688-ba386cae1636"; customerDao.delete(id); }
数据库已经查询不到id为043f7cce-c6f1-4155-b688-ba386cae1636的记录了!
开发servicepublic class BusinessService { CustomerDao customerDao = new CustomerDao(); public List开发web 的增加和查询 提供UI,增加客户的ServletgetAll() { return customerDao.getAll(); } public void addCustomer(Customer customer) { customerDao.addCustomer(customer); } public void deleteCustomer(String id) { customerDao.delete(id); } public void updateCustomer(Customer customer) { customerDao.update(customer); } public Customer findCustomer(String id) { return customerDao.find(id); } }
//直接跳转到显示增加用户页面的jsp request.getRequestDispatcher("/WEB-INF/addCustomer.jsp").forward(request, response);开发显示添加客户页面
效果是这样子的
我们发现,在日期的下拉框中,只有一个数据(因为我们在value中只写了一个数据)
要想在下拉框中可以选择很多的数据,那么value的值就不能单单只有一个。当然了,也不可能在JSP页面中写下面的代码
我们用javaScript生成下拉框的数据就行了!!
获取年份!
function makeYear() { //得到下拉框的控件 var year = document.getElementById("year"); //要想下拉框有更多的数据,就需要有更多的option控件 //js获取得到年份是getFullYear(),单单的getYear()只是获取两位数 for (var i=1901; i<= new Date().getFullYear(); i++) { //生成option控件 var option = document.createElement("option"); //option控件的值和文本内容为循环生成的年分! option.value = i; option.innerText = i; //将生成option控件绑定到select控件上 year.appendChild(option); } }
获取月份和日也类似
function makeMonth() { var month = document.getElementById("month"); for (var i = 2; i <= 12; i++) { var option = document.createElement("option"); if (i < 10) { option.value = "0" + i; option.innerText = "0" + i; } else { option.value = i; option.innerText = i; } month.appendChild(option); } } function makeDay() { var day = document.getElementById("day"); for(var i=2;i<=12;i++) { var option = document.createElement("option"); if(i<10) { option.value = "0" + i; option.innerText = "0" + i; }else{ option.value = i; option.innerText = i; } day.appendChild(option); } }
在JSP页面中导入javascript文件
注意:javasrcipt文件不能放在WEB-INF下面!!!!否则是获取不到的!!!
这三个函数都是在页面加载时就应该被初始化了,所以在body上绑定onload时间即可!!
function pageInit() { makeYear(); makeMonth(); makeDay(); }
效果:
JavaScript拼凑数据表单的数据非常多,毫无疑问,我们会使用BeanUtils来将数据封装到Bean对象中!
对于表单的数据,还是有些杂乱的。表单中日期的年月日是分开的,我们要么在客户端将年月日的数据拼凑起来,要么在服务器端将年月日拼凑起来!同理,客户的喜好可能不单单有一个,但在Customer对象中,喜好单单用一个String类型来表示的。我们也要把客户的喜好拼凑起来。
显然,在客户端用javaScript做拼凑是非常方便的!
function makeBirthday() { //获取下拉框的数据,把数据拼凑成日期字符串 var year = document.getElementById("year"); var month = document.getElementById("month"); var day = document.getElementById("day"); var birthday = year + "-" + month + "-" + day; //想要将拼凑完的字符串提交给服务器,用隐藏域就行了 var input = document.createElement("input"); input.type = "hidden"; input.value = birthday; input.name = "birthday"; //将隐藏域绑定在form下【为了方便,在form中设置id,id名字为form】 document.getElementById("form").appendChild(input); } function makePreference() { //获取喜好的控件 var hobbies = document.getElementsByName("hobbies"); //定义变量,记住用户选中的选项 var preference = ""; //遍历喜好的控件,看用户选上了什么! for (var i = 0; i < hobbies.length; i++) { if (hobbies[i].checked == true) { preference += hobbies[i].value + ","; } } //刚才拼凑的时候,最后一个逗号是多余的,我们要把它去掉 preference = preference.substr(0, preference.length - 1); //也是用隐藏域将数据带过去给服务器 var input = document.createElement("input"); input.type = "hidden"; input.value = preference; input.name = "preference"; //将隐藏域绑定到form表单上 document.getElementById("form").appendChild(input); }
当表单提交的时候,触发上面两个函数就行了!所以在form表单上绑定onsumit事件!
function makeForm() { makeBirthday(); makePreference(); return true; }
效果:
处理修改表单数据的Servlet//将数据封装到Bean中 Customer customer = WebUtils.request2Bean(request, Customer.class); //将id封装到Customer对象中!!!不要忘了id!!!在表单中获取到的数据是没有id的!!!!!记得!!!! customer.setId(request.getParameter("id")); //调用Service层的方法,实现修改 BusinessService businessService = new BusinessService(); businessService.updateCustomer(customer); //修改成功就跳回查看客户界面 request.getRequestDispatcher("/LookCustomer").forward(request, response);
效果:
总结在dao层中,我们有添加客户、通过id查找用户、删除用户、修改用户信息的方法。
日期我们一般用下拉框来给用户选取,要想下拉框的信息有足够多的数据,我们需要用到JavaScript【DOM编程动态增加和修改数据】
javasrcipt文件不能放在WEB-INF目录下面
日期的数据通过下拉框选取,年、月、日是分散的,我们需要把他们拼接,于是我们也用JavaScript来拼接【减低服务器端的压力】
开发工具方法request2Bean,主要用到了BeanUtils框架,这样就不用在Servlet一个一个封装了。
在JSP判断集合是否有元素时,我们可以用EL表达式${empty(集合)}。
如果记录数有很多,我们应该使用分页技术,一般地,我们使用Page类来封装分页的数据
要使用分页技术,就必须在数据库用查询总记录数,通过总记录数,就可以算出总页数了【每页显示多少条记录由我们说了算】
在dao层还要编写获取具体的分页数据,从哪里开始,哪里结束,返回一个List集合,再把List集合封装到Page对象上
由于获取分页数据需要当前的页数是多少,(所以在service中要判断当前页数是否存在,如果不存在,那么就设置为1)【更新,我认为在Controller判断会好一点】
分页中,我们还支持上一页和下一页的功能,如果页数大于1,才显示上一页,如果页数小于1,才显示下一页。
给出下拉框进行页数跳转,使用JavaScript事件机制,获取页数,再提交给Servlet处理即可
我们还要控制页数的显示,因为不可能有100页,我们就显示100页,这样是不可能的。在Page类中维护两个变量,startPage,endPage。我们规定每次只能显示10页数据,如果第一次访问就显示1-10页。如果当前页数大于10,那么就显示6-15页。如果角标越界了,那么就显示前10页或者后10页
我们把显示分页的页面封装成多带带的jsp,使用的Servlet连接也可以用url变量来维护。
前台数据做拼接,最终都是把拼接好的数据用一个隐藏域封装起来,随后让form表单一起提交
如果文章有错的地方欢迎指正,大家互相交流。习惯在微信看技术文章的同学,想要获取更多的Java资源的同学,可以关注微信公众号:Java3y
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/68586.html
摘要:中主要是使用语言。将的动态功能和标准的安全性引入大型网络应用的开发集成部署和管理之中。提供了一个图形界面的管理工具,称为信息服务管理器,可用于监视配置和控制服务。 一、基本概念 1.1、WEB开发的相关知识 WEB,在英语中web即表示网页的意思,它用于表示Internet主机上供外界访问的资源。 Internet上供外界访问的Web资源分为: 静态web资源(如html 页面...
摘要:当后继请求相同的页面时,容器加载之前生成的类,并且通知去执行已经存在的字节码,从而省去了转换的过程,这也是第一次执行页面时间较长的原因。 以往学习的时候大多是看完书或者看完视频,动手实践一下就OK了。然而过了一段时间我发现东西都忘差不多了,需要复习才能重新掌握。现在开始学习JavaWeb了,我将在这里记录自己的学习的一点一滴,不仅便于自己以后回顾知识点,也希望能对JavaWeb初学者有...
摘要:系列文章请查看超详细的面试题总结一之基础知识篇超详细的面试题总结二之基础知识篇超详细的面试题总结三之集合篇常见问题下面的都是自己之前在学习的时候总结的,对于巩固的基础知识应该有很大帮助。注意多线程的并发的读写类属性会导致数据不同步。 系列文章请查看: 超详细的Java面试题总结(一)之Java基础知识篇 超详细的Java面试题总结(二)之Java基础知识篇 超详细的Java面试题总结(...
摘要:方法的参数不但可以使相对于上下文根的路径,而且可以是相对于当前的路径。如和都是合法的路径。 转发与重定向区别是什么 在调用方法上 转发 调用 HttpServletRequest 对象的方法 request.getRequestDispatcher(test.jsp).forward(req, resp); 重定向 调用 HttpServletResponse 对象的方法 res...
摘要:实现不同语言间进行协助开发,可以使用通信的方式来实现,这次实现和的协助开发,是项目主要服务端,由于要处理一些系统底层的事务,所以要用提供一个辅助服务,为主服务端处理相关事务,以下是搭建流程和服务间通信原理。 实现不同语言间进行协助开发,可以使用通信的方式来实现,这次实现Nodejs和JavaWeb的协助开发,Nodejs是项目主要服务端,由于要处理一些系统底层的事务,所以要用JavaW...
阅读 2390·2021-11-22 15:35
阅读 3730·2021-11-04 16:14
阅读 2665·2021-10-20 13:47
阅读 2468·2021-10-13 09:49
阅读 2045·2019-08-30 14:09
阅读 2311·2019-08-26 13:49
阅读 860·2019-08-26 10:45
阅读 2745·2019-08-23 17:54