Spring Boot 底层使用 Spring Data 来访问数据库,Spring Data JPA 等于在ORM之上又进行了一次封装,但具体的对数据库的访问依然要依赖于底层的ORM框架,Spring Data JPA 默认是通过 Hibernate 实现的。
传送门:Spring Data JPA和介绍和使用。
1、在创建SpringBoot 的项目时,选择mysql,JPA,web的组件,或者自己手动在maven中添加库依赖:
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
8.0.21
com.alibaba
druid-spring-boot-starter
1.1.13
org.springframework.boot
spring-boot-starter-data-jpa
2、在 application.yml(或aproperties)中添加相应的配置:
server.port=80
spring.datasource.url=jdbc:mysql://localhost:3306/my_springboot?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT
spring.datasource.username=root
spring.datasource.password=123456
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA配置
spring.jpa.database=mysql
# 数据库平台
spring.jpa.database-platform=mysql
# 每次启动项目时,数据库初始化策略
spring.jpa.hibernate.ddl-auto=update
# 指定默认的存储引擎为InnoDB
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
# 在控制台打印SQL
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
3、新建一个model, dao类:
在测试类中测试,所以 service 和controller就不写了
@Entity
@Table(name = "t_user1")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
@Column(name = "id")
private Integer id;
@Column(name = "username")
private String username;
@Column(name = "pazzword")
private String pazzword;
@Column(name = "sex")
private String sex;
@Column(name = "age")
private int age;
@Column(name = "birthday")
private Date birthday;
...
}
public interface UserDao extends JpaRepository {
/*
* 我们在这里直接继承 JpaRepository 的 方法
* 这也是JPA的一大优点
* */
}
截图看一下 JpaRepository 中的一些方法
4、 在 测试类中 进行 CRUD
@SpringBootApplication
public class SpringbootdemoApplication {
public static void main(String[] args) {
SpringApplication.run( SpringbootdemoApplication.class, args);
}
}
@RunWith(SpringRunner.class)
@SpringBootTest
public class SpringbootdemoApplicationTests {
@Autowired
private UserDao userDao;
@Test
public void contextLoads() throws SQLException {
System.out.println(userDao);
// // 新增
// User user = new User();
// user.setUsername("张三");
// user.setPazzword("zhs123");
// user.setSex("男");
// user.setAge(20);
// user.setBirthday(new Date());
// userDao.save(user);
// 删除
// userDao.deleteById(2);
// 查询
User user = userDao.findById(1).get();
System.out.println(user);
// 对查到的 user 修改 UID
user.setUsername("张三1");
user.setSex("女");
userDao.save(user);
}
}
JPA 生成的表
CREATE TABLE `t_user1` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`age` int(11) DEFAULT NULL,
`birthday` datetime DEFAULT NULL,
`pazzword` varchar(255) DEFAULT NULL,
`sex` varchar(255) DEFAULT NULL,
`username` varchar(255) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
二、SpringBoot 配置多数据源之Spring Data JPA
不同于MyBatis和JdbcTemplate,在Jpa中,事务一定要配置。@Primary必须指明优先使用哪个实例。
1、在创建SpringBoot 的项目时,引入依赖
org.springframework.boot
spring-boot-starter-data-jpa
org.springframework.boot
spring-boot-starter-web
mysql
mysql-connector-java
8.0.21
com.alibaba
druid-spring-boot-starter
1.1.13
2、在 application.aproperties中添加两个数据源的配置信息
server.port=8088
# 配置两个数据源
spring.datasource.dsone.url=jdbc:mysql://localhost:3306/sbtdb1?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT
spring.datasource.dsone.username=root
spring.datasource.dsone.password=123456
spring.datasource.dsone.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.dsone.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.dstwo.url=jdbc:mysql://localhost:3306/sbtdb2?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT
spring.datasource.dstwo.username=root
spring.datasource.dstwo.password=123456
spring.datasource.dstwo.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.dstwo.driver-class-name=com.mysql.cj.jdbc.Driver
# JPA配置
spring.jpa.database=mysql
# 数据库平台
spring.jpa.database-platform=mysql
# 每次启动项目时,数据库初始化策略
spring.jpa.hibernate.ddl-auto=update
# 指定默认的存储引擎为InnoDB
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL5InnoDBDialect
# 在控制台打印SQL
spring.jpa.properties.hibernate.show_sql=true
spring.jpa.properties.hibernate.format_sql=true
3、在配置类中,定义两个DataSource Bean
@Configuration
public class DataSourceConfig {
/**
* 定义两个DataSource
* 使用spring.datasource.dsone前缀的数据库配置去创建一个DataSource.
* @Primary表示当某一个类存在多个实例时,优先使用哪个实例。注解@Primary一定不能少,否则在项目启动时会出错,
*/
@Bean("dsOne")
@Primary
@ConfigurationProperties(prefix = "spring.datasource.dsone")
DataSource dsOne() {
return DruidDataSourceBuilder.create().build();
}
@Bean("dsTwo")
@ConfigurationProperties(prefix = "spring.datasource.dstwo")
DataSource dsTwo() {
return DruidDataSourceBuilder.create().build();
}
}
4、提供两个Bean,并配置数据源
@Configuration
@EnableJpaRepositories(basePackages = "com.example.jpa.dao1", //设置Repository所在位置
entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanOne",
transactionManagerRef = "platformTransactionManagerOne")
public class JpaConfigOne {
@Autowired
@Qualifier(value = "dsOne")
DataSource dsOne;
/**
* 注入JpaProperties,它是系统提供的一个实例,里边的数据就是我们在application.properties中配置的jpa相关的配置。
*/
@Autowired
JpaProperties jpaProperties;
@Bean
@Primary
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsOne)
.packages("com.example.jpa.pojo") // 指定的包就是这个数据源对应的实体类所在的位置。
.properties(jpaProperties.getProperties())
.persistenceUnit("persistenceUnit1")
.build();
}
// 注入事务
@Bean
PlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryBeanOne = localContainerEntityManagerFactoryBeanOne(builder);
return new JpaTransactionManager(factoryBeanOne.getObject());
}
}
@Configuration
@EnableJpaRepositories(basePackages = "com.example.jpa.dao2",
entityManagerFactoryRef = "localContainerEntityManagerFactoryBeanTwo",
transactionManagerRef = "platformTransactionManagerTwo")
public class JpaConfigTwo {
@Resource(name = "dsTwo")
DataSource dsTwo;
@Autowired
JpaProperties jpaProperties;
@Bean
LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder) {
return builder.dataSource(dsTwo)
.packages("com.example.jpa.pojo")
.properties(jpaProperties.getProperties())
.persistenceUnit("persistenceUnit2")
.build();
}
@Bean
PlatformTransactionManager platformTransactionManagerTwo(EntityManagerFactoryBuilder builder) {
LocalContainerEntityManagerFactoryBean factoryBeanTwo = localContainerEntityManagerFactoryBeanTwo(builder);
return new JpaTransactionManager(factoryBeanTwo.getObject());
}
}
5、dao创建
public interface UserDao1 extends JpaRepository {
}
public interface UserDao2 extends JpaRepository {
}
@Entity
@Table(name = "t_user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY) // 自增
private int id;
private String name;
private String password;
...
}
6、测试
@SpringBootApplication
public class JpaApplication {
public static void main(String[] args) {
SpringApplication.run(JpaApplication.class, args);
}
}
@RestController
public class UserController {
@Autowired
public UserDao1 userDao1;
@Autowired
public UserDao2 userDao2;
@GetMapping("/list1")
public List list1(){
List list = userDao1.findAll();
return list;
}
@GetMapping("/list2")
public List list2(){
List list = userDao2.findAll();
return list;
}
}
测试访问ok。在Service中注入不同的UserDao,不同的UserDao操作会使用不同的数据源。我这里简单处理省略了service,pojo使用共同的类。
ends ~