文章目录
- 连接池
- 使用JdbcTemplate
- 代码
- 测试
- 使用JPA
- 代码
- 测试
- 使用MaBatis
- 代码
- 测试
- 多数据源
- 连接池
- JdbcTemplate整合
- 代码
- 测试
- 与JPA整合
- 代码
- 测试
- 与MyBatis整合
首先需要引入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整合也是比较简单的,连接池部分不用变,需要自己去创建SqlSessionFactory
和SqlSessionTemplate
注入指定的数据源,放入容器就行了。
需要注意的是,需要在配置类上面使用@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());
}
}