將項目劃分爲按照業務劃分能夠劃分爲三層,分別時持久層,業務層,展示層,可是全部的層使用到的對象可能會共用,因此將全部的對象放在領域對象的包內,使得這些公共的類都存放一個包裏面。 單元測試的類包和程序的類包對應,可是方式再不一樣的的文件夾下,這樣的目的是方便程序的打包和發佈,由於測試是在開發的時候使用,無需部署到包中。
包類結構圖以下: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>