刚接触编程的时候使用C语言写过一个通讯录,把数据存在本地的文件中,实现体系也比较low,当时完全没有把这个东西作为一个项目来写,在实现的时候也没有项目的层次体系,只是在一个.c文件中实现罢了。后来我使用JDBC尝试把信息储存到数据库里,但是当时自学的JDBC实现起来让我感觉很繁琐,后来也就不了了之了,至于项目构建,结构什么的都没有。
现在我重新实现了这个小小的项目,使用Spring的数据库支持和数据库事务管理,再加上Maven来构建项目,现在这个通讯录才有了一点项目的雏形,先上一部分代码,我来慢慢讲解。
首先这是一个Maven项目,实现的代码都在java下的com.dxy.memoapp包中,测试代码放在test下的java目录中。的Spring的三层架构里,因为这个小项目不需要接收用户请求和页面交互,所以就没有Controller层的代码,只需要DAO和Service层的就可以了。
首先,通讯录的信息保存在数据库里,我们必须要使程序和数据库有交互(增删改查),有关增删查改的具体操作统一放在DAO层,其次对于这些操作的业务判断放在Service层。这就是这个小项目的项目结构,接下来一一介绍。
对于一个Maven项目来说创建项目的时候就应该在pom.xml中配置项目所需的依赖了,下面是我所需要的依赖。
4.0.0 com.dxy springlist 1.0-SNAPSHOT org.springframework spring-framework-bom 4.3.9.RELEASE pom import org.springframework spring-context org.springframework spring-jdbc org.springframework spring-aspects mysql mysql-connector-java 5.1.43 com.alibaba druid 1.1.2 org.slf4j slf4j-api 1.7.25 ch.qos.logback logback-classic 1.2.3 junit junit 4.12 test
基本的Spring配置是必须的,因为要用到Spring事务管理,所以配置一个阿里的数据源,同时配置了事务管理器,然后我们需要自己测试,所以配置了日志的依赖和测试框架的依赖,加入AOP的依赖是因为我们也可以在配置事务管理器的时候使用XML的配置方式。现在正好看一下Spring资源文件中的配置吧。
我们可以采用两种方式来配置事务管理器,我现在采用的是注解的方式,这种方式比较方便,只需要开启事务注解驱动就可以了,现在相当于我们可以在某一层加上注解让事务管理器去进行事务管理。
DAO层主要进行和数据库交互的操作,是最核心的部分,对于一个通讯录的实现,只需要进行增删改查就可以了。首先定义一个数据访问层的接口,因为是面向接口编程,所以我们要向Service层提供DAO层的接口。对于数据库的操作是DAO层接口的实现类,在DAO层中,我们只需要进行增删查改就可以了,业务的判断处理统统交给Service层。
package com.dxy.memoapp.dao; import com.dxy.memoapp.entity.ChangeMessage; import com.dxy.memoapp.entity.Message; import java.util.List; //数据层访问接口 public interface MessageDao { int insetPeople(Message message);//信息插入 ListqueryPeopleByName(String name);//查询指定联系人的信息 int updatePeople(ChangeMessage changeMessage);//修改指定联系人的信息 List queryAllPeople();//列出所有联系人的信息 int deletePeople(int id);//根据id删除联系人信息 }
package com.dxy.memoapp.dao.imp; import com.dxy.memoapp.entity.ChangeMessage; import com.dxy.memoapp.entity.Message; import com.dxy.memoapp.dao.MessageDao; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.jdbc.core.RowMapper; import org.springframework.stereotype.Repository; import java.sql.ResultSet; import java.sql.SQLException; import java.util.List; @Repository public class MessageDaoImpl implements MessageDao { private final Logger logger = LoggerFactory.getLogger(MessageDaoImpl.class); //开启自动注入 @Autowired private JdbcTemplate jdbcTemplate; public int insetPeople(Message message) {//联系人加入 String sql = "INSERT INTO PhoneList (pname, pnumber, address) VALUES (,,)"; return jdbcTemplate.update(sql,message.getName(), message.getNumber(),message.getAddress()); } public ListqueryPeopleByName(String name) {//按名字查找指定联系人的信息 String sql = "SELECT * FROM PhoneList WHERE pname = "; List retMessage = jdbcTemplate.query(sql, new Object[]{name}, new RowMapper () { public Message mapRow(ResultSet rs, int rowNum) throws SQLException { Message message = new Message(); message.setName(rs.getString("pname")); message.setNumber(rs.getString("pnumber")); message.setAddress(rs.getString("address")); return message; } }); return retMessage; } public int updatePeople(ChangeMessage changeMessage) {//联系人信息修改 String sql = "UPDATE phonelist SET = WHERE pname = ;"; int effect = jdbcTemplate.update(sql,changeMessage.getProperty(), changeMessage.getNewMessage(),changeMessage.getMessage().getName()); return effect; } public List queryAllPeople() {//打印所有人的信息 String sql = "select * from phonelist"; List messages = jdbcTemplate.query(sql, new Object[]{}, new RowMapper () { public Message mapRow(ResultSet rs, int rowNum) throws SQLException { Message message = new Message(); message.setId(rs.getInt("id")); message.setName(rs.getString("pname")); message.setNumber(rs.getString("pnumber")); message.setAddress(rs.getString("address")); return message; } }); logger.debug("query AllPeople result={}", messages); return messages; } public int deletePeople(int id) { String sql = "DELETE FROM phonelist WHERE id = "; return jdbcTemplate.update(sql,id); } }
主要的实现代码都在DAO层,我们通过数据库的映射来进行数据库的操作,然后通过注解的方式把实现类注入IOC容器并自动装配JDBCTemplate。最后,我们只需要把接口提供给Service层就可以了。
Service层进行事物的判断和处理,处理完事务之后直接使用DAO层的接口来执行数据库访问的操作。同样的,在Service层中也体现了面向接口编程的思想,有一个接口和一个实现类,把接口传递给测试类,测试类只需要调用Service层对象的方法就可以了。
package com.dxy.memoapp.service; import com.dxy.memoapp.entity.Message; import java.util.List; public interface MessageService { ListQuerypeople(String name);//查询 Boolean AddPeople(Message message);//添加 Boolean DeletePeople(Integer id);//删除 void QueryAllPeople();//打印所有人的信息 Boolean updatePeople(Message message, String property, String NewMassage);//更新联系人 }
package com.dxy.memoapp.service.Imp; import com.dxy.memoapp.dao.MessageDao; import com.dxy.memoapp.entity.ChangeMessage; import com.dxy.memoapp.entity.Message; import com.dxy.memoapp.service.MessageService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import java.util.List; @Service @Transactional public class MessageServiceImp implements MessageService { @Autowired private MessageDao messageDao;//自动注入数据访问层对象 public ListQuerypeople(String name) {//业务层联系人查询实现 if (name == null) { throw new RuntimeException("name is null"); } List message = messageDao.queryPeopleByName(name); if (message.isEmpty()) { throw new IllegalArgumentException("Id=" + name + " not found"); } return message; } public Boolean AddPeople(Message message) { if (message == null) { throw new IllegalArgumentException("Message arguments error, please check"); } int effect = messageDao.insetPeople(message); return effect == 1; } public Boolean DeletePeople(Integer id) { if(id <= 0){ throw new RuntimeException("id is not allowed there"); } int effect = messageDao.deletePeople(id); return effect == 1; } public void QueryAllPeople() { messageDao.queryAllPeople(); } public Boolean updatePeople(Message message, String property, String NewMassage) { if(message == null){ throw new RuntimeException("didnt find people who need to update"); } ChangeMessage changeMessage = new ChangeMessage(); changeMessage.setMessage(message); changeMessage.setProperty(property); changeMessage.setNewMessage(NewMassage); int effect = messageDao.updatePeople(changeMessage); return effect == 1; } }
在Service层的实现类上增加了@Transactional注解,现在这个实现类已经被事务管理器所管理了,同时实现类里自动注入了DAO层的接口,在处理完业务的时候可以直接进入DAO层进行数据访问的操作。这个项目所需要的事务处理并不是很多,所以比较简单。
测试的类全都放在test的java目录下的包中,我们在pom.xml文件中导入了测试的依赖,所以可以直接使用测试框架。
package com.dxy.test; import com.dxy.memoapp.entity.Message; import com.dxy.memoapp.service.MessageService; import org.junit.Assert; import org.junit.BeforeClass; import org.junit.Test; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class listApp_Test { private static ApplicationContext context = null; private static MessageService memoGroupService = null; private static Logger logger = LoggerFactory.getLogger(listApp_Test.class); @BeforeClass public static void BeforeTest(){ context = new ClassPathXmlApplicationContext("application-context.xml"); memoGroupService = context.getBean(MessageService.class); } @Test public void Test_AddPeople(){ Message NeedToAdd = new Message(); NeedToAdd.setName("78s9"); NeedToAdd.setNumber("13892"); NeedToAdd.setAddress("7777777"); Boolean ret = memoGroupService.AddPeople(NeedToAdd); Assert.assertTrue(ret); } @Test public void Test_QueryPeople(){ String name = "7777"; Listret = memoGroupService.Querypeople(name); Assert.assertNotNull(ret); logger.debug("query people:{}", ret); } @Test public void Test_DeletePeople(){ Integer id = 4; Boolean ret = memoGroupService.DeletePeople(id); logger.debug("delete is {}",ret); } @Test public void Test_QueryAllPeople(){ memoGroupService.QueryAllPeople(); } @Test public void Test_updatePeople(){ Message message = memoGroupService.Querypeople("55554").get(0); memoGroupService.updatePeople(message, "pname","www"); } }
测试添加联系人
测试删除联系人
测试联系人查找
联系人更新
以上就是基于Spring的一个通讯录小项目的实现,仅供自己学习Spring使用。