文章目录
  1. 1. 依赖包
  2. 2. 配置文件准备
  3. 3. Mybatis自定义配置文件实现
  4. 4. Mybatis代码生成
  5. 5. 项目测试

MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。随着2013年开源以来,目前业内使用的也越来越多。下面通过一个实例来说明一下怎么去使用它,怎么体现出它的优势所在:

由于我是基于Spring Boot的来说明mybatis的使用,所以首先我们需要配置好mybatis。

依赖包

<!--依赖-->
<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>9.4.1208</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis</artifactId>
    <version>3.4.1</version>
</dependency>
<dependency>
    <groupId>org.mybatis</groupId>
    <artifactId>mybatis-spring</artifactId>
    <version>1.3.0</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-jdbc</artifactId>
    <version>4.2.6.RELEASE</version>
</dependency>
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid</artifactId>
    <version>1.0.20</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>test</scope>
    <version>1.4.192</version>
</dependency>

配置文件准备

在 src/main/resources/下面添加如下properties文件:

  • application.properties

    spring.profiles.active=@profiles.active@
    jdbc.url=${jdbc.url}
    jdbc.username= ${jdbc.username}
    jdbc.password= ${jdbc.password}
    jdbc.driver=${jdbc.driver}
    jdbc.poolMaximumActiveConnections=${jdbc.poolMaximumActiveConnections}
    jdbc.poolMaximumIdleConnections=${jdbc.poolMaximumIdleConnections}
    
  • application-develop.properties(测试用)

    jdbc.url=jdbc:h2:mem:demo-db;MODE=PostgreSQL;INIT=RUNSCRIPT FROM './src/test/resources/sql/demo.sql'
    jdbc.username= sa
    jdbc.password= sa
    jdbc.driver= org.h2.Driver
    jdbc.poolMaximumActiveConnections=20
    jdbc.poolMaximumIdleConnections=0
    
  • application-production.properties(生产用)

    jdbc.url=jdbc:postgresql://192.168.100.117:5432/db_demo?characterEncoding#UTF-8
    jdbc.username= postgres
    jdbc.password= postgres
    jdbc.driver=org.postgresql.Driver
    jdbc.poolMaximumActiveConnections=30
    jdbc.poolMaximumIdleConnections=0
    

Mybatis自定义配置文件实现

在src/main/java/com.jmust.service.demo下创建”MybatisConfiguration.java”文件

import com.alibaba.druid.pool.DruidDataSource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import javax.annotation.PostConstruct;
import javax.sql.DataSource;

@Configuration
@MapperScan(basePackages = {"com.jmust.service.demo.resource.mapper"})
public class MybatisConfiguration {

    @Autowired
    private Environment env;

    @Autowired
    private DataSource pooledDataSource;
    private static Log logger = LogFactory.getLog(MybatisConfiguration.class);

    @PostConstruct
    @Bean
    public DataSource dataSource() {
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.setPassword(env.getProperty("jdbc.password"));
        druidDataSource.setUsername(env.getProperty("jdbc.username"));
        druidDataSource.setUrl(env.getProperty("jdbc.url"));
        druidDataSource.setDriverClassName(env.getProperty("jdbc.driver"));
        druidDataSource.setMaxActive(Integer.parseInt(env.getProperty("jdbc.poolMaximumActiveConnections")));
        return druidDataSource;
    }

    @Bean
    public SqlSessionFactory sqlSessionFactory() {
        try {
            SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
            sessionFactory.setDataSource(pooledDataSource);
            sessionFactory.setMapperLocations(new PathMatchingResourcePatternResolver()
                    .getResources("classpath:mapping/*.xml"));

            return sessionFactory.getObject();
        } catch (Exception e) {
            logger.error("not install sessionFactory", e);
            throw new RuntimeException("not install sessionFactory");
        }
    }

    @Bean
    public DataSourceTransactionManager transaction() {
        return new DataSourceTransactionManager(pooledDataSource);
    }
}

Mybatis代码生成

  • 1、生成xxxMapper.java接口文件(src/main/com.jmust.service.demo.resource.mapper),该文件主要作用是映射到xxxMapper.xml文件中的操作标签的(比如insert对应xml文件中的
  • import com.jmust.service.demo.resource.entity.Demo;
    import org.springframework.stereotype.Repository;
    import java.util.Date;
    
    @Repository
    public interface DemoMapper {
        Demo select(long customerId);   
        boolean insert(Demo demoPojo);  
        boolean update(Demo demoPojo);
    }
    
  • 2、生成xxxMapper.xml文件(src/main/resources/mapping/),该文件的主要作用就是操作数据(插入、更改、删除……)语句的维护及管理

    <?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.jmust.service.demo.resource.mapper.DemoMapper">
    
    <resultMap id="demoPojo" type="com.jmust.service.demo.resource.entity.Demo">
        <result column="customer_id" property="customerId"/>
        <result column="total_times" property="totalTimes"/>
        <result column="continue_days" property="continueDays"/>
        <result column="last_time" property="lastTime"/>
    </resultMap>
    
    <select id="select" resultMap="demoPojo" parameterType="long">
        SELECT * FROM demo
        WHERE customer_id = #{customerId}
    </select>

    <insert id="insert" parameterType="com.jmust.service.demo.resource.entity.Demo">
        insert into demo(customer_id,total_times,continue_days,last_time)
        values
        (#{customerId},1,#{continueDays},#{lastTime},#{awardType})
    </insert>

    <update id="update" parameterType="com.jmust.service.demo.resource.entity.Demo">
        update demo
        <set>
            <if test="continueDays != null">
                continue_days = #{continueDays},
            </if>
            <if test="awardType != null">
                award_type = #{awardType},
            </if>
            <if test="lastTime != null">
                last_time = #{lastTime}
            </if>
        </set>
        where customer_id = #{customerId}
    </update>

</mapper>
  • 3、自定义接口类(DemoResources)src/main/com.jmust.service.demo.resource,定义操作契约

    import com.jmust.service.demo.resource.entity.Demo;
    import java.util.Date;
    
    public interface DemoResources {
         Demo queryDemo(long customerId);
         void update(Demo demoinPojo);
         void insert(Demo demoPojo);
    }
    
  • 4、实现接口类,业务逻辑包含在内(src/main/com.jmust.service.demo.resource)

    import com.jmust.contract.ExtendedStatusRuntimeException;
    import com.jmust.contract.ResourceUnavailableException;
    import com.jmust.service.demo.DemoStatus;
    import com.jmust.service.demo.resource.entity.Demo;
    import com.jmust.service.demo.resource.mapper.DemoMapper;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.dao.DuplicateKeyException;
    import org.springframework.stereotype.Component;
    
    import java.util.Date;
    
    @Component
    public class DemoResourcesImpl implements DemoResources{
        @Autowired
        private DemoMapper demoMapper;
        @Override
        public Demo queryDemo(long customerId) {
            try {
                return demoMapper.select(customerId);
            }catch (Exception e){
                throw new ResourceUnavailableException("Database fail select Demo",e);
            }
        }
    
        @Override
        public void update(Demo demoPojo) {
            try {
                if(!demoMapper.update(demoPojo)){
                    throw new ExtendedStatusRuntimeException(101, "Demo process  fail  ,because Demo   update fail");
                }
            }catch (Exception e){
                throw new ResourceUnavailableException("Database fail update demoPojo",e);
            }
        }
    
        @Override
        public void insert(Demo demo) {
            try {
                if(!demoMapper.insert(demo)){
                    throw new ExtendedStatusRuntimeException(102, "demo process  fail  ,because demo insert  fail");
                }
            }catch (DuplicateKeyException e){
                if(!DemoMapper.update(demo)){
                    throw new ExtendedStatusRuntimeException(102, "demo process  fail  " +
                            ",because demo update  fail");
                }
            }catch (Exception e){
                throw new ResourceUnavailableException("Database fail insert demoPojo ",e);
            }
        }
    
    }
    

项目测试

import com.jmust.server.profile.ProfileDevelop;
import com.jmust.server.profile.ProfileTest;
import com.jmust.service.demo.DemoConstants;
import com.jmust.service.demo.MybatisConfiguration;
import com.jmust.service.demo.resource.entity.Demo;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.testng.AbstractTestNGSpringContextTests;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;

import java.sql.Timestamp;
import java.util.Date;
import java.util.List;

import static org.assertj.core.api.Assertions.assertThat;

@ProfileTest
@ProfileDevelop
@ContextConfiguration(classes = {MybatisConfiguration.class, DemoResourcesImpl.class})
@TestPropertySource(value = "classpath:application.properties")
public class DemoPojoResourcesTest extends AbstractTestNGSpringContextTests {
    private Long concurrent = System.currentTimeMillis();
    private int customerId = 11;

    @Autowired
    private DemoResources cm;

    @BeforeClass
    public void insert() {
        Demo demoPojo = new Demo();
        demoPojo.setCustomerId(customerId);
        demoPojo.setCreateTime(new Timestamp(concurrent));
        demoPojo.setAwardTypeEnum("");
        demoPojo.setTotalTimes(0);
        cm.insert(demoPojo);
    }

    @Test
    public void queryDemo() {
        Demo demoPojo = cm.queryDemo(customerId);
        assertThat(demoPojo.getCustomerId()).isEqualTo(customerId);
        assertThat(demoPojo.getCreateTime()).isEqualTo(new Timestamp(concurrent));
        assertThat(demoPojo.getTotalTimes()).isEqualTo(1);
    }
}
文章目录
  1. 1. 依赖包
  2. 2. 配置文件准备
  3. 3. Mybatis自定义配置文件实现
  4. 4. Mybatis代码生成
  5. 5. 项目测试