将项目划分为按照业务划分能够划分为三层,分别时持久层,业务层,展示层,可是全部的层使用到的对象可能会共用,因此将全部的对象放在领域对象的包内,使得这些公共的类都存放一个包里面。 单元测试的类包和程序的类包对应,可是方式再不一样的的文件夹下,这样的目的是方便程序的打包和发布,由于测试是在开发的时候使用,无需部署到包中。
包类结构图以下:html
集成Spring的系统能够将全部的配置信息统一到一个文件中,也能够放置到多个文件中,对于简单的应用来讲,因为配置信息少,使用一个配置文件足够应付,可是随着配置信息增长,一个配置文件就显得捉襟见肘,对于团队的协做开发也是很不利的。这里咱们的配置信息不多,因此一个配置文件足够应付java
配置内容: flexible-context.xmlmysql
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd"> <!--扫描类,使得使用了注解的类自动生成bean,同时完成Bean的注入--> <context:component-scan base-package="com.flexible.dao"></context:component-scan> <context:component-scan base-package="com.flexible.web"></context:component-scan> <context:component-scan base-package="com.flexible.service"></context:component-scan> <!--使用dbcp做为数据库链接池--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/springdb" p:username="root" p:password="root@123" ></bean> <!--配置JDBC模板--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" ></bean> <!--配置事务管理器--> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager" p:dataSource-ref="dataSource" ></bean> <!--经过AOP配置提供事务加强,让service包下的Bean的全部方法都拥有事务--> <aop:config proxy-target-class="true"> <aop:pointcut id="serviceMethod" expression="(execution(* com.flexible.service..*(..))) and (@annotation(org.springframework.transaction.annotation.Transactional))"/> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice> </beans>
flexible-servlet.xmlgit
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!--扫描web包,应用Sprig的注解--> <context:component-scan base-package="com.flexible.web"/> <!--配置试图解析器,将ModelAndView及字符串解析为具体的页面--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/pages/" p:suffix=".jsp"></bean> </beans>
web.xmlgithub
public class User implements Serializable { /** * 用户id */ private Integer userId; /** * 用户名称 */ private String userName; /** *用户密码 */ private String password; /** *签到分数 */ private Integer credits; /** * 最新Ip */ private String lastIp; /** * 最后访问日期 */ private Date lastVisit; .... }
public class LoginLog { /** * 登录日志id */ private Integer loginLogId; /** * 用户id */ private Integer userId; /** * ip */ private String ip; /** * 登录日期 */ private Date loginDate; ... }
知识点总结: 领域对象能够细分为四种: PO(Persistent Object):持久化对象,表示持久层的的数据结果 DTO(Data Transfer Object):数据传输对象,之前是EJB分布式应用的粗粒度的数据事提,如今泛指展示层于服务之间的数据传输对象,能够堪称和DO等效 DO等等于DTO VO(View Object):试图对象,展现对象。web
一.使用DAO 在DAO实现类中不须要咱们手动得去连接和释放连接,jdbcTemplate将这些都已经抽取出来了,咱们须要作得就是须要在配置文件里面配置 而后将jdbcTemplate使用注解@Autowired注解注入jdbcTemplate变量,因此咱们必须先在配置文件声明数据源和定义jdbcTemplate的beanspring
flexible-context.xmlsql
<!--使用dbcp做为数据库链接池--> <bean id="dataSource" //使用了DBCP数据源 class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close" p:driverClassName="com.mysql.jdbc.Driver" p:url="jdbc:mysql://localhost:3306/springdb" p:username="root" p:password="root@123" ></bean> <!--配置JDBC模板--> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate" p:dataSource-ref="dataSource" ></bean>
Java掉代码 UserDao.java数据库
[@Repository](https://my.oschina.net/u/3055569) public class UserDao { private JdbcTemplate jdbcTemplate; private final static String MATCH_COUNT_SQL = " SELECT count(*) " + "FROM t_user " + "WHERE user_name =? " + "AND password=? "; private final static String UPDATE_LOGIN_INFO_SQL = " UPDATE t_user " + "SET " + "last_visit=?," + "last_ip=?," + "credits=?"+ " WHERE user_id =?"; @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } /** * 根据用户名查询 * * @param userName * @return */ public User getUserByUserName(String userName) { String searchSql = "SELECT user_id,user_name,credits " + "FROM t_user " + "WHERE user_name=?"; final User user = new User(); jdbcTemplate.query(searchSql, new Object[]{userName}, (resultSet) -> { user.setUserId(resultSet.getInt("user_id")); user.setUserName(userName); user.setCredits(resultSet.getInt("credits")); }); return user == null ? new User() : user; } /** * 更新用户登录日志 * * @param user */ public Boolean updateLoginInfo(User user) { System.out.println(user.toString()); Integer flag = jdbcTemplate.update(UPDATE_LOGIN_INFO_SQL, new Object[] { user.getLastVisit(), user.getLastIp(),user.getCredits(),user.getUserId()}); return flag > 0 ? true : false; } /** * 根据帐号和密码查找匹配的数量 * * @param userName * @param password * @return */ public int getMatchCount(String userName, String password) { return jdbcTemplate.queryForObject(MATCH_COUNT_SQL, new Object[]{userName, password}, Integer.class); } }
LoginLogDao.javaexpress
@Repository public class LoginLogDao { private JdbcTemplate jdbcTemplate; //保存登录日志SQL private final static String INSERT_LOGIN_LOG_SQL= "INSERT INTO t_login_log(user_id,ip,login_datetime) VALUES(?,?,?)"; public void insertLoginLog(LoginLog loginLog) { Object[] args = { loginLog.getUserId(), loginLog.getIp(), loginLog.getLoginDate() }; jdbcTemplate.update(INSERT_LOGIN_LOG_SQL, args); } @Autowired public void setJdbcTemplate(JdbcTemplate jdbcTemplate) { this.jdbcTemplate = jdbcTemplate; } }
二.使用Mapper
事务管理代码没有出如今程序的代码中,可是咱们须要以某种方式告诉Spring哪些业务须要工做在事务环境下以及事务的规则等内容,以便Spring根据这些信息自动为目标业务添加事务管理的能力 flexible-context.xml
<!--扫描事务层的代码--> <context:component-scan base-package="com.flexible.service"> </context:component-scan> <!--经过AOP配置提供事务加强,让service包下的Bean的全部方法都拥有事务--> <aop:config proxy-target-class="true"> <aop:pointcut id="serviceMethod" expression="(execution(* com.flexible.service..*(..))) and (@annotation(org.springframework.transaction.annotation.Transactional))"/> <aop:advisor pointcut-ref="serviceMethod" advice-ref="txAdvice"/> </aop:config> <tx:advice id="txAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="*"/> </tx:attributes> </tx:advice>
在Java代码里面咱们须要作的就是将方法上面声明一个注解 @Transactional,例如
@Transactional public void loginSuccess(User user) { user.setCredits(5 + user.getCredits()); LoginLog loginLog = new LoginLog(); loginLog.setUserId(user.getUserId()); loginLog.setIp(user.getLastIp()); loginLog.setLoginDate(user.getLastVisit()); userDao.updateLoginInfo(user); loginLogDao.insertLoginLog(loginLog); }
TestNG和JUnit相比有较大的改进,须要将TestNG依赖添加进pom.xml.Spring4.x的测试框架很好的整合了TestNG单元测试框架,经过继承AbstractTransactionalTestNGSpringContextTests类来启动测试运行器,@ContextConfiguration用于知道Spring的配置文件。
<dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> <scope>test</scope> </dependency>
单元测试代码以下:
@ContextConfiguration("classpath*:/flexible-context.xml") public class UserServiceTest extends AbstractTransactionalTestNGSpringContextTests { @Autowired UserService userService; @Test public void testHasMatchUser(){ boolean b1 = userService.hasMatchUser("admin", "123456"); boolean b2 = userService.hasMatchUser("admin", "1111"); assertTrue(b1); assertTrue(!b2); } }
Spring3.0提供了REST风格的MVC,是SpringMvc变得更加的轻便,易用。Spring4.x对mvc金行了全面的升级,支持了@CrossOrigi配置,Groovy Web集成,Gson,Jackson,Protobuf的HttpMessageConverter消息转换器,使得SpringMvc的功能更加丰富,强大。
@RestController public class LoginController { private UserService userService; @Autowired public void setUserService(UserService userService) { this.userService = userService; } @RequestMapping(value = "/index.html") public String loginPage() { return "login"; } @RequestMapping(value = "/loginCheck.html") public ModelAndView loginCheck(HttpServletRequest request, LoginCommand loginCommand) { boolean isValidUser = userService.hasMatchUser(loginCommand.getUserName(), loginCommand.getPassword()); System.out.println("the request parameter is username {},password {}" + loginCommand.getUserName() + "," + loginCommand.getPassword()); if (!isValidUser) { return new ModelAndView("login", "error", "用户名或密码错误。"); } else { User user = userService.findUserByUserName(loginCommand .getUserName()); user.setLastIp(request.getLocalAddr()); user.setLastVisit(new Date()); userService.loginSuccess(user); request.getSession().setAttribute("user", user); return new ModelAndView("main"); } } }
ModelAndView对象既包括试图信息,又包括渲染试图须要的模型信息,解析试图的配置在flexible-servlet.xml
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"> <!--扫描web包,应用Sprig的注解--> <context:component-scan base-package="com.flexible.web"/> <!--配置试图解析器,将ModelAndView及字符串解析为具体的页面--> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:viewClass="org.springframework.web.servlet.view.JstlView" p:prefix="/WEB-INF/pages/" p:suffix=".jsp"></bean> </beans>