IMBAzxt / SpringMVCMyBatis

0 stars 0 forks source link

搭建历程 #1

Open IMBAzxt opened 6 years ago

IMBAzxt commented 6 years ago
IMBAzxt commented 6 years ago
IMBAzxt commented 6 years ago

mybatis配置,使用如下方式可以配置当个mapper

<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.zhengxt.dao.UserMapper" />
        <property name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

使用如下配置可以进行通配所有的mapper

<!-- 配置mybatisSqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <!--<property name="configLocation" value="classpath:mybatis/mybatis.xml"/>-->
        <!--<property name="mapperLocations" value="classpath*:com/itclj/magpie/**/*Mapper.xml"/>-->
    </bean>

    <!-- 配置SqlSessionTemplate -->
    <bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
        <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactory" />
    </bean>

    <!-- 配置mybatis mapper接口 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.zhengxt.dao"/>
        <property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/>
    </bean>

 <!-- 使用annotation注解方式配置事务 -->
    <tx:annotation-driven transaction-manager="transactionManager"/> 

UserMapper.class

public interface UserMapper {

    @Select("SELECT * FROM users WHERE id = #{userId}")
    Users getUser(@Param("userId") int userId);
}
IMBAzxt commented 6 years ago

mybatis的增删改查功能实现。 spring-mybatis.xml文件改动,增加configLocation属性。

<!-- 配置mybatisSqlSessionFactoryBean -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="configLocation" value="classpath:mybatis-config.xml"/>
    </bean>

增加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 type="com.zhengxt.Users" alias="Users" />
    </typeAliases>
    <mappers>
        <mapper resource="mapper/usersMapper.xml" />
    </mappers>
</configuration>

添加usersMapper.xml文件。

<?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">

<mapper namespace="com.zhengxt.dao.UserMapper">
    <resultMap type="Users" id="userMap">
        <id property="id" column="id" />
        <result property="username" column="username" />
        <result property="password" column="password" />
        <result property="passwordSalt" column="password_salt" />
    </resultMap>
    <!-- 增加一个用户;useGeneratedKeys="true"表示给主键设置自增长;keyProperty="id"表示将自增长后的Id赋值给实体类中的id字段。 -->
    <insert id="addUser" useGeneratedKeys="true" keyProperty="id" parameterType="Users">
        insert into users(username,password,password_salt) values(#{username},#{password},#{passwordSalt})
    </insert>
    <!-- 根据用户ID查找用户 -->
    <select id="findUserById" parameterType="int" resultMap="userMap">
        select * from users where id = #{id}
    </select>
    <!-- 更改用户信息 -->
    <update id="updateUser" parameterType="Users">
        update users set username=#{username},password=#{password},password_salt=#{passwordSalt} where id=#{id}
    </update>
    <!-- 删除用户信息 -->
    <delete id="deleteUser" parameterType="int">
        delete from Users where id = #{id}
    </delete>
    <!-- 查找所有用户 -->
    <select id="findAllUsers" resultType="Users">
        select * from users
    </select>
</mapper>

在UserMapper中添加对应的接口

public interface UserMapper {

    Users findUserById(int id);

    void addUser(Users users);

    void updateUser(Users users);

    void deleteUser(int id);

    Users[] findAllUsers();
}

测试

@Autowired
    UserMapper userMapper;
    static int userId = 0;

    @Test
    public void testAddUser() {
        Users users = new Users();
        users.setUsername("test001");
        users.setPassword("password");
        users.setPasswordSalt("salt");
        userMapper.addUser(users);
        userId = users.getId();
    }

    @Test
    public void testFindUser() {
        Assert.assertEquals("test001", userMapper.findUserById(userId).getUsername());
    }

    @Test
    public void testFindAllUser() {
        Users[] users = userMapper.findAllUsers();
        System.out.println(users.length);
    }

    @Test
    public void testUpdateUser() {
        Users users = userMapper.findUserById(userId);
        users.setPassword("passwd");
        userMapper.updateUser(users);
        Assert.assertEquals("passwd", userMapper.findUserById(userId).getPassword());
    }

    @Test
    public void testDeleteUser() {
        userMapper.deleteUser(userId);
        Assert.assertEquals(null, userMapper.findUserById(userId));
    }
zhengxuetao commented 6 years ago

springmvc集成

}


- 最后添加对应的jsp。
IMBAzxt commented 6 years ago

springmvc实现rest api,参考

IMBAzxt commented 6 years ago

controller层集成junit测试

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package com.zhengxt;

import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.zhengxt.dto.Response;
import com.zhengxt.entity.Users;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.web.context.WebApplicationContext;

import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.*;
import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import static org.springframework.test.web.servlet.setup.MockMvcBuilders.*;

/**
 *
 * @author ThinkPad
 */
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {
    "classpath:spring.xml",
    "classpath:springmvc-servlet.xml"})
@WebAppConfiguration
public class RestApiTest {
    @Autowired
    WebApplicationContext wac;

    MockMvc mockMvc;
    int id = 1001;
    String username = "张三";

    @Before
    public void setup() {
        this.mockMvc = webAppContextSetup(this.wac).build();
    }

    @Test
    public void testGet() throws Exception {

        String result = mockMvc.perform(
                get("/api/testGet/" + id) //请求地址
                 .header("Accept-Encoding", "UTF-8") //添加头部信息
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE) //返回的数据格式
                .param("username", username) //添加参数(可以添加多个)
        )
                .andDo(print()) //打印出请求信息
                .andExpect(status().isOk()) //判断返回是否成功
                .andExpect(jsonPath("$.data.id").value(id))
                .andExpect(jsonPath("$.data.username").value(username))
                .andReturn().getResponse().getContentAsString();   //将相应的数据转换为字符串
        // jackson字符串转对象
        ObjectMapper mapper = new ObjectMapper();

        Response<Users> resp = mapper.readValue(result, new TypeReference<Response<Users>>() {
        });
        Users users = resp.getData();
        Assert.assertEquals(String.valueOf(id), String.valueOf(users.getId()));
        Assert.assertEquals(username, users.getUsername());
    }

    @Test
    public void testPost() throws Exception {
        Users users = new Users();
        users.setId(id);
        users.setUsername(username);
        mockMvc.perform(
                post("/api/testPost")
                .flashAttr("users", users) //@ModelAttribute("users") Users users,这种情况需要使用flashAttr来进行传值
                //                .content(mapper.writeValueAsString(users))
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
        )
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data.id").value(id))
                .andExpect(jsonPath("$.data.username").value(username))
                .andReturn()
                .getResponse()
                .getContentAsString();

    }

    @Test
    public void testPut() throws Exception {
        Users users = new Users();
        users.setId(id);
        users.setUsername(username);
        mockMvc.perform(
                put("/api/testPut")
                .flashAttr("users", users) //@ModelAttribute("users") Users users,这种情况需要使用flashAttr来进行传值
                //                .content(mapper.writeValueAsString(users))
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
        )
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data.id").value(id))
                .andExpect(jsonPath("$.data.username").value(username))
                .andReturn()
                .getResponse()
                .getContentAsString();

    }

    @Test
    public void testDelete() throws Exception {
        mockMvc.perform(
                delete("/api/testDelete/" + id)
                .contentType(MediaType.APPLICATION_JSON_UTF8_VALUE)
        )
                .andDo(print())
                .andExpect(status().isOk())
                .andExpect(jsonPath("$.data").value(id))
                .andReturn()
                .getResponse()
                .getContentAsString();

    }
}

添加依赖包

        <dependency>
            <groupId>com.jayway.jsonpath</groupId>
            <artifactId>json-path</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
IMBAzxt commented 6 years ago

springmv rest api获取request、response的方法

IMBAzxt commented 6 years ago

踩坑一:多端跨域问题,解决方法https://github.com/IMBAzxt/SpringMVCMyBatis/issues/4 踩坑二:使用@ModelAttribute注解接收不到请求过来的数据,错误理解@RequestBody和@ModelAttribute的区别。

@RequestBody和@ModelAttribute的区别

https://blog.csdn.net/lzdujing1/article/details/52325143

IMBAzxt commented 6 years ago

通过上面的issue,本篇全部使用@requestbody来接收,代码做相应的修改。

IMBAzxt commented 6 years ago

查看这篇文章后,决定使用druid替代c3p0。

IMBAzxt commented 6 years ago

集成redis,使用redis做二级缓存。参考

Redis settings

redis.host=127.0.0.1 redis.port=6379 redis.pass=

redis.maxIdle=300 redis.maxActive=600 redis.maxWait=1000 redis.testOnBorrow=true


- spring-redis配置文件

<?xml version="1.0" encoding="GBK"?> <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:tx="http://www.springframework.org/schema/tx"

   xsi:schemaLocation="http://www.springframework.org/schema/beans
                        http://www.springframework.org/schema/beans/spring-beans.xsd
                        http://www.springframework.org/schema/context
                        http://www.springframework.org/schema/context/spring-context.xsd
                        http://www.springframework.org/schema/tx
                        http://www.springframework.org/schema/tx/spring-tx.xsd

">

<context:property-placeholder location="classpath:jdbc.properties" />

<!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxIdle" value="${redis.maxIdle}" />
    <property name="maxTotal" value="${redis.maxActive}" />
    <property name="maxWaitMillis" value="${redis.maxWait}" />
    <property name="testOnBorrow" value="${redis.testOnBorrow}" />  
</bean>

<!-- 连接池配置,类似数据库连接池 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
    <property name="hostName" value="${redis.host}"></property>
    <property name="port" value="${redis.port}"></property>
    <property name="password" value="${redis.pass}"></property>
    <property name="poolConfig"  ref="poolConfig"></property>
</bean>
<!-- 使用中间类解决RedisCache.jedisConnectionFactory的静态注入,从而使MyBatis实现第三方缓存 -->
<bean id="redisCacheTransfer" class="com.zhengxt.dao.cache.RedisCacheTransfer">
    <property name="jedisConnectionFactory" ref="jedisConnectionFactory" />
</bean> 

- RedisDAO

package com.zhengxt.dao.cache;

import java.util.concurrent.locks.ReadWriteLock; import java.util.concurrent.locks.ReentrantReadWriteLock; import org.apache.ibatis.cache.Cache; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.data.redis.connection.RedisConnection; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer; import org.springframework.data.redis.serializer.RedisSerializer; import redis.clients.jedis.exceptions.JedisConnectionException;

/*