SSM框架整合-實現CRUD,登入和分頁操作
二.專案結構:spring+springmvc+mybatis+maven+mysql+freemark+jetty
三.專案介紹:主要實現登入 crud以及分頁效果
1.登入介面
2.主頁
3.新增頁面
4.編輯頁面
四.搭建
1)準備配置檔案
jar包依賴 這裡推薦一個外掛 mavenHelper.jar 可以自動檢測jar包的衝突依賴關係
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.zj</groupId> <artifactId>Test-User</artifactId> <packaging>war</packaging> <version>0.0.1-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.build.resourceEncoding>UTF-8</project.build.resourceEncoding> <!-- 定義spring的版本變數在dependency裡面直接引用 --> <spring.version>4.3.2.RELEASE</spring.version> <slf4j.version>1.7.2</slf4j.version> </properties> <dependencies> <!-- spring web --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${spring.version}</version> </dependency> <!-- spring mvc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${spring.version}</version> </dependency> <!-- web開發要有servlet --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.0.1</version> </dependency> <!-- spring 測試 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${spring.version}</version> </dependency> <!-- 單元測試 --> <!-- <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency>--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <!-- spring jdbc --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <!-- spring事物 --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-context-support</artifactId> <version>${spring.version}</version> </dependency> <!-- aspectj切面程式設計的jar --> <dependency> <groupId>org.aspectj</groupId> <artifactId>aspectjweaver</artifactId> <version>1.8.9</version> </dependency> <!-- tomcat 連線池 --> <dependency> <groupId>org.apache.tomcat</groupId> <artifactId>tomcat-jdbc</artifactId> <version>7.0.42</version> </dependency> <!-- mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.1</version> </dependency> <!-- 新增mybatis與Spring整合的核心包 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency> <!-- mysql 驅動包 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.39</version> </dependency> <!-- 日誌列印相關的jar --> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>${slf4j.version}</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>${slf4j.version}</version> </dependency> <!-- mybatis分頁外掛 --> <dependency> <groupId>com.github.miemiedev</groupId> <artifactId>mybatis-paginator</artifactId> <version>1.2.17</version> <exclusions> <exclusion> <artifactId>mybatis</artifactId> <groupId>org.mybatis</groupId> </exclusion> </exclusions> </dependency> <!-- Template Language --> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.21</version> </dependency> <!-- Java utility類 --> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.3.2</version> </dependency> <!-- fastjson配置 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.13</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.8.1</version> </dependency> <dependency> <groupId>org.codehaus.jackson</groupId> <artifactId>jackson-mapper-asl</artifactId> <version>1.9.12</version> </dependency> <!--GSON--> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.0</version> </dependency> <!--kaptcha--> <dependency> <groupId>com.github.axet</groupId> <artifactId>kaptcha</artifactId> <version>0.0.9</version> </dependency> <!--spring session--> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session</artifactId> <version>1.3.1.RELEASE</version> </dependency> <dependency> <groupId>redis.clients</groupId> <artifactId>jedis</artifactId> <version>2.9.0</version> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>RELEASE</version> </dependency> <!-- <dependency> <groupId>com.alibaba</groupId> <artifactId>sms-dayu</artifactId> <version>1.0</version> </dependency>--> </dependencies> <build> <finalName>Test-User</finalName> <!-- 資原始檔的設定 --> <plugins> <!-- compiler plugin --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>2.3.2</version> <configuration> <source>1.7</source> <target>1.7</target> <encoding>UTF-8</encoding> <compilerArguments> <bootclasspath>${java.home}/lib/rt.jar</bootclasspath> </compilerArguments> </configuration> </plugin> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>9.2.1.v20140609</version> <configuration> <!--<webAppSourceDirectory>WebContent</webAppSourceDirectory>--> <!--<scanIntervalSeconds>3</scanIntervalSeconds>--> <!--<contextXml>src/main/resources/jetty-contexts.xml</contextXml>--> <webAppConfig> <!--<contextPath>/crm</contextPath>--> <!-- 此處指定預設Jetty Web配置檔案 <defaultsDescriptor>src/main/resources/webdefault.xml</defaultsDescriptor> --> </webAppConfig> </configuration> </plugin> </plugins> </build> </project>
準備spring-mybatis.xml spring整合對資料庫的配置
<?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: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-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd"> <!-- 自動掃描 --> <context:component-scan base-package="com.zj" /> <!-- 引入配置檔案 --> <bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> <property name="location" value="classpath:jdbc.properties" /> </bean> <!-- 配置資料來源 --> <bean id="dataSource" class="org.apache.tomcat.jdbc.pool.DataSource" destroy-method="close"> <property name="poolProperties"> <bean class="org.apache.tomcat.jdbc.pool.PoolProperties"> <property name="driverClassName" value="${JDBC.driver}"/> <property name="url" value="${JDBC.url}"/> <property name="username" value="${JDBC.username}"/> <property name="password" value="${JDBC.password}"/> <property name="jmxEnabled" value="true"/> <property name="testWhileIdle" value="true"/> <property name="testOnBorrow" value="true"/> <property name="testOnReturn" value="false"/> <property name="validationInterval" value="30000"/> <property name="validationQuery" value="SELECT 1"/> <property name="timeBetweenEvictionRunsMillis" value="30000"/> <property name="maxActive" value="200"/> <property name="initialSize" value="10"/> <property name="maxWait" value="30000"/> <property name="minEvictableIdleTimeMillis" value="30000"/> <property name="minIdle" value="10"/> <property name="logAbandoned" value="false"/> <property name="removeAbandoned" value="true"/> <property name="removeAbandonedTimeout" value="60"/> <property name="jdbcInterceptors" value="org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer"/> </bean> </property> </bean> <!-- spring和MyBatis完美整合,不需要mybatis的配置對映檔案 --> <!-- 配置sqlSessionFactory --> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- mybatis配置檔案的路徑 --> <property name="configLocation" value="classpath:mybatis.xml" /> <!-- 例項化sqlSessionFactory時需要使用上述配置好的資料來源以及SQL對映檔案 --> <property name="dataSource" ref="dataSource" /> <!-- 自動掃描/mapper/下所有以xml結尾的檔案--> <property name="mapperLocations" value="classpath:/mapper/*.xml" /> </bean> <!-- DAO介面所在包名,Spring會自動查詢其下的類 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.zj.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"></property> </bean> <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 設定事物增強 --> <tx:advice id="txAdvice" transaction-manager="txManager"> <tx:attributes> <tx:method name="get*" read-only="true" /> <tx:method name="find*" read-only="true" /> <tx:method name="query*" read-only="true" /> <tx:method name="load*" read-only="true" /> <tx:method name="add*" rollback-for="Exception"/> <tx:method name="insert*" rollback-for="Exception" /> <tx:method name="update*" rollback-for="Exception" /> <tx:method name="delete*" rollback-for="Exception" /> </tx:attributes> </tx:advice> <!-- 配置掃描器 --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <!-- 掃描com.shsxt.crm.dao這個包以及它的子包下的所有對映介面類 --> <property name="basePackage" value="com.zj.dao" /> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" /> </bean> </beans>
準備spring-mvc.xml 配置檢視 aop
<?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:mvc="http://www.springframework.org/schema/mvc" xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:task="http://www.springframework.org/schema/task" xsi:schemaLocation=" http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.5.xsd http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-4.3.xsd "> <!-- 自動掃描該包,使SpringMVC認為包下用了@controller註解的類是控制器 --> <context:component-scan base-package="com.zj.controller" /> <mvc:annotation-driven /> <!-- 靜態資原始檔的處理--> <mvc:default-servlet-handler /> <!-- 啟用@Aspect註解 --> <aop:aspectj-autoproxy /> <!-- 檢視配置 --> <bean id="freemarkerConfig" class="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer" > <property name="templateLoaderPath" value="/WEB-INF/views/" /> <property name="defaultEncoding" value="UTF-8" /> <property name="freemarkerSettings"> <props> <prop key="number_format">0.##########</prop> <!--解決數字問題--> <prop key="boolean_format">true,false</prop> <!--解決頁面布林值的輸出--> <prop key="tag_syntax">square_bracket</prop> <!-- auto_detect:自動選擇(選擇第一種標籤語法) angle_bracket(<#if>) square_bracket[#if]--> <prop key="classic_compatible">true</prop> <!--非空不會報錯--> <prop key="template_update_delay">0</prop> <!--快取時間--> <prop key="default_encoding">UTF-8</prop> <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop> <prop key="date_format">yyyy-MM-dd</prop> <prop key="time_format">HH:mm:ss</prop> </props> </property> <property name="freemarkerVariables"> <map> <entry key="student_list" value-ref="studentDirective" /> </map> </property> </bean> <!-- 檢視解析器 --> <bean class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver"> <property name="prefix" value="" /> <property name="suffix" value=".ftl" /> <property name="contentType" value="text/html;charset=UTF-8"/> </bean> <!-- 文字轉化 --> <mvc:annotation-driven> <mvc:message-converters> <bean class="org.springframework.http.converter.StringHttpMessageConverter"/> <bean class="org.springframework.http.converter.json.MappingJackson2HttpMessageConverter"/> </mvc:message-converters> </mvc:annotation-driven> </beans>
準備mybatis.xml 配置實體層和分頁外掛
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 通過別名簡化對類的使用 --> <typeAliases> <!-- 通過package, 可以直接指定package的名字, mybatis會自動掃描你指定包下面的javabean, 並且預設設定一個別名,預設的名字為非限定類名來作為它的別名。 --> <package name="com.zj.model" /> </typeAliases> <plugins> <!-- 分頁外掛配置 --> <plugin interceptor="com.github.miemiedev.mybatis.paginator.OffsetLimitInterceptor"> <property name="dialectClass" value="com.github.miemiedev.mybatis.paginator.dialect.MySQLDialect"/> </plugin> </plugins> </configuration>
準備log4j.porperties
<span style="color:#666666;"># Global logging configuration log4j.rootLogger=INFO,stdout,file # MyBatis logging configuration... log4j.logger.com.sdrd.mapper=DEBUG #log4j.logger.org.mybatis.example.BlogMapper=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] %c{1}:%L - %m%n ### direct messages to file file.log ### #log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file=org.apache.log4j.DailyRollingFileAppender log4j.appender.file.DatePattern='.'yyyy-MM-dd'.log' log4j.appender.file.Threshold = INFO log4j.appender.file.append=true log4j.appender.file.File=./logs/info.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss} %5p %c{1}:%L - %m%n
jdbc.porperties配置檔案
JDBC.username=root JDBC.password=root JDBC.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf8 JDBC.driver=com.mysql.jdbc.Driver
這些檔案都是放在resource下
web.xml配置 web專案的入口 配置掃描以上檔案產生聯動
<?xml version="1.0" encoding="UTF-8"?> <web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" version="3.0"> <display-name>Archetype Created Web Application</display-name> <!-- Spring和mybatis的配置檔案 --> <context-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mybatis.xml</param-value> </context-param> <!-- 編碼過濾器 --> <filter> <filter-name>encodingFilter</filter-name> <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class> <async-supported>true</async-supported> <init-param> <param-name>encoding</param-name> <param-value>UTF-8</param-value> </init-param> </filter> <filter-mapping> <filter-name>encodingFilter</filter-name> <url-pattern>/*</url-pattern> </filter-mapping> <!-- Spring監聽器 --> <listener> <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> </listener> <!-- 防止Spring記憶體溢位監聽器 --> <listener> <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class> </listener> <!-- Spring MVC servlet --> <servlet> <servlet-name>SpringMVC</servlet-name> <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class> <init-param> <param-name>contextConfigLocation</param-name> <param-value>classpath:spring-mvc.xml</param-value> </init-param> <load-on-startup>1</load-on-startup> <async-supported>true</async-supported> </servlet> <servlet-mapping> <servlet-name>SpringMVC</servlet-name> <!-- 此處可以可以配置成*.do,對應struts的字尾習慣 --> <url-pattern>/</url-pattern> </servlet-mapping> <welcome-file-list> <welcome-file>/index.jsp</welcome-file> </welcome-file-list> </web-app>
2)準備實體類
因為要進行分頁操作先定義一個BaseDto
package com.zj.model; import com.github.miemiedev.mybatis.paginator.domain.Order; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; import org.apache.commons.lang3.StringUtils; public class BaseDto { private Integer page; private Integer pageSize; private String sort; public String getSort() { return sort; } public void setSort(String sort) { this.sort = sort; } public Integer getPage() { return page; } public void setPage(Integer page) { this.page = page; } public Integer getPageSize() { return pageSize; } public void setPageSize(Integer pageSize) { this.pageSize = pageSize; } public PageBounds buildPageBounds(){ if(this.page == null||this.page<1){ this.page = 1; } if(this.pageSize==null||this.pageSize<1){ this.pageSize = 2; } PageBounds pageBounds = new PageBounds(this.page,this.pageSize); if (StringUtils.isNotBlank(this.sort)) { pageBounds.setOrders(Order.formString(this.sort)); } return pageBounds; } }
接著定義User類和Student類
package com.zj.model; import java.io.Serializable; public class User implements Serializable{ private Integer userId; private String userName; private String userPassword; private Integer uid; public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserPassword() { return userPassword; } public void setUserPassword(String userPassword) { this.userPassword = userPassword; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userPassword='" + userPassword + '\'' + ", uid=" + uid + '}'; } }
package com.zj.model; public class Student extends BaseDto{ private Integer id; private String name; private Integer gender; private Integer age; private Integer uid; public Integer getUid() { return uid; } public void setUid(Integer uid) { this.uid = uid; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getGender() { return gender; } public void setGender(Integer gender) { this.gender = gender; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Student{" + "id=" + id + ", name='" + name + '\'' + ", gender=" + gender + ", age=" + age + ", uid=" + uid + '}'; } }
建完以後大家是不是發現有個IsLogin的註解類 這個註解是用來進行登入驗證的 想想看 進行crud的時候是不是要登入以後才能進行 那我們利用aop和註解實現這麼一個功能 在crud的方法上加上這個標籤就可以實現這個功能是不是就很簡單 開始
定義一個註解的名字
package com.zj.model; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; @Target({ElementType.METHOD,ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) public @interface IsLogin { }
然後給這個註解加上功能
package com.zj.proxy; import com.zj.exception.LoginException; import com.zj.model.IsLogin; import com.zj.model.User; import javafx.fxml.LoadException; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; import org.aspectj.lang.annotation.Pointcut; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import javax.servlet.http.HttpSession; @Component @Aspect public class LoginProxy { @Autowired private HttpSession session; @Pointcut(value = "@annotation(com.zj.model.IsLogin)") private void pointcut(){ } @Before(value="pointcut()") public void beforeMethod(JoinPoint joinPoint){ User user = (User) session.getAttribute("user"); System.out.println("-------進行登入驗證-------"); if(user == null){ throw new LoginException("請先登入"); } } }
接著來 定義一個結果類 什麼操作都要有個結果 對吧 這樣前臺才好判斷是不是執行成功或者失敗 對吧
package com.zj.result; public class ResultInfo { String mes; int code; public ResultInfo(){ } public ResultInfo(String mes){ this.mes = mes; } public String getMes() { return mes; } public void setMes(String mes) { this.mes = mes; } public int getCode() { return code; } public void setCode(int code) { this.code = code; } }
2)準備工具類和異常類
package com.zj.exception; import com.alibaba.fastjson.JSON; import com.zj.controller.BaseController; import com.zj.result.ResultInfo; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.io.PrintWriter; @ControllerAdvice public class GlobalExceptionHandler extends BaseController { @ExceptionHandler(value = LoginException.class) public String handlerParamException(LoginException loginException, HttpServletRequest request, HttpServletResponse response,Model model){ model.addAttribute("proPath", request.getContextPath()); String xmlHttpRequest = request.getHeader("X-Requested-With"); return "login"; } }
package com.zj.exception; public class LoginException extends RuntimeException { private int errCode; public int getErrCode() { return errCode; } public void setErrCode(int errCode) { this.errCode = errCode; } public LoginException(){ } public LoginException(String mes) { super(mes); } }
package com.zj.exception; public class ParameterException extends RuntimeException { public ParameterException(){ } public ParameterException(String mes){ super(mes); } }
package com.zj.util; import com.zj.exception.ParameterException; public class AssertUtil { public static void isNull(Object value){ if(value == null){ throw new ParameterException("不能空"); } } }
3)準備dao,service和controller的編寫
再來寫使用者登陸的Dao層和對學生操作的Dao層
package com.zj.dao; import com.zj.model.User; import org.apache.ibatis.annotations.Select; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface UserDao { @Select("select * from usertable where userName =#{userName} and userPassword =#{userPassword}") public User login(User user); /*測試*/ List<User> test(); }
package com.zj.dao; import com.github.miemiedev.mybatis.paginator.domain.PageBounds; import com.github.miemiedev.mybatis.paginator.domain.PageList; import com.zj.model.Student; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; import org.springframework.stereotype.Repository; @Repository public interface StudentDao { @Select("select a.* from student a,usertable b where a.uid=b.uid and limit #{limit}") PageList<Student> findListStudent(@Param(value = "limit") Integer limit); @Select("select * from student ") PageList<Student> findStudent(PageBounds pageBounds); @Select("select a.* from student a,usertable b where a.uid=b.uid and a.id=#{id}") Student findStudentById(@Param(value = "id") Integer id); @Update({"insert student(name,gender,age,uid) values(#{name},#{gender},#{age},#{uid})"}) void addStudent(Student student); @Update({"UPDATE student set name=#{name},gender=#{gender},age=#{age} where id = #{id} and uid=#{uid}"}) void updateStudent(Student student); @Delete("delete from student where id=#{id} and uid=#{uid}") void deleteStudent(@Param(value = "id") Integer id,@Param(value = "uid") Integer uid); }
接著來service層
package com.zj.service; import com.zj.dao.UserDao; import com.zj.model.User; import com.zj.util.RedisUtil; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; @Service public class UserService{ @Autowired private UserDao userDao; private Logger log = Logger.getLogger(UserService.class); RedisUtil r = new RedisUtil(); public User login(User user,String id) { log.info("使用者登入:"+user); return userDao.login(user); } }
package com.zj.service; import com.github.miemiedev.mybatis.paginator.domain.PageList; import com.zj.dao.StudentDao; import com.zj.model.Student; import com.zj.result.ResultInfo; import com.zj.util.AssertUtil; import org.apache.log4j.Logger; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class StudentService { @Autowired private StudentDao studentDao; private static Logger log = Logger.getLogger(StudentService.class); public ResultInfo addStudent(Integer uid,Student student){ ResultInfo resultInfo = new ResultInfo(); log.info("addStudent入參:"+resultInfo); if(student!=null){ student.setUid(uid); studentDao.addStudent(student); resultInfo.setCode(200); resultInfo.setMes("新增成功"); return resultInfo; } resultInfo.setCode(300); resultInfo.setMes("新增失敗"); return resultInfo; } public ResultInfo updateStudent(Student student,Integer uid){ ResultInfo resultInfo = new ResultInfo(); log.info("updateStudent入參:"+student.toString()); if(student!=null){ student.setUid(uid); studentDao.updateStudent(student); resultInfo.setCode(200); resultInfo.setMes("新增成功"); return resultInfo; } resultInfo.setCode(300); resultInfo.setMes("新增失敗"); return resultInfo; } public void deleteStudent(Integer id,Integer uid){ AssertUtil.isNull(id); studentDao.deleteStudent(id,uid); log.info("deleteStudents刪除ID:"+id); } public Student findStudentById(Integer id,Integer uid){ AssertUtil.isNull(id); log.info("findStudentById尋找ID:"+id); return studentDao.findStudentById(id); } public PageList<Student> findListStudent(Integer limit){ PageList<Student> students = studentDao.findListStudent(limit); return students; } public PageList<Student> findStudent(Student student){ PageList<Student> students = studentDao.findStudent(student.buildPageBounds()); return students; } }
再來controller層
首先來個BaseController 儲存專案路徑(tomcat啟動的有用)
package com.zj.controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.ModelAttribute; import javax.servlet.http.HttpServletRequest; public class BaseController { @ModelAttribute protected void preMethod(HttpServletRequest request, Model model) { String ctx = request.getContextPath(); System.out.println("ctx------------->"+ctx); model.addAttribute("proPath",ctx); } }
接著使用者和學生的controller層
package com.zj.controller; import com.zj.model.User; import com.zj.result.ResultInfo; import com.zj.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.annotation.Resource; import javax.imageio.ImageIO; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.util.Random; @Controller @RequestMapping("user") public class UserController extends BaseController{ @Autowired private UserService userService; /* * 登入操作 * */ @RequestMapping("login") @ResponseBody public ResultInfo login(User user, HttpServletRequest request, HttpSession session){ ResultInfo resultInfo = new ResultInfo(); String id = request.getSession().getId(); User acc= userService.login(user,id); System.out.println("sessioid---------------->"+id); if(acc!=null){ //存session session.setAttribute("user", acc); resultInfo.setCode(200); resultInfo.setMes("登陸成功"); return resultInfo; } resultInfo.setCode(300); resultInfo.setMes("登入失敗"); return resultInfo; } /* * 跳轉主頁 * */ @RequestMapping("index") public String index(HttpServletRequest request, HttpSession session){ User user = (User)session.getAttribute("user"); if(user!=null){ return "redirect:/student/main"; } return "login"; } /* * 登出操作 * */ @RequestMapping("out") public String out(HttpSession session){ session.removeAttribute("user"); return "login"; } /* * 生成驗證碼 * */ @RequestMapping("yzm") public void sendYzm(HttpServletRequest request, HttpServletResponse response) throws IOException { // 圖片高度 final int IMG_HEIGHT = 100; // 圖片寬度 final int IMG_WIDTH = 25; // 驗證碼長度 final int CODE_LEN = 4; // 用於繪製圖片,設定圖片的長寬和圖片型別(RGB) BufferedImage bi = new BufferedImage(IMG_HEIGHT, IMG_WIDTH, BufferedImage.TYPE_INT_RGB); // 獲取繪圖工具 Graphics graphics = bi.getGraphics(); graphics.setColor(new Color(100, 230, 200)); // 使用RGB設定背景顏色 graphics.fillRect(0, 0, 100, 30); // 填充矩形區域 // 驗證碼中所使用到的字元 char[] codeChar = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456".toCharArray(); String captcha = ""; // 存放生成的驗證碼 Random random = new Random(); for(int i = 0; i < CODE_LEN; i++) { // 迴圈將每個驗證碼字元繪製到圖片上 int index = random.nextInt(codeChar.length); // 隨機生成驗證碼顏色 graphics.setColor(new Color(random.nextInt(150), random.nextInt(200), random.nextInt(255))); // 將一個字元繪製到圖片上,並制定位置(設定x,y座標) graphics.drawString(codeChar[index] + "", (i * 20) + 15, 20); captcha += codeChar[index]; } // 將生成的驗證碼code放入sessoin中 request.getSession().setAttribute("code", captcha); // 通過ImageIO將圖片輸出 ImageIO.write(bi, "JPG", response.getOutputStream()); } /* * 驗證碼校驗 * */ @RequestMapping("check") @ResponseBody public ResultInfo checkYzm(HttpServletRequest request, HttpServletResponse response){ ResultInfo resultInfo = new ResultInfo(); // 獲取存放在session中的驗證碼 String code = (String) request.getSession().getAttribute("code"); // 獲取頁面提交的驗證碼 String inputCode = request.getParameter("code"); if(code.toLowerCase().equals(inputCode.toLowerCase())) { // 驗證碼不區分大小寫 // 驗證成功,跳轉到成功頁面 resultInfo.setCode(200); } else { // 驗證失敗 resultInfo.setCode(300); resultInfo.setMes("驗證碼錯誤"); } return resultInfo; } }
package com.zj.controller; import com.github.miemiedev.mybatis.paginator.domain.PageList; import com.zj.model.IsLogin; import com.zj.model.Student; import com.zj.model.User; import com.zj.result.ResultInfo; import com.zj.service.StudentService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.ui.Model; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpSession; @Controller @RequestMapping("student") public class StudentController extends BaseController{ @Autowired private StudentService studentService; /* * 新增操作 * */ @RequestMapping("add") @ResponseBody @IsLogin public ResultInfo addStudent(HttpServletRequest request,Student student){ HttpSession session = request.getSession(); User user = (User)session.getAttribute("user"); int uid = user.getUid(); return studentService.addStudent(uid,student); } /* * 跳轉新增檢視 * */ @RequestMapping("addView") @IsLogin public String addView(){ return "addView"; } /* * 跳轉主頁 * */ @RequestMapping("main") @IsLogin public String findListStudent(Student student, Model model){ PageList<Student> students = studentService.findStudent(student); model.addAttribute("students",students); model.addAttribute("pagenator",students.getPaginator()); model.addAttribute("student",student); return "main"; } /* * 刪除操作 * */ @RequestMapping("delete/{id}") @IsLogin public String deleteStudent(@PathVariable Integer id,@PathVariable Integer uid){ studentService.deleteStudent(id,uid); return "redirect:/student/main"; } /* * 跳轉編輯頁面 * */ @RequestMapping("updateView/{id}") @IsLogin public String updateView(@PathVariable Integer id,Model model,HttpSession session){ User user = (User) session.getAttribute("user"); Student student = studentService.findStudentById(id,user.getUid()); model.addAttribute("student",student); return "update"; } /* * 編輯操作 * */ @RequestMapping("update") @ResponseBody public ResultInfo updateStudent(Student student, HttpServletRequest request, HttpSession session){ User user = (User) session.getAttribute("user"); /*if(user == null){ ResultInfo resultInfo = new ResultInfo(); resultInfo.setCode(300); resultInfo.setMes("請先登入"); return resultInfo; }*/ return studentService.updateStudent(student,user.getUid()); } }
其實我這不規範 對邏輯的處理都應該放在service層的 懶得改了... 有興趣的同學自行修改
因為前臺使用的freemark所以 頁面的展示資料我通過TemplateDirectiveModel實現
package com.zj.directive; import com.alibaba.fastjson.JSON; import freemarker.core.Environment; import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.BeansWrapperBuilder; import freemarker.template.*; import java.io.IOException; import java.util.HashMap; import java.util.Map; public abstract class BaseDirective implements TemplateDirectiveModel{ //獲取引數值 public <T> T getParameter(String paramName,Map params,Class<?> clazz) throws TemplateException{ BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build(); //獲取引數 TemplateModel templateModel = (TemplateModel) params.get(paramName); T value = (T) beansWrapper.unwrap(templateModel, clazz); return value; } //輸出 public void setVariable(Environment env, TemplateDirectiveBody body,String key,Object value) throws TemplateException,IOException{ BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_21).build(); TemplateModel templateModel = beansWrapper.wrap(value); env.setVariable(key, templateModel); // 輸出 if (body != null) { body.render(env.getOut()); } else { env.getOut().write(JSON.toJSONString(value)); } } }
package com.zj.directive; import com.alibaba.fastjson.JSON; import com.zj.model.Student; import com.zj.model.User; import com.zj.service.StudentService; import com.zj.service.UserService; import freemarker.core.Environment; import freemarker.ext.beans.BeansWrapper; import freemarker.ext.beans.BeansWrapperBuilder; import freemarker.template.*; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import java.io.IOException; import java.util.List; import java.util.Map; @Component public class StudentDirective extends BaseDirective{ @Autowired private StudentService studentService; @Override public void execute(Environment env, Map params, TemplateModel[] loopVars, TemplateDirectiveBody body) throws TemplateException, IOException { Integer limit = getParameter("limit", params, Integer.class); List<Student> students = studentService.findListStudent(limit); setVariable(env,body,"students",students); } }
4)全部完成後 進行前臺頁面的編寫
登入頁
<html> <head> <title>Login page</title> <script src="${proPath}/statics/js/jquery-1.11.3.js"></script> <script src="${proPath}/statics/js/jquery.js"></script> <script type="text/javascript"> function flushCode() { // 每次重新整理的時候獲取當前時間,防止瀏覽器快取重新整理失敗 var time = new Date(); document.getElementById("scode").src = "${proPath}/user/yzm?time=" + time; } function check() { var userName = $("#name").val(); var password = $("#password").val(); if(userName == ""){ alert("使用者名稱不能為空"); return; } if(password == ""){ alert("密碼不能為空"); return; } $.ajax({ url:'${proPath}/user/check', data:{ code:$("#yzm").val() }, type:'post', dataType:'json', success:function (data) { if(data.code==200){ $.ajax({ url:'${proPath}/user/login', data:{ userName:userName, userPassword:password }, type:'post', dataType:'json', success:function (data) { if(data.code == 200){ window.location.href="${proPath}/student/main"; }else{ alert(data.mes); } } }) }else{ alert(data.mes); } } }) } </script> </head> <body> <div id="loginDiv"> <div style="position:absolute;width:500px;height:200px;top:200px;left:550px"> <table border=""> <tr> <td> <label for="name">賬號:</label> </td> <td> <input type="text" id="name" name="userName" /> </td> </tr> <tr> <td> <label for="password">密碼:</label> </td> <td> <input type="text" id="password" name="userPassword" /> </td> </tr> <tr> <td> <label for="yzm">驗證碼:</label> </td> <td> <input type="text" id="yzm" name="userYzm" /> <img alt="驗證碼" id="scode" src="${proPath}/user/yzm" > <a href="#" onclick="javascript:flushCode();">看不清?</a> </td> </tr> <tr> <td colspan="2" align="center"> <button type="button" onclick="check()">登入</button> </td> </tr> </table> </div> <div style="color:red">${requestScope.msg}</div> </div> </body> </html>
主頁
<html xmlns="http://www.w3.org/1999/html"> <head> <title>Main</title> <script src="${proPath}/statics/js/jquery.js" type=text/javascript></script> <script type="text/javascript"> $(function () { $.pageSkip = function(pageNumber) { $("#pageNumber").val(pageNumber); $("#student").submit(); return false; } }) </script> </head> <body> <div style="position:absolute;width:500px;height:200px;top:200px;left:550px"> <form id="student" action="${proPath}/student/main" method="post"> <input type="hidden" id="pageNumber" name="page" value="${student.page}" /> <input type="hidden" id="pageSize" name="pageSize" value="${student.pageSize}" /> <table border=""> <tr> <td>編號</td> <td>姓名</td> <td>級別</td> <td>年齡</td> <td>操作</td> </tr> [#if students?has_content] [#list students as student] <tr> <td>${student.id}</td> <td>${student.name}</td> <td>${student.gender}</td> <td>${student.age}</td> <td> [#--<a href="${proPath}/student/buyView/${student.id}">購買</a>|--] <a href="${proPath}/student/updateView/${student.id}">編輯</a>| <a href="${proPath}/student/delete/${student.id}">刪除</a> </td> </tr> [/#list] [#else] <tr align="center"> <td colspan="5">無資料...</td> </tr> [/#if] <tr align="center"> <td colspan="5"> [#if pagenator.totalPages>1] [#if pagenator.isFirstPage()] [#else] <a href="javascript: $.pageSkip(1);" class="">首頁</a> [/#if] [#if pagenator.hasPrePage] <a href="javascript: $.pageSkip(${pagenator.prePage});" class="previousPage">上一頁</a> [#else] <span class="previousPage"> </span> [/#if] [#list pagenator.slider(3) as slider ] [#if slider==pagenator.page ] <span class="currentPage">${slider}</span> [#else] <a href="javascript: $.pageSkip(${slider});">${slider}</a> [/#if] [/#list] [#if pagenator.hasNextPage] <a href="javascript: $.pageSkip(${pagenator.nextPage});" class="nextPage">下一頁</a> [#else] <span class="nextPage"> </span> [/#if] [#if pagenator.isLastPage()] <span class="lastPage" > </span> [#else] <a href="javascript: $.pageSkip(${pagenator.totalPages});" class="lastPage">末頁</a> [/#if] [/#if] </td> </tr> <tr align="center" > <td colspan="5"> <a href="${proPath}/student/addView">新增</a> <a href="${proPath}/user/out">退出</a> </td> </tr> </table> </form </div> </body> </html>
新增頁
<html> <head> <title>Main</title> <script src="${proPath}/statics/js/jquery.js" type=text/javascript></script> <script type="text/javascript"> $(function(){ $("#back").click(function () { window.location.href="main"; }) $("#add").click(function () { var name = $("#name").val(); var gender = $("#gender").val(); var age = $("#age").val(); if(name!=""&&gender!=""&&age!=""){ $.ajax({ type:'post', url:'${proPath}/student/add', data:$('#form').serialize(), dataType:'json', success:function (data) { console.log('...'); if(data.code==200){ console.log(data.mes); window.location.href="main"; }else{ console.log(data.mes); } } }) }else{ alert("請填寫完整..."); } }) }) </script> </head> <body> <div style="position:absolute;width:500px;height:200px;top:200px;left:550px"> <form id="form" method="post" > <table border=""> <tr> <td>姓名</td> <td><input id="name" type="text" name="name"/></td> </tr> <tr> <td>級別</td> <td><input id="gender" type="text" name="gender"/></td> </tr> <tr> <td>年齡</td> <td><input id="age" type="text" name="age"/></td> </tr> <tr align="center"> <td colspan="4"> <button type="button" id="add">新增</button> <button type="button" id="back">返回</button> </td> </tr> </table> </form> </div> </body> </html>
編輯頁
<html> <head> <title>Main</title> <script src="${proPath}/statics/js/jquery.js" type=text/javascript></script> <script type="text/javascript"> $(function(){ $("#back").click(function () { window.location.href="${proPath}/student/main"; }) $("#update").click(function () { var name = $("#name").val(); var gender = $("#gender").val(); var age = $("#age").val(); if(name!=""&&gender!=""&&age!=""){ $.ajax({ type:'post', url:'${proPath}/student/update', data:$('#form').serialize(), dataType:'json', success:function (data) { console.log('...'); if(da