Spring Boot数据库操作


首先需要引入Spring Boot的数据库模块,然后根据连接的数据库类型加入数据库驱动。

<!-- 数据库-->
<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>

<!-- 数据库驱动-->
<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
</dependency>

连接池

默认的情况下,Spring Boot使用的连接池是Hikari,只要我们引入的jdbc模块,就会同时引入这个连接池的依赖,然后在运行的时候就会使用这个东西。

默认启动的时候通过org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration这个类初始化连接池;他会根据当前是否存在对应的依赖,然后创建不同的连接池。默认支持以下几种连接池:

  • Dbcp2
  • Hikari
  • OracleUcp
  • Tomcat

使用其他的数据源需要添加一个属性spring.datasource.type同时需要引入对应连接池的依赖

如下是我使用druid连接池的配置:

# 配置数据库连接的属性
spring.datasource.url=jdbc:mysql://localhost:3306/springboot_demo
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

# 指定连接池
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
<dependency>
   <groupId>com.alibaba</groupId>
   <artifactId>druid</artifactId>
   <version>1.1.17</version>
</dependency>

使用JdbcTemplate

JdbcTemplate是Spring中提供的一个对数据库进行数据访问操作的模板类,文档链接:传送门

在使用的时候不需要额外配置啥,直接使用注解在Dao层进行注入就行了。

代码

这个的Dao层的接口

package com.example.demo.dao;

import com.example.demo.bean.User;

import java.util.List;
import java.util.Map;

/**
 * @version 1.0.0
 * @date 2020年12月16日 08:58
 */
public interface UserDao {

    /**
     * 添加用户
     * @param user 要添加的用户的信息
     * @return 结果
     */
    boolean addUser(User user);

    /**
     * 通过Id删除用户
     * @param id 要删除的用户的Id
     * @return 删除结果
     */
    boolean deleteUser(Integer id);

    /**
     * 更新用户信息
     * @param user 要更新的用户的信息
     * @return 更新的结果
     */
    boolean updateUser(User user);

    /**
     * 通过用户Id查询用户信息
     * @param id 要查询的用户的id
     * @return 查询到的用户信息
     */
    User getUserById(Integer id);

    /**
     * 获取用户列表
     * @return 用户列表
     */
    List<Map<String, Object>> getUserList();
}

对应的实现类,直接写好sql,然后调用JdbcTemplate的方法就行了。

package com.example.demo.dao.impl;

import com.example.demo.bean.User;
import com.example.demo.dao.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * @version 1.0.0
 * @date 2020年12月16日 09:09
 */
@Repository
public class UserDaoImpl implements UserDao {
    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public boolean addUser(User user) {
        String sql = "insert into user(name, age) values(?, ?)";
        Object[] params = {user.getName(), user.getAge()};

        int count = jdbcTemplate.update(sql, params);
        return count > 0;
    }

    @Override
    public boolean deleteUser(Integer id) {

        String sql = "delete from user where id=?";

        int count = jdbcTemplate.update(sql, id);

        return count > 0;
    }

    @Override
    public boolean updateUser(User user) {

        String sql = "update user set name=?, age=? where id=?";

        Object[] params = {user.getName(), user.getAge(), user.getId()};

        int count = jdbcTemplate.update(sql, params);

        return count > 0;
    }

    @Override
    public User getUserById(Integer id) {

        String sql = "select id, name, age from user where id=?";

//        RowMapper<User> rowMapper = BeanPropertyRowMapper.newInstance(User.class);
//        return  jdbcTemplate.queryForObject(sql, rowMapper, id);

         return jdbcTemplate.queryForObject(sql,(rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name"), rs.getInt("age")), id );

//        RowMapper<User> rowMapper = DataClassRowMapper.newInstance(User.class);
//        return jdbcTemplate.queryForObject(sql, rowMapper, id);
    }

    @Override
    public List<Map<String, Object>> getUserList() {

        String sql = "select id, name, age from user";
        return jdbcTemplate.queryForList(sql);
    }
}

对于jdbcTemplate的查询方法,在使用queryForObject的时候,如果是一个封装好的实体类,需要传入一个RowMapper指定查询到的值是怎样转换成实体类的,这个不会自动转换。RowMapper可以直接使用Lambda表达式来自定义,也可以使用Spring提供的类来自动生成。

需要注意的是,如果查询不到值的话queryForObject会抛出EmptyResultDataAccessException异常,这个玩意不是在查询到数据之后转换为实体类的时候的问题,需要进行额外的处理。

测试

package com.example.demo.dao.impl;

import com.example.demo.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.EmptyResultDataAccessException;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @version 1.0.0
 * @date 2020年12月16日 09:31
 */
@SpringBootTest
class UserDaoImplTest {

    @Autowired
    UserDaoImpl userDao;

    @Test
    void addUser() {
        User user = new User("张胜男", 23);

        boolean b = userDao.addUser(user);

        System.out.println(b);
    }

    @Test
    void deleteUser() {
        boolean b = userDao.deleteUser(1);

        System.out.println(b);
    }

    @Test
    void updateUser() {
        User user = new User(1, "李四", 23);

        System.out.println(user);
        boolean b = userDao.updateUser(user);

        System.out.println(b);
    }

    @Test
    void getUserById() {
        User user;
        try {
            user = userDao.getUserById(0);
        }catch (EmptyResultDataAccessException e) {
            user = null;
            e.printStackTrace();
        }

        System.out.println(user);
    }

    @Test
    void getUserList() {

        List<Map<String, Object>> userList = userDao.getUserList();

        System.out.println(userList);
    }
}

使用JPA

需要添加如下的依赖

<dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

在这种情况下,我们只需要写业务逻辑的接口,然后写上对应的sql语句或者是JPQL语句,甚至有一些特定的只需要写上方法就行了,然后剩余的部分交给框架解决。

这个只是一个非常简单的小Demo,具体的请看官方的文档:传送门,API接口:传送门

首先就是Dao类需要继承CrudRepository或者是其子类

然后关键信息其实就是几个注解

  • @Entity:标记这个类是一个实体类
  • @Id:标记当前的属性对应主键
  • @GeneratedValue:标记当前属性的自增方法
  • @Modifying:在对数据库修改的操作中需要用到这个注解
  • @Transactional:事务控制,在修改操作中需要用到
  • Query:主要用来添加语句,如果是使用了原生的sql语句,需要添加nativeQuery = true这个属性

另外就行jpa支持直接解析特定的方法名,无需自己写语句也能够进行数据库操作。

举个例子:

Optional<User> findById(Integer id);

代码

package com.example.demo.bean;

import org.springframework.stereotype.Component;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;

/**
 * @version 1.0.0
 * @date 2020年12月15日 16:57
 */
@Entity
public class User {

    @Id
    @GeneratedValue
    private Integer id;
    private String name;
    private Integer age;
    
    //省去构造方法等
}
package com.example.demo.dao;



@value = "insert into user(name, age) values(?, ?)",)

import com.example.demo.bean.User;
import io.swagger.models.auth.In;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * @version 1.0.0
 * @date 2020年12月16日 08:58
 */
public interface UserDao extends JpaRepository<User, Integer> {

    /**
     * 添加用户
     * @param user 要添加的用户的信息
     * @return 结果
     */
    @Modifying
    @Transactional
    @Query(value = "insert into user(name, age) values(?, ?)", nativeQuery = true)
    int addUser(String name, Integer age);

    /**
     * 通过Id删除用户
     * @param id 要删除的用户的Id
     * @return 删除结果
     */
    @Modifying
    @Transactional
    @Query(value = "delete from user where id=?", nativeQuery = true)
    int deleteUser(Integer id);

    /**
     * 更新用户信息
     * @param user 要更新的用户的信息
     * @return 更新的结果
     */
    @Modifying
    @Transactional
    @Query(value = "update user set name=?, age=? where id=?", nativeQuery = true)
    int updateUser(@Param("name")String name, @Param("age") Integer age, @Param("id") Integer id);

    /**
     * 通过用户Id查询用户信息
     * @param id 要查询的用户的id
     * @return 查询到的用户信息    @Modifying
    @Transactional
    @Query(value = "insert into user(name, age) values(?, ?)", nativeQuery = true)
     */
    @Query("from User u where u.id=:id")
    User getUserById(@Param("id") Integer id);

    /**
     * 获取用户列表
     * @return 用户列表
     */
    @Query(value = "select id, name, age from user", nativeQuery = true)
    List<User> getUserList();

}

测试

package com.example.demo.dao;

import com.example.demo.bean.User;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.dao.EmptyResultDataAccessException;

import java.util.List;
import java.util.Map;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @version 1.0.0
 * @date 2020年12月16日 17:24
 */
@SpringBootTest
class UserDaoTest {

    @Autowired
    private UserDao userDao;

    @Test
    void addUser() {

        int b = userDao.addUser("张胜男", 23);

        System.out.println(b);
    }

    @Test
    void deleteUser() {
        int b = userDao.deleteUser(2);

        System.out.println(b);
    }

    @Test
    void updateUser() {

        int b = userDao.updateUser("李四", 23, 3);

        System.out.println(b);
    }

    @Test
    void getUserById() {
        User user;
        user = userDao.getUserById(2);

        System.out.println(user);
    }

    @Test
    void getUserList() {

        List<User> userList = userDao.getUserList();

        System.out.println(userList);
    }

}

使用MaBatis

首先,引入依赖

<dependency>
   <groupId>org.mybatis.spring.boot</groupId>
   <artifactId>mybatis-spring-boot-starter</artifactId>
   <version>2.1.4</version>
</dependency>

需要配置数据库,直接参考上面的就行了

然后在启动类上面添加上,标记Dao类的位置

@MapperScan(basePackages = "com.example.demo.dao.primary")

常用的配置就下面的这两个,其他的可以直接在mybatis的配置文件里面配置,具体的参考mybatis的说明文件:传送门

# 指定主配置文件的位置
mybatis.config-location=
# 指定mapper的映射文件的位置,如果是和mapper类在同一个包下面,可以省略;如果是使用注解,同样可以省略
mybatis.mapper-locations=

代码

package com.example.demo.dao.primary;

import com.example.demo.bean.User;

import java.util.List;

/**
 * @version 1.0.0
 * @date 2020年12月16日 19:56
 */
public interface UserDao1 {


    /**
     * 向数据库中添加用户
     * @param user 用户信息
     * @return 添加的结果
     */
    boolean addUser(User user);

    /**
     * 更新用户的信息
     * @param user 用户信息
     * @return 更新结果
     */
    boolean updateUser(User user);

    /**
     * 删除用户
     * @param id 要删除的用户的Id
     * @return 删除结果
     */
    boolean deleteUser(Integer id);
}

因为我习惯使用映射文件,所以会多一个,如果是使用注解,可以直接在类上配置

<?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.example.demo.dao.primary.UserDao1">


    <!--    boolean addUser(User user);-->
    <insert id="addUser" parameterType="com.example.demo.bean.User" useGeneratedKeys="true" keyProperty="id">
        insert into user(name, age) values(#{name}, #{age})
    </insert>

    <!--    boolean updateUser(User user);-->
    <update id="updateUser" parameterType="com.example.demo.bean.User">
        update user set name=#{name}, age=#{age} where id=#{id}
    </update>

    <!--    boolean deleteUser(Integer id);-->
    <delete id="deleteUser">
        delete from user where id=#{id}
    </delete>
</mapper>

测试

省略

多数据源

想要整合多个数据源需要分别配置两个不同数据源信息,需要自己写配置类

# 配置数据库连接的属性
# 主数据源
# 需要注意的是数据库地址,原先是url,在这里变成了jdbc-url
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/springboot_demo
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.username=root
spring.datasource.primary.password=123456

spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/demo
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456

这个需要注意的是,在主数据源上面要加上@Primary,表示这个是主数据源。

@ConfigurationProperties则是绑定配置文件中数据的前缀

@Configuration
public class DataSourceConfig {

    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }
}

连接池

默认情况上面的配置已经使用了Hikari连接池,想要使用Druid连接池,我在网上找到了两种解决方法,大致都一样。

第一个是在创建数据源的时候直接就创建Druid连接池,这个就直接跳过了原本的通过反射来创建数据源。

return new DruidDataSource();

第二个是在配置文件中指定数据源的类型,然后在配置类中获取到该类型,然后在交给Spring Boot通过反射创建数据源。

下面是配置类的详细信息

@Configuration
public class DataSourceConfig {
    //获取到不同数据源的连接池类型
    @Value("${spring.datasource.primary.type}")
    private Class<? extends DataSource> primaryDataSourceType;

    @Value("${spring.datasource.secondary.type}")
    private Class<? extends DataSource> secondaryDataSourceType;

    @Bean(name = "primaryDataSource")
    @Qualifier("primaryDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().type(primaryDataSourceType).build();
    }

    @Bean(name = "secondaryDataSource")
    @Qualifier("secondaryDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().type(secondaryDataSourceType).build();
    }
}

在配置文件里面,我指定了两个不同的连接池,Hikari因为其内部配置是使用的jdbc-url所以在指定数据库链接的位置存在不同。

spring.datasource.primary.url=jdbc:mysql://localhost:3306/springboot_demo
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.type=com.alibaba.druid.pool.DruidDataSource

spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/demo
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.type=com.zaxxer.hikari.HikariDataSource

JdbcTemplate整合

同样,也需要自己写配置类,将使用了不同数据源的JdbcTemplate添加到容器中

需要注意的是,记得在DataSource属性上面使用注解,指定是那个数据源

@Configuration
public class JdbcTemplateConfig {

    @Bean(name = "primaryJdbcTemplate")
    @Primary
    public JdbcTemplate primaryJdbcTemplate(@Qualifier("primaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    @Bean(name = "secondaryJdbcTemplate")
    public JdbcTemplate secondaryJdbcTemplate(@Qualifier("secondaryDataSource") DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }
}

这样,就可以在Dao类中直接注入不同的数据源然后使用了

代码

使用主数据源进行增删改操作

package com.example.demo.dao.primary;

import com.example.demo.bean.User;
import org.springframework.stereotype.Repository;

/**
 * @version 1.0.0
 * @date 2020年12月16日 19:56
 */
public interface UserDao1 {

    /**
     * 增加用户
     * @param user 信息
     * @return 结果
     */
    boolean addUser(User user);

    /**
     * 更新用户信息
     * @param user 更新的用户信息
     * @return 更新结果
     */
    boolean updateUser(User user);

    /**
     * 通过用户id删除用户
     * @param id 要删除的用户
     * @return 结果
     */
    boolean deleteUser(Integer id);
}
package com.example.demo.dao.primary.impl;

import com.example.demo.bean.User;
import com.example.demo.dao.primary.UserDao1;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

/**
 * @version 1.0.0
 * @date 2020年12月16日 20:06
 */
@Repository
public class UserDao1Impl implements UserDao1 {
    @Autowired
    private JdbcTemplate primaryJdbcTemplate;

    @Override
    public boolean addUser(User user) {

        String sql = "insert into user(name, age) values(?, ?)";
        Object[] params = {user.getName(), user.getAge()};

        int update = primaryJdbcTemplate.update(sql, params);

        return update > 0;
    }

    @Override
    public boolean updateUser(User user) {

        String sql = "update user set name=?, age=? where id=?";

        int update = primaryJdbcTemplate.update(sql, user.getName(), user.getAge(), user.getId());
        return update > 0;
    }

    @Override
    public boolean deleteUser(Integer id) {

        String sql = "delete from user where id=?";

        int update = primaryJdbcTemplate.update(sql, id);
        return update > 0;
    }
}

使用辅助数据源进行读操作

package com.example.demo.dao.secondary;

import com.example.demo.bean.User;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * @version 1.0.0
 * @date 2020年12月16日 19:56
 */
public interface UserDao2 {

    /**
     * 获取用户列表
     * @return 用户列表
     */
    List<Map<String, Object>> getUserList();

    /**
     * 通过Id查询用户信息
     * @param id id
     * @return 用户信息
     */
    User getUserById(Integer id);

    /**
     * 通过用户名模糊查询用户信息
     * @param name 用户名
     * @return 所有符合条件的信息
     */
    List<Map<String, Object>> getUserByName(String name);

}

实现类

package com.example.demo.dao.secondary.impl;

import com.example.demo.bean.User;
import com.example.demo.dao.secondary.UserDao2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Map;

/**
 * @version 1.0.0
 * @date 2020年12月16日 20:01
 */
@Repository
public class UserDao2Impl implements UserDao2 {
    @Qualifier("secondaryJdbcTemplate")
    @Autowired
    private JdbcTemplate secondaryJdbcTemplate;

    @Override
    public List<Map<String, Object>> getUserList() {

        String sql = "select id, name, age from user";

        return secondaryJdbcTemplate.queryForList(sql);
    }

    @Override
    public User getUserById(Integer id) {

        String sql = "select id, name, age from user where id=?";

        return secondaryJdbcTemplate.queryForObject(sql,
                (rs, rowNum) -> new User(rs.getInt("id"), rs.getString("name"), rs.getInt("age")), id);
    }

    @Override
    public List<Map<String, Object>> getUserByName(String name) {
        String sql = "select id, name, age from user where name like ?";

        return secondaryJdbcTemplate.queryForList(sql, "%"+name+"%");
    }
}
测试
package com.example.demo.dao.primary.impl;

import com.example.demo.bean.User;
import com.example.demo.dao.primary.UserDao1;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

/**

 * @version 1.0.0
 * @date 2020年12月16日 20:14
 */
@SpringBootTest
class UserDao1ImplTest {
    @Autowired
    private UserDao1 userDao;

    @Test
    void addUser() {
        User user = new User("王五", 44);

        boolean b = userDao.addUser(user);

        System.out.println(b);
    }

    @Test
    void updateUser() {
        User user = new User(6,"xiaoming", 14);

        boolean b = userDao.updateUser(user);

        System.out.println(b);
    }

    @Test
    void deleteUser() {

        boolean b = userDao.deleteUser(6);

        System.out.println(b);
    }
}
package com.example.demo.dao.secondary.impl;

import com.example.demo.bean.User;
import com.example.demo.dao.secondary.UserDao2;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import java.util.List;
import java.util.Map;

import static org.junit.jupiter.api.Assertions.*;

/**
 * @version 1.0.0
 * @date 2020年12月17日 09:13
 */
@SpringBootTest
class UserDao2ImplTest {
    @Autowired
    private UserDao2 userDao;

    @Test
    void getUserList() {
        List<Map<String, Object>> userList = userDao.getUserList();


        System.out.println(userList);
    }

    @Test
    void getUserById() {

        User userById = userDao.getUserById(3);

        System.out.println(userById);
    }

    @Test
    void getUserByName() {
        List<Map<String, Object>> userByName = userDao.getUserByName("");

        System.out.println(userByName);
    }
}

与JPA整合

下面是针对主数据源的配置,其他的数据源相对来说除了,dao类的位置更改了,少了@Primary注解,其他的基本一样。

package com.example.demo.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.persistence.EntityManager;
import javax.sql.DataSource;
import java.util.Map;

/**
 * @version 1.0.0
 * @date 2020年12月17日 10:43
 */
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(entityManagerFactoryRef="primaryEntityManagerFactory",
        transactionManagerRef="primaryTransactionManager",
        basePackages = "com.example.demo.dao.primary")
public class PrimaryConfig {
    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;
    @Autowired
    private JpaProperties jpaProperties;

    @Primary
    @Bean(name = "primaryEntityManager")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
    }

    @Primary
    @Bean(name = "primaryEntityManagerFactory")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
        return builder
                .dataSource(primaryDataSource)
                .properties(jpaProperties.getProperties())
                //设置实体类所在位置
                .packages("com.example.demo.bean")
                .persistenceUnit("primaryPersistenceUnit")
                .build();
    }

    @Primary
    @Bean(name = "primaryTransactionManager")
    public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
    }
}
代码

默认提供的有一些简单的增删改查操作。

package com.example.demo.dao.primary;

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

/**
 * @version 1.0.0
 * @date 2020年12月16日 19:56
 */
public interface UserDao1 extends JpaRepository<User, Integer> {
}
package com.example.demo.dao.secondary;

import com.example.demo.bean.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import java.util.List;

/**
 * @version 1.0.0
 * @date 2020年12月16日 19:56
 */
public interface UserDao2 extends JpaRepository<User, Integer> {

    /**
     * 通过用户名模糊查询用户信息
     * @param name 用户名
     * @return 所有符合条件的信息
     */
    @Query(value = "select id, name, age from user where name like %?%", nativeQuery = true)
    List<User> getUserByName(String name);

}
测试

代码略

与MyBatis整合

与MyBaits整合也是比较简单的,连接池部分不用变,需要自己去创建SqlSessionFactorySqlSessionTemplate注入指定的数据源,放入容器就行了。

需要注意的是,需要在配置类上面使用@MapperScan注解,指定那些mapper类是使用当前的数据源,在主启动类上面的那个就可以删除了,其他的和上面那个不使用多数据源的相同。

package com.example.demo.config;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import javax.sql.DataSource;

/**
 * @version 1.0.0
 * @date 2020年12月17日 10:43
 */
@Configuration
@MapperScan(
        basePackages = "com.example.demo.dao.primary",
        sqlSessionFactoryRef = "primarySqlSessionFactory",
        sqlSessionTemplateRef = "primarySqlSessionTemplate"
)
public class PrimaryConfig {
    @Autowired
    @Qualifier("primaryDataSource")
    private DataSource primaryDataSource;


    @Bean("primarySqlSessionFactory")
    @Primary
    public SqlSessionFactory primarySqlSessionFactory() throws Exception {
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();

        sqlSessionFactoryBean.setDataSource(primaryDataSource);

        return sqlSessionFactoryBean.getObject();
    }

    @Bean("primarySqlSessionTemplate")
    @Primary
    public SqlSessionTemplate primarySqlSessionTemplate() throws Exception {
        return new SqlSessionTemplate(primarySqlSessionFactory());
    }

}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值