Spring 4 mvc restful 系列之二

接着上一篇 Spring 4 mvc restful 系列之一 ,本篇主要是在第一篇的基础上为其添加持久层框架。

用到的orm为mybatis,dbcp和mysql。

1、首先在pom.xml里添加以上的依赖包

<!-- 持久层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>
View Code

保存,等下载完成后,做下一步操作。

2、新建数据库配置文件jdbc.properties

##数据库连接池配置
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
View Code

3、新建model:Teacher类,并创建对应的service,serviceimpl和对应的controller,这一步骤跟第一篇里的student一样。

A:model 类

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;
    }
    

}
View Code

B:service 接口

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);
}
View Code

C:serviceimpl 接口实现

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);
    }

}
View Code

D:对应的controller,跟第一篇里的student差不多,注意访问路径的配置。

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);
        }
}
View Code

4、为teacher类添加持久层的mapper实现。

新建包:com.blue.datacenter.mapper.然后新建TeacherMapper.java接口,方法名字跟service接口一致。注意到findByPage方法中的注解传参方式。

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);
}
View Code

新建TeacherMapper.xml,这是mybaits的持久层实现执行的语句映射,注意参数的表示方式。

<?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>
View Code

同时,在config包里添加mybatis的实体接口映射资源配置文件mybatis-config.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>
        <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>
View Code

5、整合spring和mybatis,新建spring-mybatis.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" 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>
    
View Code

6、以上步骤完成后,即可运行看看结果。这里采用chrome的应用:postman 来检查结果。 

至此,添加mybatis持久层就完成了。

posted @ 2016-08-23 09:50  zcia  阅读(163)  评论(0编辑  收藏  举报