<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <!-- jdbcTemplate 依賴 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!-- mysql 依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- 測試 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- springboot-web組件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
4.1.2 application.properties新增配置java
spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver
@Service public class UserServiceImpl implements UserService { @Autowired private JdbcTemplate jdbcTemplate; public void createUser(String name, Integer age) { jdbcTemplate.update("insert into users values(null,?,?);", name, age); } }
4.1.4 App類mysql
@SpringBootApplication public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
注意: spring-boot-starter-parent要在1.5以上git
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 測試 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mysql 依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- springboot-web組件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
4.2.二、配置文件引入github
spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver
public interface UserMapper { @Select("SELECT * FROM USERS WHERE NAME = #{name}") User findByName(@Param("name") String name); @Insert("INSERT INTO USERS(NAME, AGE) VALUES(#{name}, #{age})") int insert(@Param("name") String name, @Param("age") Integer age); }
@MapperScan("com.mapper") @SpringBootApplication public class MybatisApp { public static void main(String[] args) { SpringApplication.run(MybatisApp.class, args); } }
pageHelperweb
PageHelper 是一款好用的開源免費的 Mybatis 第三方物理分頁插件spring
物理分頁sql
支持常見的 12 種數據庫。Oracle,MySql,MariaDB,SQLite,DB2,PostgreSQL,SqlServer 等數據庫
支持多種分頁方式apache
支持常見的 RowBounds(PageRowBounds),PageHelper.startPage 方法調用,Mapper 接口參數調用springboot
Maven依賴
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter</artifactId> </dependency> <!-- 測試 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.1.1</version> </dependency> <!-- mysql 依賴 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!-- springboot-web組件 --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- springboot 整合 pagehelper --> <dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper-spring-boot-starter</artifactId> <version>1.2.5</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-lang3</artifactId> <version>3.7</version> </dependency> </dependencies>
配置文件
spring.datasource.url=jdbc:mysql://localhost:3306/test spring.datasource.username=root spring.datasource.password=root spring.datasource.driver-class-name=com.mysql.jdbc.Driver logging.level.com.example.demo.dao=DEBUG pagehelper.helperDialect=mysql pagehelper.reasonable=true pagehelper.supportMethodsArguments=true pagehelper.params=count=countSql pagehelper.page-size-zero=true
Entity層
@Data public class User { private Integer id; private String name; private Integer age; }
Mapper層
public interface UserMapper { @Select("SELECT * FROM USERS ") List<User> findUserList(); }
Service層
@Service public class UserService { @Autowired private UserMapper userMapper; public PageInfo<User> findUserList(int page, int size) { // 開啓分頁插件,放在查詢語句上面 PageHelper.startPage(page, size); List<User> listUser = userMapper.findUserList(); // 封裝分頁以後的數據 PageInfo<User> pageInfoUser = new PageInfo<User>(listUser); return pageInfoUser; } }
Controller層
@RestController public class IndexController { @Autowired private UserService userService; @RequestMapping("/findUser") public PageInfo<User> findUserList(int page, int size) { return userService.findUserList(page, size); } }
啓動項目
@MapperScan("com.mapper") @SpringBootApplication public class PageHelper { public static void main(String[] args) { SpringApplication.run(PageHelper.class, args); } }
<parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.0.RELEASE</version> </parent> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> </dependencies>
@Entity(name = "users") public class UserEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; @Column(name = "name") private String name; @Column(name = "age") private Integer age; }
4.3.3 建立UserDao
public interface UserDao extends JpaRepository<User, Integer> { }
4.3.3 建立IndexController
@RestController public class IndexController { @Autowired private UserDao userDao; @RequestMapping("/jpaFindUser") public Object jpaIndex(User user) { Optional<User> userOptional = userDao.findById(user.getId()); User reusltUser = userOptional.get(); return reusltUser == null ? "沒有查詢到數據" : reusltUser; } }
4.3.4 啓動項目
@SpringBootApplication public class JpaApp { public static void main(String[] args) { SpringApplication.run(JpaApp.class, args); } }
思考下,大家在項目中有使用到多數據源嗎?
原理使用根據包名,加載不一樣的數據源
###datasource1 spring.datasource.test1.driver-class-name = com.mysql.jdbc.Driver spring.datasource.test1.jdbc-url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8 spring.datasource.test1.username = root spring.datasource.test1.password = root ###datasource2 spring.datasource.test2.driver-class-name = com.mysql.jdbc.Driver spring.datasource.test2.jdbc-url = jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8 spring.datasource.test2.username = root spring.datasource.test2.password = root
//DataSource01 @Configuration // 註冊到springboot容器中 @MapperScan(basePackages = "com.example.test01", sqlSessionFactoryRef = "test1SqlSessionFactory") public class DataSource1Config { @Bean(name = "test1DataSource") @ConfigurationProperties(prefix = "spring.datasource.test1") @Primary public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "test1SqlSessionFactory") @Primary public SqlSessionFactory testSqlSessionFactory(@Qualifier("test1DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); // bean.setMapperLocations( // new // PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test1/*.xml")); return bean.getObject(); } @Bean(name = "test1TransactionManager") @Primary public DataSourceTransactionManager testTransactionManager(@Qualifier("test1DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "test1SqlSessionTemplate") @Primary public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("test1SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
DataSource02
//DataSource2 @Configuration // 註冊到springboot容器中 @MapperScan(basePackages = "com.example.test02", sqlSessionFactoryRef = "test2SqlSessionFactory") public class DataSource2Config { @Bean(name = "test2DataSource") @ConfigurationProperties(prefix = "spring.datasource.test2") public DataSource testDataSource() { return DataSourceBuilder.create().build(); } @Bean(name = "test2SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); // bean.setMapperLocations( // new // PathMatchingResourcePatternResolver().getResources("classpath:mybatis/mapper/test2/*.xml")); return bean.getObject(); } @Bean(name = "test2TransactionManager") public DataSourceTransactionManager testTransactionManager(@Qualifier("test2DataSource") DataSource dataSource) { return new DataSourceTransactionManager(dataSource); } @Bean(name = "test2SqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
public interface User1Mapper { @Insert("insert into users values(null,#{name},#{age});") public int addUser(@Param("name") String name, @Param("age") Integer age); }
在多數據源的狀況下,使用@Transactional註解時,應該指定事務管理者
@Transactional(transactionManager = 「test2TransactionManager」)
4.4.5啓動項目
@SpringBootApplication @MapperScan(basePackages = { "com.example.mapper" }) public class App { public static void main(String[] args) { SpringApplication.run(App.class, args); } }
No qualifying bean of type [javax.sql.DataSource] is defined: expected single matching bean but found 2: test1DataSource,test2DataSource
加上@Primary便可。
There was an unexpected error (type=Internal Server Error, status=500).
No qualifying bean of type ‘org.springframework.transaction.PlatformTransactionManager’ available: expected single matching bean but found 2: test1TransactionManager,test2TransactionManager
指定事務管理器
Springboot1.5的時候 沒有默認指向數據源 會報錯
Springboot2.0的時候 不報錯
Springboot默認集成事物,只主要在方法上加上@Transactional便可
使用springboot+jta+atomikos 分佈式事物管理
Atomikos 是一個爲Java平臺提供增值服務的而且開源類事務管理器。
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jta-atomikos</artifactId> </dependency>
5.1.2.2新增配置文件信息
# Mysql 1 mysql.datasource.test1.url = jdbc:mysql://localhost:3306/test01?useUnicode=true&characterEncoding=utf-8 mysql.datasource.test1.username = root mysql.datasource.test1.password = root mysql.datasource.test1.minPoolSize = 3 mysql.datasource.test1.maxPoolSize = 25 mysql.datasource.test1.maxLifetime = 20000 mysql.datasource.test1.borrowConnectionTimeout = 30 mysql.datasource.test1.loginTimeout = 30 mysql.datasource.test1.maintenanceInterval = 60 mysql.datasource.test1.maxIdleTime = 60 # Mysql 2 mysql.datasource.test2.url =jdbc:mysql://localhost:3306/test02?useUnicode=true&characterEncoding=utf-8 mysql.datasource.test2.username =root mysql.datasource.test2.password =root mysql.datasource.test2.minPoolSize = 3 mysql.datasource.test2.maxPoolSize = 25 mysql.datasource.test2.maxLifetime = 20000 mysql.datasource.test2.borrowConnectionTimeout = 30 mysql.datasource.test2.loginTimeout = 30 mysql.datasource.test2.maintenanceInterval = 60 mysql.datasource.test2.maxIdleTime = 60
@Data @ConfigurationProperties(prefix = "mysql.datasource.test1") public class DBConfig1 { private String url; private String username; private String password; private int minPoolSize; private int maxPoolSize; private int maxLifetime; private int borrowConnectionTimeout; private int loginTimeout; private int maintenanceInterval; private int maxIdleTime; private String testQuery; }
@Data @ConfigurationProperties(prefix = "mysql.datasource.test2") public class DBConfig2 { private String url; private String username; private String password; private int minPoolSize; private int maxPoolSize; private int maxLifetime; private int borrowConnectionTimeout; private int loginTimeout; private int maintenanceInterval; private int maxIdleTime; private String testQuery; }
@Configuration // basePackages 最好分開配置 若是放在同一個文件夾可能會報錯 @MapperScan(basePackages = "com.example.test01", sqlSessionTemplateRef = "testSqlSessionTemplate") public class MyBatisConfig1 { // 配置數據源 @Primary @Bean(name = "testDataSource") public DataSource testDataSource(DBConfig1 testConfig) throws SQLException { MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(testConfig.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(testConfig.getPassword()); mysqlXaDataSource.setUser(testConfig.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("testDataSource"); xaDataSource.setMinPoolSize(testConfig.getMinPoolSize()); xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize()); xaDataSource.setMaxLifetime(testConfig.getMaxLifetime()); xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout()); xaDataSource.setLoginTimeout(testConfig.getLoginTimeout()); xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval()); xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime()); xaDataSource.setTestQuery(testConfig.getTestQuery()); return xaDataSource; } @Primary @Bean(name = "testSqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("testDataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Primary @Bean(name = "testSqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("testSqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
@Configuration @MapperScan(basePackages = "com.example.test02", sqlSessionTemplateRef = "test2SqlSessionTemplate") public class MyBatisConfig2 { // 配置數據源 @Bean(name = "test2DataSource") public DataSource testDataSource(DBConfig2 testConfig) throws SQLException { MysqlXADataSource mysqlXaDataSource = new MysqlXADataSource(); mysqlXaDataSource.setUrl(testConfig.getUrl()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); mysqlXaDataSource.setPassword(testConfig.getPassword()); mysqlXaDataSource.setUser(testConfig.getUsername()); mysqlXaDataSource.setPinGlobalTxToPhysicalConnection(true); AtomikosDataSourceBean xaDataSource = new AtomikosDataSourceBean(); xaDataSource.setXaDataSource(mysqlXaDataSource); xaDataSource.setUniqueResourceName("test2DataSource"); xaDataSource.setMinPoolSize(testConfig.getMinPoolSize()); xaDataSource.setMaxPoolSize(testConfig.getMaxPoolSize()); xaDataSource.setMaxLifetime(testConfig.getMaxLifetime()); xaDataSource.setBorrowConnectionTimeout(testConfig.getBorrowConnectionTimeout()); xaDataSource.setLoginTimeout(testConfig.getLoginTimeout()); xaDataSource.setMaintenanceInterval(testConfig.getMaintenanceInterval()); xaDataSource.setMaxIdleTime(testConfig.getMaxIdleTime()); xaDataSource.setTestQuery(testConfig.getTestQuery()); return xaDataSource; } @Bean(name = "test2SqlSessionFactory") public SqlSessionFactory testSqlSessionFactory(@Qualifier("test2DataSource") DataSource dataSource) throws Exception { SqlSessionFactoryBean bean = new SqlSessionFactoryBean(); bean.setDataSource(dataSource); return bean.getObject(); } @Bean(name = "test2SqlSessionTemplate") public SqlSessionTemplate testSqlSessionTemplate( @Qualifier("test2SqlSessionFactory") SqlSessionFactory sqlSessionFactory) throws Exception { return new SqlSessionTemplate(sqlSessionFactory); } }
@EnableConfigurationProperties(value = { DBConfig1.class, DBConfig2.class })
分佈式事務,能夠預覽個人這個連接分佈式事務