Spring Boot 技术探索

Spring Boot makes it easy to create stand-alone, production-grade Spring based Applications that you can "just run".

15、Spring Boot同时使用Spring Data JPA和MyBatis

平台环境:

名称

版本号

Mac OS X

10.14.5

JDK

1.8.0_201

Apache Maven

3.6.0

IntelliJ IDEA

2019.1 (Ultimate Edition)

Spring Boot

2.1.6.RELEASE

MySQL

8.0.13 库名叫test1

 

  Spring Data JPA它提供了极简的方式操作数据库,但有时候仍然需要MyBatis的灵活性来执行自由度极高的手工编写的SQL。这里通过在Spring Data JPA中配置MyBatis,来达到两者共存的方式操作数据库。

 

一、Spring Data JPA的配置

1、pom.xml中配置好依赖项。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.6.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.example</groupId>
    <artifactId>demo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>demo</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.0</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

 

2、application.properties中写好配置项

# Spring Config
spring.datasource.driverClassName = com.mysql.cj.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/test1?serverTimezone=Asia/Shanghai&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 12345678

# Spring Data JPA Config
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
spring.jpa.show-sql=true
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl

# MyBatis Config
logging.level.com.example.MyBatisDemo.mapper=debug
#开启驼峰命名转换
mybatis.configuration.map-underscore-to-camel-case=true
#开启null值返回
mybatis.configuration.callSettersOnNulls=true

 

3、建立Spring Data JPA的Entity类

package com.example.demo.dao.entity;

import java.io.Serializable;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class User implements Serializable
{
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(nullable = false, unique = true)
    private String userName;

    @Column(nullable = false)
    private String passWord;

    @Column
    private Date regTime;

    @Column
    private String remark;

    @Column
    private Integer sex;

    public Long getId()
    {
        return id;
    }

    public void setId(Long id)
    {
        this.id = id;
    }

    public String getUserName()
    {
        return userName;
    }

    public void setUserName(String userName)
    {
        this.userName = userName;
    }

    public String getPassWord()
    {
        return passWord;
    }

    public void setPassWord(String passWord)
    {
        this.passWord = passWord;
    }

    public Date getRegTime()
    {
        return regTime;
    }

    public void setRegTime(Date regTime)
    {
        this.regTime = regTime;
    }

    public String getRemark()
    {
        return remark;
    }

    public void setRemark(String remark)
    {
        this.remark = remark;
    }

    public Integer isSex()
    {
        return sex;
    }

    public void setSex(Integer sex)
    {
        this.sex = sex;
    }
}

 

4、建立Spring Data JPA的Repository类

package com.example.demo.dao;

import com.example.demo.dao.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long>
{
    // 自定义查询
    User findByUserName(String userName);
}

 

到这里,Spring Data JPA的配置就完成了。接下来开始配置MyBatis。

 

 

二、MyBatis的配置

1、pom.xml和application.properties的配置在之前的JPA部分已经写过了。这里直接开始自定义Mapper类

package com.example.demo.dao.MyBatis;

import java.util.LinkedHashMap;
import java.util.List;

import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

public interface MyBatisMapper
{
    // 执行任意SELECT语句(利用LinkedHashMap接收返回的结果)
    @Select("${sql}")
    List<LinkedHashMap<String, Object>> myBatisSelectSQL(@Param("sql") String sql);

    // 执行任意INSERT、UPDATE、DELETE语句
    @Update("${sql}")
    int myBatisUpdateSQL(@Param("sql") String sql);
}
  • 这里写了两个方法,用于执行任意SQL语句。
  • 由于这里MyBatis的引入主要用于对JPA中不方便的操作进行补充,因此省略掉了定义实体类,直接使用LinkedHashMap接收返回的结果。如果你愿意,也可以自定义实体类,并在这里接收返回结果。

 

2、新建配置类,加入对自定义Mapper的扫描注解

package com.example.demo.config;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@MapperScan("com.example.demo.dao.MyBatis")// 这个也可以直接写到Spring Boot的启动类上
public class AppConfig
{
}

 

到这里,MyBatis的配置就完成了。接下来开始把MyBatis配置到JPA中。

 

 

三、在JPA中加入MyBatis的功能(合并)

1、自定义CustomizedRepository

package com.example.demo.dao;

import java.util.LinkedHashMap;
import java.util.List;

import org.apache.ibatis.annotations.Param;

public interface CustomizedRepository
{
    List<LinkedHashMap<String, Object>> myBatisSelectSQL(@Param("sql") String sql);

    int myBatisUpdateSQL(@Param("sql") String sql);
}

 

2、自定义CustomizedRepositoryImpl,实现CustomizedRepository接口

package com.example.demo.dao;

import com.example.demo.dao.MyBatis.MyBatisMapper;

import javax.annotation.Resource;
import java.util.LinkedHashMap;
import java.util.List;

// 在这个实现类里用你自己喜欢的DAO框架,比如说MyBatis, JdbcTemplate
public class CustomizedRepositoryImpl implements CustomizedRepository
{
    @Resource
    MyBatisMapper employeeMapper;

    @Override
    public List<LinkedHashMap<String, Object>> myBatisSelectSQL(String sql)
    {
        return employeeMapper.myBatisSelectSQL(sql);
    }

    @Override
    public int myBatisUpdateSQL(String sql)
    {
        return employeeMapper.myBatisUpdateSQL(sql);
    }
}

 

3、在我们之前自定义的UserRepository类中,继承CustomizedRepository接口。

package com.example.demo.dao;

import com.example.demo.dao.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Long>, CustomizedRepository
{
    // 自定义查询
    User findByUserName(String userName);
}

 

到此为止,在Spring Data JPA中配置MyBatis就完成了。

接下来开始测试。

 


 

测试

1、新建测试类

package com.example.demo;

import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Optional;

import com.example.demo.dao.UserRepository;
import com.example.demo.dao.entity.User;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;

@RunWith(SpringRunner.class)
@SpringBootTest
public class JpaMyBatisDemoApplicationTests
{
    @Autowired
    private UserRepository userRepository;

    // JPA Insert
    @Test
    public void testInsert() throws Exception
    {
        User aUser = new User();
        aUser.setUserName("a01");
        aUser.setPassWord("123456");
        aUser.setRegTime(new Date());
        aUser.setRemark("rmkA01");
        aUser.setSex(1);

        userRepository.save(aUser);
    }

    // JPA Select
    @Test
    public void testSelect() throws Exception
    {
        Optional<User> obj = userRepository.findById(1L);
        User user = obj.get();
        System.out.println("testSelect():" + user.getUserName() + "," + user.getRemark());
    }

    // JPA 自定义查询
    @Test
    public void testSelectCustom() throws Exception
    {
        User user = userRepository.findByUserName("a01");
        System.out.println("testSelect():" + user.getUserName() + "," + user.getRemark());
    }

    // JPA Update
    @Test
    public void testUpdate() throws Exception
    {
        User userUpdate = userRepository.findByUserName("a01");
        userUpdate.setRemark("rmkA01_XXX");
        userRepository.save(userUpdate);
    }

    // JPA Delete
    @Test
    public void testDelete() throws Exception
    {
        userRepository.delete(userRepository.findByUserName("a01"));
    }

    // MyBatis Insert
     @Test
    public void testMyBatisInsert() throws Exception
    {
        int affectedRows = userRepository.myBatisUpdateSQL("insert into User(passWord, regTime, remark, sex, userName) values ('123123', current_timestamp, 'remark_a100', 0, 'A100')");
        System.out.println(affectedRows);
    }

    // MyBatis Select
    @Test
    public void testSelectSQL() throws Exception
    {
        List<LinkedHashMap<String, Object>> items = userRepository.myBatisSelectSQL("SELECT * FROM User");
        for (LinkedHashMap<String, Object> hashMap : items)
        {
            for (String key : hashMap.keySet())
            {
                System.out.println(key + ":" + hashMap.get(key));
            }
            System.out.println("--------------");
        }
    }

    // MyBatis Update
    @Test
    public void testMyBatisUpdate() throws Exception
    {
        int affectedRows = userRepository.myBatisUpdateSQL("update User SET remark = 'remark_a100XXX' WHERE userName = 'A100'");
        System.out.println(affectedRows);
    }

    // MyBatis Delete
    @Test
    public void testMyBatisDelete() throws Exception
    {
        userRepository.myBatisUpdateSQL("delete from User WHERE userName = 'A100'");
    }
}

 

Bootstrap Thumbnail Second
MySQL

MySQL is the world's most popular open source database.

GO

Bootstrap Thumbnail Third
算法基础

本书介绍了什么是计算机算法,如何描述它们,以及如何来评估它们。

GO