[SpringMVC]從頭開始-整合Mybatis CRUD 範例
開發環境:Intellij IDEA 13.1.4 + MySQL Workbench 6.1
FrameWork:SpringMVC 3.2.11.RELEASE + Mybatis 3.2.3
整個範例來源自:
Building Java Web Application Using MyBatis With Spring
需求的 pom.xml dependency 有:
<properties>
<spring.version>3.2.11.RELEASE</spring.version>
<log4j.version>1.2.17</log4j.version>
<jstl.version>1.2</jstl.version>
<mysql-connector-java.version>5.1.32</mysql-connector-java.version>
<servlet-api.version>2.5</servlet-api.version>
<mybatis-spring.version>1.2.1</mybatis-spring.version>
<mybatis.verison>3.2.3</mybatis.verison>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<!-- Spring dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- Spring Transactional -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- servlet -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet-api.version}</version>
<scope>provided</scope>
</dependency>
<!-- jstl -->
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<!-- MyBatis integration -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis-spring.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.verison}</version>
</dependency>
<!-- mysql connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql-connector-java.version}</version>
</dependency>
</dependencies>
檔案架構為:
首先先使用 MySQL Workbench 建立一張 Tabale
CREATE TABLE `student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`dateOfBirth` datetime NOT NULL,
`emailAddress` varchar(255) NOT NULL,
`firstName` varchar(255) NOT NULL,
`lastName` varchar(255) NOT NULL,
`password` varchar(8) NOT NULL,
`userName` varchar(20) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=43 DEFAULT CHARSET=utf8;
用來儲存我們要存放的學生資料
接著先來建立 相關的 Model
Student.java 及 StudentLogin.java (相關檔案可在文末Demo程式中取得)
接著建立 Mybatis 所需要的 Mapper 檔案,在這裡我們採用 Annotation
的方式來設定,不採用 XML mapper 對應的方式。也就是將SQL 語法
直接設定在 java 類別中。
public interface StudentMapper {
@Insert("INSERT INTO student(userName, password, firstName,"
+ "lastName, dateOfBirth, emailAddress) VALUES"
+ "(#{userName},#{password}, #{firstName}, #{lastName},"
+ "#{dateOfBirth}, #{emailAddress})")
@Options(useGeneratedKeys=true, keyProperty="id", flushCache=true, keyColumn="id")
public void insertStudent(Student student);
@Select("SELECT USERNAME as userName, PASSWORD as password, "
+ "FIRSTNAME as firstName, LASTNAME as lastName, "
+ "DATEOFBIRTH as dateOfBirth, EMAILADDRESS as emailAddress "
+ "FROM student WHERE userName = #{userName}")
public Student getStudentByUserName(String userName);
}
這裡宣告了兩個方法分別是 insertStudent 及 getStudentByUserName
用來寫入學生資料及取得學生資料。
接著設計一個服務類別,用來提供關於 StudentMapper 的相關服務。
分別是 StudentService 及他的實踐類別 StudentServiceImpl
public interface StudentService {
void insertStudent(Student student);
boolean getStudentByLogin(String userName, String password);
boolean getStudentByUserName(String userName);
}
@Service("studentService")
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Transactional
public void insertStudent(Student student) {
studentMapper.insertStudent(student);
}
public boolean getStudentByLogin(String userName, String password) {
Student student = studentMapper.getStudentByUserName(userName);
if(student != null && student.getPassword().equals(password)) {
return true;
}
return false;
}
public boolean getStudentByUserName(String userName) {
Student student = studentMapper.getStudentByUserName(userName);
if(student != null) {
return true;
}
return false;
}
}
在服務的實現類別中,我們採用 @Autowired 來注入 StudentMapper,
並使用 @Transactional 來管理整個 存取的 Transaction
接著我們建立一個 Controller 來管理整個程序的動向。
@Controller
@SessionAttributes("student")
public class StudentController {
@Autowired
private StudentService studentService;
@RequestMapping(value = "/StudentEnrollmentWithMyBatis", method = RequestMethod.GET)
public String goBack(){
return "index";
}
@RequestMapping(value="/signup", method= RequestMethod.GET)
public String signup(Model model) {
Student student = new Student();
model.addAttribute("student", student);
return "signup";
}
@RequestMapping(value="/signup", method=RequestMethod.POST)
public String signup(@ModelAttribute("student") Student student, Model model) {
if(studentService.getStudentByUserName(student.getUserName())) {
model.addAttribute("message", "User Name exists. Try another user name");
return "signup";
} else {
studentService.insertStudent(student);
model.addAttribute("message", "Saved student details");
return "redirect:login.html";
}
}
@RequestMapping(value="/login", method=RequestMethod.GET)
public String login(Model model) {
StudentLogin studentLogin = new StudentLogin();
model.addAttribute("studentLogin", studentLogin);
return "login";
}
@RequestMapping(value="/login", method=RequestMethod.POST)
public String login(@ModelAttribute("studentLogin") StudentLogin studentLogin) {
boolean found = studentService.getStudentByLogin(studentLogin.getUserName(), studentLogin.getPassword());
if (found) {
return "success";
} else {
return "failure";
}
}
}
這裡的 @RequestMapping 會對應到我們網頁上資料的流動,
比如說 @RequestMapping(value="/login", method=RequestMethod.POST)
由於我們會設定 Servlet 對應到 *.html,所以當Server 接收到的是
POST 方法所傳遞過來的 login.html 時,會經由我們設定的 controller,
導出一個 success or failure 的字串,再經由 viewResolver,解析出
success.jsp or failure.jsp 的 view 來,並將相關結果呈現給使用者。
這樣講可能有點空洞,我們來看看 設定檔就可以比較容易理解。
首先是 spring configuration 檔案
<!-- 開起 SpringMVC 的 annotation -->
<mvc:annotation-driven />
<!-- 自動掃描package中的檔案,並 Autowired -->
<context:component-scan base-package="test" />
<!-- 設定 properties 的路徑 -->
<context:property-placeholder location="classpath*:config.properties" />
<!-- 設定dataSource -->
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}" />
<!-- 設定 transactionManager 管理哪個 dataSource -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"
p:dataSource-ref="dataSource" />
<!-- 指定 Annotation Transaction 所使用的 transaction-manager -->
<tx:annotation-driven transaction-manager="transactionManager" />
<!-- 建立 Mybatis 所使用的 SessionFactory,定指定 dataSource 及 typeAliasesPackage
及 mapperLocations(當使用 xml 來設定 mpaaer 檔時,檔案所在目錄-->
<bean id="sqlSessionFactiory" class="org.mybatis.spring.SqlSessionFactoryBean"
p:dataSource-ref="dataSource"
p:typeAliasesPackage="test.models"
p:mapperLocations="classpath*:mappers/*.xml" />
<!-- 透過 SqlSessionTemplate 建立 一個 Mybatis 用的 sqlSession -->
<bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactiory" />
</bean>
<!-- ref
SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType)
Constructs a Spring managed SqlSession with the SqlSessionFactory provided as an argument and the given ExecutorType ExecutorType cannot be changed once the SqlSessionTemplate is constructed.
-->
<!-- 讓 Mybatis 可以去掃描指定 package 的檔案,並完成相關的 Annotation 的設置 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"
p:basePackage="test.mappers" />
<!-- 指定 ViewResolver -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"
p:prefix="/WEB-INF/jsp/"
p:suffix=".jsp" />
經由這些設定之後,搭配我們在 WEB-INF/jsp 中建立的相關 jsp
檔案,整個程式在部屬到 Tomcat 後,即可正常執行
執行畫面:
demo程式(右鍵另開視窗下載) ==> http://goo.gl/jYraBi
開發流程:
Table 設計 ⇒ 畫面設計 ⇒ 程式撰寫 ⇒ 驗證
原文網址 ==> http://kuoshenghsu.blogspot.tw/2014/09/springmvc-mybatis-crud.html