本文主要是介绍springboot整合springdata jpa 与多数据源,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
springboot整合springdata jpa 与多数据源
1.整合springdata jpa
1.建库
新建一个数据库 命名为 jpa
不用建表,我们通过构建实体类来自动生成表
2.引入依赖
(默认是web项目,以提前引入了web和thymeleaf的starter)
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-jpa</artifactId></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope></dependency><dependency><groupId>com.alibaba</groupId><artifactId>druid</artifactId><version>1.1.9</version></dependency>
3.数据库配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.url=jdbc:mysql:///jpa?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=123
#以上数据库的基本信息
spring.jpa.show-sql=true
#开启控制台打印生成sql过程
spring.jpa.database=mysql
#项目启动时根据实体类的值自动更新数据库中的表,可选有create,create-drop,validate,no
spring.jpa.hibernate.ddl-auto=update
#规定使用数据库的官方语言是MySQL57Dialect
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57Dialect
4.entity层
@Data
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "t_book")
public class Book {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;@Column(name = "book_name", nullable = false)private String bookName;private String author;private Float price;
//@Transient 代表生成表时,不生成此字段@Transientprivate String description;
}
5.dao层
public interface BookDao extends JpaRepository<Book, Integer> {// 根据作者名字获取书的集合List<Book> getBooksByAuthorStartingWith(String author);// 根据提供价格大于的获取书的集合List<Book> getBooksByPriceGreaterThan(Float price);//获取编号最大的书 ,nativeQuery 开启原生sql@Query(value = "select * from t_book where id=(select max(id) from t_book)", nativeQuery = true)Book getMaxIdBook();// :id ,:author 用来做参数绑定,这里使用的的列名是属性名 不是数据库中列的名字//采用此种方式,一定要写 @param@Query("select b from t_book b where b.id>:id and b.author=:author")List<Book> getBookByIdAndAuthor(@Param("author") String author, @Param("id") Integer id);//?1 ,?2是另一种参数声明方式,但要注意参数的顺序@Query("select b from t_book b where b.id<?2 and b.bookName like %?1%")List<Book> getBooksByIdAndName(String name, Integer id);// 对于update操作,需要添加@Modifying注解并添事务(可以在service实现层方法上加上 @Transactional(isolation = Isolation.READ_COMMITTED))@Modifying@Query(value = "update t_book b set b.book_name=:newName where b.id =:id", nativeQuery = true)void updateBookName(@Param("newName") String newName,@Param("id") Integer id);}
1.使用springdata jpa ,编写dao层使,我们可以直接继承 JpaRepository<实体类class ,主键类型> ,其中提供了一些基本的增删改善,分页查询,排序查询等
2.在springdata jpa中,只要方法的名字符合既定规范,springdata就能分析出你的意图,从而可以避免自己定义sql.也就是根据方法名字自动生成sql语句。我们可以在ecplice或idea中开启方法提示功能,那么输入find 或get 就会有很多的提示方法。当然我们也可以去看官方文档的命名规则,这里我们就不陈述了。
3.如果既定规范不能满足要求,那么 可以采用编写原生sql的方法。例如第10行代码,加上 nativeQuery = true
,就支持原生sql了。
4.传递参数 有两个方式,在上述代码中已经写明。
5.对于修改操作,需要添加@Modifying注解并添事务(可以在service实现层方法上加上 @Transactional(isolation = Isolation.READ_COMMITTED))。
6.service层
@Service
public class BookService {@AutowiredBookDao bookDao;public void addBook(Book book) {bookDao.save(book);}public Page<Book> getBookByPage(Pageable pageable) {return bookDao.findAll(pageable);}public List<Book> getBooksByAuthorStartingWith(String author) {return bookDao.getBooksByAuthorStartingWith(author);}public List<Book> getBooksByPriceGreaterThan(Float price) {return bookDao.getBooksByPriceGreaterThan(price);}public Book getMaxIdBook() {return bookDao.getMaxIdBook();}public List<Book> getBookByIdAndAuthor(String author, Integer id) {return bookDao.getBookByIdAndAuthor(author, id);}public List<Book> getBooksByIdAndName(String name, Integer id) {return bookDao.getBooksByIdAndName(name, id);}@Transactional(isolation = Isolation.READ_COMMITTED)public void updateBookName(String newName,Integer id){bookDao.updateBookName(newName,id);}
7.controller层
@RestController
public class BookController {@AutowiredBookService bookService;@GetMapping("/findAll")public void findAll() {
// 首先通过PageRequest.of方法获得一个PageRequest对象,arm1 代表第几页(从0开始),arm2代码每页显示的条数PageRequest pageable = PageRequest.of(1, 3);Page<Book> page = bookService.getBookByPage(pageable);System.out.println("总页数:" + page.getTotalPages());System.out.println("总记录数:" + page.getTotalElements());System.out.println("查询结果:" + page.getContent());System.out.println("当前页数:" + (page.getNumber() + 1));System.out.println("当前页记录数:" + page.getNumberOfElements());System.out.println("每页记录数:" + page.getSize());}
}
这里只做一个对分页查询的方法。数据库数据可以自己添加。
2.Jpa多数据源
1.建库
新建两个数据库 muljpa1 和muljpa2,不用建表,我们通过构建实体类来自动生成表.
2.引入依赖
依赖与上面差不多,只需要改变一个druid的依赖
<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.1.10</version></dependency>
3,数据库连接和jpa相关配置
配置两个数据源,区别主要是数据库不同。
server.port=8081
#数据源1
spring.datasource.one.password=123
spring.datasource.one.username=root
spring.datasource.one.url=jdbc:mysql:///muljpa1?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource
#数据源2
spring.datasource.two.password=123
spring.datasource.two.username=root
spring.datasource.two.url=jdbc:mysql:///muljpa2?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC
spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource
#jpa相关配置
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL57InnoDBDialect
spring.jpa.properties.database=mysql
spring.jpa.properties.hibernate.hbm2ddl.auto=update
spring.jpa.properties.show-sql= true
4.配置数据源
创建DataSourceConfig配置数据源,根据application.properties中的配置生成两个数据源
@Configuration
public class DataSourceConfig {@Bean@ConfigurationProperties("spring.datasource.one")@PrimaryDataSource dsOne() {return DruidDataSourceBuilder.create().build();}@Bean@ConfigurationProperties("spring.datasource.two")DataSource dsTwo() {return DruidDataSourceBuilder.create().build();}
}
@DataSourceConfig 中提供两个数据源:dsOne 和dsTwo,默认方法名即为实例名。
@ConfigurationProperties 注解表示使用不同前缀的配置文件来创建不同的DataSource实例。
5.实体类和两个dao(分成两个包,一个是dao1,一个是dao2)
@Entity(name = "t_user")
@Data
@NoArgsConstructor
@AllArgsConstructor
public class User {@Id@GeneratedValue(strategy = GenerationType.AUTO)private Integer id;private String name;private String gender;private Integer age;
}
public interface UserDao extends JpaRepository<User,Integer> {
}
public interface UserDao2 extends JpaRepository<User,Integer> {
}
6.创建JPA配置
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.hz.muljpa.dao1",entityManagerFactoryRef = "entityManagerFactoryBeanOne",transactionManagerRef = "platformTransactionManagerOne")
public class JpaConfigOne {@Resource(name = "dsOne")DataSource dsOne;@AutowiredJpaProperties jpaProperties;@Bean@PrimaryLocalContainerEntityManagerFactoryBean entityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder) {return builder.dataSource(dsOne).properties(jpaProperties.getProperties()).packages("com.hz.muljpa.entity").persistenceUnit("pu1").build();}@BeanPlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder) {LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanOne(builder);return new JpaTransactionManager(factoryOne.getObject());}
}
1.使用@EnableTransactionManagement注解来进行JPA的配置,该注解主要配置三个属性,basePackages用来指定repository所在的位置,entityManagerFactoryRef用来指定用来指定实体类管理工厂Bean的名字(就是上述代码,第一个方法的名字),transactionManagerRef用来指定事务管理器的引用名称,(就是上述代码方法的第二个名字)。
2.LocalContainerEntityManagerFactoryBean 创建该实例来提供entityManager实例,在创建该类过程中,首先设置配置源(dsOne),然后设置jpA的相关配置,在设置实体类所在的位置,最后配置实体化单元,若项目中只有一个EntityManagerFactory,则persistenceUnit可以省略,若有多个,则必须明确指定,对于我们配置多数据来说,肯定是多个,一会我们还要在创建一个jpaconfigTwo类。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(basePackages = "com.hz.muljpa.dao2",
entityManagerFactoryRef = "entityManagerFactoryBeanTwo",
transactionManagerRef = "platformTransactionManagerTwo")
public class JpaConfigTwo {@Resource(name = "dsTwo")DataSource dsTwo;@AutowiredJpaProperties jpaProperties;@BeanLocalContainerEntityManagerFactoryBean entityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder) {return builder.dataSource(dsTwo).properties(jpaProperties.getProperties()).packages("com.hz.muljpa.entity").persistenceUnit("pu2").build();}@BeanPlatformTransactionManager platformTransactionManagerTwo(EntityManagerFactoryBuilder builder) {LocalContainerEntityManagerFactoryBean factoryTwo = entityManagerFactoryBeanTwo(builder);return new JpaTransactionManager(factoryTwo.getObject());}
}
注意这两个类中都有LocalContainerEntityManagerFactoryBean被创建,但只有一个上面加了 @Primary注解,代表该实例优先使用。
7.创建controller
@RestController
public class UserController {@AutowiredUserDao userDao;@AutowiredUserDao2 userDao2;@GetMapping("/testmuijpa")public void test1() {User u1 = new User();u1.setAge(55);u1.setName("鲁迅");u1.setGender("男");userDao.save(u1);User u2 = new User();u2.setAge(80);u2.setName("泰戈尔");u2.setGender("男");userDao2.save(u2);}
}
8.测试
localhost:8081/testmuijpa
查看数据库中有没有数据。
("/testmuijpa")
public void test1() {
User u1 = new User();
u1.setAge(55);
u1.setName(“鲁迅”);
u1.setGender(“男”);
userDao.save(u1);
User u2 = new User();
u2.setAge(80);
u2.setName(“泰戈尔”);
u2.setGender(“男”);
userDao2.save(u2);
}
}
### 8.测试localhost:8081/testmuijpa查看数据库中有没有数据。
这篇关于springboot整合springdata jpa 与多数据源的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!