Spring 4 mvc restful 系列之二
接着上一篇 Spring 4 mvc restful 系列之一 ,本篇主要是在第一篇的基础上为其添加持久层框架。
用到的orm为mybatis,dbcp和mysql。
1、首先在pom.xml里添加以上的依赖包
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<!-- 持久层mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.0</version> </dependency> <!-- mysql连接驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.38</version> </dependency> <!-- 连接池驱动 --> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-jdbc</artifactId> <version>${spring.version}</version> </dependency> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis-spring</artifactId> <version>1.3.0</version> </dependency>
保存,等下载完成后,做下一步操作。
2、新建数据库配置文件jdbc.properties
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
##数据库连接池配置 driverClassName=com.mysql.jdbc.Driver url=jdbc:mysql://192.168.123.128:3306/test?useUnicode=true&characterEncoding=UTF-8 jdbc.username=root jdbc.password=root initialSize=1 maxActive=20 maxIdle=10 minIdle=1 maxWait=60000
3、新建model:Teacher类,并创建对应的service,serviceimpl和对应的controller,这一步骤跟第一篇里的student一样。
A:model 类
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.blue.datacenter.model; import java.io.Serializable; public class Teacher implements Serializable { private static final long serialVersionUID = -9182779830441596398L; private long id; private String name; private int age; private String professional; public long getId() { return id; } public void setId(long id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getProfessional() { return professional; } public void setProfessional(String professional) { this.professional = professional; } }
B:service 接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.blue.datacenter.service; import java.util.List; import com.blue.datacenter.model.Teacher; public interface TeacherService { Teacher findById(long id); Teacher findByName(String name); void saveTeacher(Teacher teacher); void updateTeacher(Teacher teacher); void deleteTeacherById(long id); List<Teacher> findByPage(int pageNum,int size); public boolean isTeacherExist(Teacher teacher); }
C:serviceimpl 接口实现
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.blue.datacenter.service.impl; import java.util.List; import javax.annotation.Resource; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import com.blue.datacenter.mapper.TeacherMapper; import com.blue.datacenter.model.Teacher; import com.blue.datacenter.service.TeacherService; @Service @Transactional public class TeacherServiceImpl implements TeacherService { @Resource private TeacherMapper mapper; @Override public Teacher findById(long id) { // TODO Auto-generated method stub return mapper.findById(id); } @Override public void saveTeacher(Teacher teacher) { // TODO Auto-generated method stub mapper.saveTeacher(teacher); } @Override public void updateTeacher(Teacher teacher) { // TODO Auto-generated method stub mapper.updateTeacher(teacher); } @Override public void deleteTeacherById(long id) { // TODO Auto-generated method stub mapper.deleteTeacherById(id); } @Override public List<Teacher> findByPage(int pageNum, int size) { // TODO Auto-generated method stub if(pageNum==0){ pageNum=1; } if(size==0){ size=10; } int start=(pageNum-1)*size; return mapper.findByPage(start, size); } @Override public boolean isTeacherExist(Teacher teacher) { // TODO Auto-generated method stub return mapper.isTeacherExist(teacher); } @Override public Teacher findByName(String name) { // TODO Auto-generated method stub return mapper.findByName(name); } }
D:对应的controller,跟第一篇里的student差不多,注意访问路径的配置。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.blue.datacenter.controller; import java.util.List; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RequestMethod; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.util.UriComponentsBuilder; import com.blue.datacenter.model.Teacher; import com.blue.datacenter.service.TeacherService; @RestController @RequestMapping(value="/api/") public class TeacherController { @Autowired private TeacherService teacherService; //----查找所有teachers------------------- @RequestMapping(value = "/teacher", method = RequestMethod.GET) public ResponseEntity<List<Teacher>> listAllTeachers() { List<Teacher> Teachers = teacherService.findByPage(0, 0); if(Teachers.isEmpty()){ return new ResponseEntity<List<Teacher>>(HttpStatus.NO_CONTENT);//You many decide to return HttpStatus.NOT_FOUND } return new ResponseEntity<List<Teacher>>(Teachers, HttpStatus.OK); } //-------------------按id查找teacher------------------------ //@CrossOrigin(origins = "*", maxAge = 3600) @RequestMapping(value = "/teacher/{id}", method = RequestMethod.GET) public ResponseEntity<Teacher> getTeacher(@PathVariable("id") long id){ Teacher teacher = teacherService.findById(id); if(teacher==null){ return new ResponseEntity<Teacher>(HttpStatus.NOT_FOUND); } return new ResponseEntity<Teacher>(teacher, HttpStatus.OK); } //------------------新增teacher--------------------------- @RequestMapping(value = "/teacher/", method = RequestMethod.POST) public ResponseEntity<Void> createTeacher(@RequestBody Teacher teacher, UriComponentsBuilder ucBuilder) { System.out.println("Creating Teacher " + teacher.getName()); if (teacherService.isTeacherExist(teacher)) { System.out.println("A Teacher with name " + teacher.getName() + " already exist"); return new ResponseEntity<Void>(HttpStatus.CONFLICT); } teacherService.saveTeacher(teacher); HttpHeaders headers = new HttpHeaders(); headers.setLocation(ucBuilder.path("/teacher/{id}").buildAndExpand(teacher.getId()).toUri()); return new ResponseEntity<Void>(headers, HttpStatus.CREATED); } //-------------------更新teacher -------------------------------------------------------- @RequestMapping(value = "/teacher/{id}", method = RequestMethod.PUT) public ResponseEntity<Teacher> updateTeacher(@PathVariable("id") long id, @RequestBody Teacher teacher) { System.out.println("Updating Teacher " + id); Teacher currentTeacher = teacherService.findById(id); if (currentTeacher==null) { System.out.println("Teacher with id " + id + " not found"); return new ResponseEntity<Teacher>(HttpStatus.NOT_FOUND); } currentTeacher.setName(teacher.getName()); currentTeacher.setAge(teacher.getAge()); currentTeacher.setProfessional(teacher.getProfessional()); teacherService.updateTeacher(currentTeacher); return new ResponseEntity<Teacher>(currentTeacher, HttpStatus.OK); } //------------------- 删除teacher -------------------------------------------------------- @RequestMapping(value = "/teacher/{id}", method = RequestMethod.DELETE) public ResponseEntity<Teacher> deleteTeacher(@PathVariable("id") long id) { System.out.println("Fetching & Deleting Teacher with id " + id); Teacher teacher = teacherService.findById(id); if (teacher == null) { System.out.println("Unable to delete. Teacher with id " + id + " not found"); return new ResponseEntity<Teacher>(HttpStatus.NOT_FOUND); } teacherService.deleteTeacherById(id); return new ResponseEntity<Teacher>(HttpStatus.NO_CONTENT); } }
4、为teacher类添加持久层的mapper实现。
新建包:com.blue.datacenter.mapper.然后新建TeacherMapper.java接口,方法名字跟service接口一致。注意到findByPage方法中的注解传参方式。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package com.blue.datacenter.mapper; import java.util.List; import org.apache.ibatis.annotations.Param; import com.blue.datacenter.model.Teacher; public interface TeacherMapper { Teacher findById(long id); Teacher findByName(String name); void saveTeacher(Teacher teacher); void updateTeacher(Teacher teacher); void deleteTeacherById(long id); List<Teacher> findByPage(@Param("start")int pageNum,@Param("size")int size); public Boolean isTeacherExist(Teacher teacher); }
新建TeacherMapper.xml,这是mybaits的持久层实现执行的语句映射,注意参数的表示方式。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- namespace:必须与对应的接口全类名一致 id:必须与对应接口的某个对应的方法名一致 --> <mapper namespace="com.blue.datacenter.mapper.TeacherMapper"> <insert id="saveTeacher" parameterType="Teacher"> insert into teachers(name,age,professional) values(#{name},#{age},#{professional}) </insert> <update id="updateTeacher" parameterType="Teacher"> update teachers set name=#{name},age=#{age},professional=#{professional} where id=#{id} </update> <delete id="deleteTeacherById" parameterType="long"> delete from teachers where id=#{id} </delete> <!-- mybsits_config中配置的alias类别名,也可直接配置resultType为类路劲 --> <select id="findById" parameterType="long" resultType="Teacher"> select id,name, age,professional from teachers where id=#{id} </select> <select id="findByName" parameterType="String" resultType="Teacher"> select id,name, age,professional from teachers where name=#{name} </select> <select id="findByPage" resultType="Teacher" > select id,name, age,professional from teachers where id >=(select id from teachers limit #{start},1) limit #{size}; </select> <select id="isTeacherExist" parameterType="Teacher" resultType="boolean"> select count(id) from teachers where name=#{name} </select> </mapper>
同时,在config包里添加mybatis的实体接口映射资源配置文件mybatis-config.xml,这是整个持久化的入口。
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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> <typeAlias alias="Teacher" type="com.blue.datacenter.model.Teacher" /> </typeAliases> <!-- 实体接口映射资源 --> <!-- 说明:如果xxMapper.xml配置文件放在和xxMapper.java统一目录下,mappers也可以省略,因为org.mybatis.spring.mapper.MapperFactoryBean默认会去查找与xxMapper.java相同目录和名称的xxMapper.xml --> <mappers> <mapper resource="com/blue/datacenter/mapper/TeacherMapper.xml" /> </mappers> </configuration>
5、整合spring和mybatis,新建spring-mybatis.xml文件,注意配置文件的位置,详细内容如下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
<?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:tx="http://www.springframework.org/schema/tx" xmlns:util="http://www.springframework.org/schema/util" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.2.xsd http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.2.xsd"> <!-- 1. 数据源 : DriverManagerDataSource dbcp连接池 --> <!-- 分解配置 jdbc.properites --> <context:property-placeholder location="classpath*:config/*.properties" /> <!-- 数据库连接池配置 --> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="${driverClassName}" /> <property name="url" value="${url}" /> <property name="username" value="${jdbc.username}" /> <property name="password" value="${jdbc.password}" /> <!-- 初始化连接大小 --> <property name="initialSize" value="${initialSize}"></property> <!-- 连接池最大数量 --> <property name="maxActive" value="${maxActive}"></property> <!-- 连接池最大空闲 --> <property name="maxIdle" value="${maxIdle}"></property> <!-- 连接池最小空闲 --> <property name="minIdle" value="${minIdle}"></property> <!-- 获取连接最大等待时间 --> <property name="maxWait" value="${maxWait}"></property> <!-- 连接被泄露时是否打印 --> <property name="logAbandoned" value="true"/> <!--removeAbandoned: 是否自动回收超时连接--> <property name="removeAbandoned" value="true"/> <!--removeAbandonedTimeout: 超时时间(以秒数为单位)--> <property name="removeAbandonedTimeout" value="10"/> <!-- 在空闲连接回收器线程运行期间休眠的时间值,以毫秒为单位. --> <property name="timeBetweenEvictionRunsMillis" value="10000"/> <!-- 在每次空闲连接回收器线程(如果有)运行时检查的连接数量 --> <property name="numTestsPerEvictionRun" value="5"/> <!-- 1000 * 60 * 30 连接在池中保持空闲而不被空闲连接回收器线程--> <property name="minEvictableIdleTimeMillis" value="10000"/> <property name="validationQuery" value="SELECT NOW() FROM DUAL"/> </bean> <!-- 2. mybatis的SqlSession的工厂: SqlSessionFactoryBean dataSource:引用数据源 MyBatis定义数据源,同意加载配置 --> <bean id="mySqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"></property> <property name="configLocation" value="classpath:config/mybatis-config.xml" /> </bean> <!-- 3. mybatis自动扫描加载Sql映射文件/接口 : MapperScannerConfigurer sqlSessionFactory basePackage:指定sql映射文件/接口所在的包(自动扫描) --> <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.blue.datacenter.mapper"></property> <property name="sqlSessionFactoryBeanName" value="mySqlSessionFactory"></property> </bean> <!-- 4. 事务管理 : DataSourceTransactionManager dataSource:引用上面定义的数据源 --> <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"></property> </bean> <!-- 5. 使用声明式事务 transaction-manager:引用上面定义的事务管理器 --> <tx:annotation-driven transaction-manager="txManager" /> </beans>
6、以上步骤完成后,即可运行看看结果。这里采用chrome的应用:postman 来检查结果。
至此,添加mybatis持久层就完成了。
自由交流~@blue