SpringBoot的持久化層可以是Spring內置的輕量級JdbcTemplate、也可以是Hibernate或Mybatis等等,只需要在在工程pom.xml文件中添加對應的依賴就可以了。
新建工程我們能發(fā)現,SpringBoot對數據庫操作的支持有以下幾種:
可見SpringBoot對各種的支持還是挺多的。
入正題。看看對SQL的支持。主要選了比較傳統/流行/有前景的4個進行操作:
均是采用mysql。
所以應該添加對mysql操作的依賴:
1
2
3
4
5
6
|
<!--MySQL--> <dependency> <groupid>mysql</groupid> mysql-connector-java</artifactid> <scope>runtime</scope> </dependency> |
同時,需要對web進行支持,添加web相關依賴
1
2
3
4
5
|
<!--web支持--> <dependency> <groupid>org.springframework.boot</groupid> spring-boot-starter-web</artifactid> </dependency> |
需要在application.properties中配置mysql相關信息(也可以使用*.yml)。配置如下:
1
2
3
4
|
spring.datasource.driver- class -name=com.mysql.jdbc.Driver spring.datasource.url= jdbc:mysql: //localhost:3306/springboottest?useUnicode=true&characterEncoding=utf-8 spring.datasource.username=root spring.datasource.password=root |
實際應用的時候,需要添加數據庫連接池,為了方便,就暫時不添加了。
1. SpringBoot用JdbcTemplates訪問Mysql
首先需要添加對JdbcTemplates的依賴,可以在新建工程中點擊添加,或手動添加
1
2
3
4
5
|
<!--JDBC支持--> <dependency> <groupid>org.springframework.boot</groupid> spring-boot-starter-jdbc</artifactid> </dependency> |
目錄結構如上,代碼如下:
1
2
3
4
5
6
|
@Data public class Account { private int id ; private String name ; private double money; } |
這里是安裝了一個插件,然后只需要添加如下依賴,添加@Data注解,就會幫我們自動生成getter和setter,也可以用@getter或@Setter注解進行標注。
1
2
3
4
|
<dependency> <groupid>org.projectlombok</groupid> lombok</artifactid> </dependency> |
1
2
3
4
5
6
7
8
9
|
public interface IAccountDao { int add(Account account); int update(Account account); int delete( int id); Account findAccountById( int id); Account selectAccountById( int id); List findAccountList(); }</account> |
實現類:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
|
@Repository public class AccountDaoImpl implements IAccountDao{ @Autowired private JdbcTemplate jdbcTemplate; @Override public int add(Account account) { return jdbcTemplate.update( "INSERT INTO account(name,money) VALUES(?,?)" , account.getName(),account.getMoney()); } @Override public int update(Account account) { return jdbcTemplate.update( "UPDATE account SET name=?,money=? WHERE id=?" , account.getName(),account.getMoney(),account.getId()); } @Override public int delete( int id) { return jdbcTemplate.update( "DELETE FROM TABLE account WHERE id=?" , id); } @Override public Account findAccountById( int id) { List list = jdbcTemplate.query( "SELECT * FROM account WHERE id = ?" , new Object[]{id}, new BeanPropertyRowMapper(Account. class )); if (list!= null && list.size()> 0 ){ Account account = list.get( 0 ); return account; } else { return null ; } } @Override public Account selectAccountById( int id){ return jdbcTemplate.queryForObject( "SELECT * FROM account WHERE id = ?" , new RowMapper() { @Override public Account mapRow(ResultSet resultSet, int i) throws SQLException { Account account = new Account(); account.setId(resultSet.getInt( "id" )); account.setName(resultSet.getString( "name" )); account.setMoney(resultSet.getDouble( "money" )); return account; } },id); } @Override public List findAccountList() { List list = jdbcTemplate.query( "SELECT * FROM account" , new Object[]{}, new BeanPropertyRowMapper(Account. class )); if (list!= null && list.size()> 0 ) return list; else return null ; } }</account></account></account></account> |
后續(xù)也可以添加更多的操作,包括分頁等等。這里主要就是jdbcTemplate的操作了,詳情也可以查相關資料
Service層:
1
2
3
4
5
6
7
8
|
public interface IAccountService { int add(Account account); int update(Account account); int delete( int id); Account findAccountById( int id); Account selectAccountById( int id); List findAccountList(); }</account> |
實現
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
@Service public class JdbcAccountService implements IAccountService { @Autowired private IAccountDao accountDao; @Override public int add(Account account) { return accountDao.add(account); } @Override public int update(Account account) { return accountDao.update(account); } @Override public int delete( int id) { return accountDao.delete(id); } @Override public Account findAccountById( int id) { return accountDao.findAccountById(id); } @Override public Account selectAccountById( int id) { return accountDao.selectAccountById(id); } @Override public List findAccountList() { return accountDao.findAccountList(); } } </account> |
Controller:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
@RestController @RequestMapping ( "/jdbc/account" ) public class JdbcAccountController { @Autowired private IAccountService accountService; @RequestMapping (value = "/list" ,method = RequestMethod.<em>GET</em>) public List getAccounts(){ return accountService.findAccountList(); } @RequestMapping (value = "/{id}" ,method = RequestMethod.<em>GET</em>) public Account getAccountById( @PathVariable ( "id" ) int id){ // return accountService.findAccountById(id); return accountService.selectAccountById(id); } @RequestMapping (value = "/{id}" ,method = RequestMethod.<em>PUT</em>) public String updateAccount( @PathVariable ( "id" ) int id , @RequestParam (value = "name" ,required = true )String name, @RequestParam (value = "money" ,required = true ) double money){ Account account= new Account(); account.setMoney(money); account.setName(name); account.setId(id); int t=accountService.update(account); if (t== 1 ){ return account.toString(); } else { return "fail" ; } } @RequestMapping (value = "" /*,method = RequestMethod.POST*/ ) public String postAccount( @RequestParam (value = "name" )String name, @RequestParam (value = "money" ) double money){ Account account= new Account(); account.setMoney(money); account.setName(name); int t= accountService.add(account); if (t== 1 ){ return account.toString(); } else { return "fail" ; } } }</account> |
難度不大,只是簡單的對數據庫進行訪問和修改,注意注解不要忘記標注了。
2.SpringBoot 整合JPA
Jpa算是比較方便的,用起來只需注意相關規(guī)則就可以了,不管jpa還是mybatis,都是有各自優(yōu)點的,在那里使用方便,就采用哪個,沒好壞之分。
首先,也是需要添加相關的依賴
1
2
3
4
5
|
<!--JPA支持--> <dependency> <groupid>org.springframework.boot</groupid> spring-boot-starter-data-jpa</artifactid> </dependency> |
創(chuàng)建實體(注意注解)
Dao層:這里只做了簡單的演示,所以沒有添加特殊的操作,直接繼承jpa給我們提供的接口,就可以了,后續(xù)需要添加一些東西的話,可以添加對應的方法
1
2
|
public interface AccountDao extends JpaRepository { }</account,integer> |
Controller層:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
@RestController @RequestMapping ( "/jpa/account" ) public class JpaAccountController { @Autowired private AccountDao accountDao; @RequestMapping (value = "/list" ,method = RequestMethod.<em>GET</em>) public List getAccounts(){ return accountDao.findAll(); } @RequestMapping (value = "/{id}" ,method = RequestMethod.<em>GET</em>) public Account getAccountById( @PathVariable ( "id" ) int id){ return accountDao.findOne(id); } @RequestMapping (value = "/{id}" ,method = RequestMethod.<em>PUT</em>) public String updateAccount( @PathVariable ( "id" ) int id , @RequestParam (value = "name" ,required = true )String name, @RequestParam (value = "money" ,required = true ) double money){ Account account= new Account(); account.setMoney(money); account.setName(name); account.setId(id); Account account1 = accountDao.saveAndFlush(account); return account1.toString(); } @RequestMapping (value = "" /*,method = RequestMethod.POST*/ ) public String postAccount( @RequestParam (value = "name" )String name, @RequestParam (value = "money" ) double money){ Account account= new Account(); account.setMoney(money); account.setName(name); Account account1 = accountDao.save(account); return account1.toString(); } }</account> |
總體來說,jpa代碼很簡潔,也很強大,能夠實現一些常規(guī)的操作,對于開發(fā)者來說還是挺高效的,對于一些特殊的需求,也可以看官方給我們的文檔,3.springboot整合mybatisMybatis在現在也是一個非常流行的持久化層框架了,和Hibernate比起來,可以自己編寫sql語句,從而利用高效的sql語句制作好的產品。但缺點也是在編寫sql語句,這方面有點花時間,相比jpa來說。入正題:
添加依賴:
1
2
3
4
5
6
|
<!--MyBatis支持--> <dependency> <groupid>org.mybatis.spring.boot</groupid> mybatis-spring-boot-starter</artifactid> <version> 1.2 . 0 </version> </dependency> |
Mybatis可以采用兩種方式進行編寫,一種是基于xml的配置方式,一種是基于注解的方式,選擇何種方式,當然是蘿卜白菜啦,選最合適自己的。
實體還是上一個例子的實體,這里就不添加了,dao層設計我們先來說一下用注解的方式:注解的方式相比下還是挺方便的,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
@Mapper public interface AccountMapper { @Insert ( "INSERT INFO account(name,money) VALUES(#{name},#{money})" ) int add( @Param ( "name" )String name, @Param ( "money" ) double money); @Update ( "UPDATE account SET name = #{name}, money = #{money} WHERE id = #{id}" ) int update( @Param ( "name" ) String name, @Param ( "money" ) double money, @Param ( "id" ) int id); @Delete ( "DELETE FROM account WHERE id = #{id}" ) int delete( int id); @Select ( "SELECT id, name AS name, money AS money FROM account WHERE id = #{id}" ) Account findAccount( @Param ( "id" ) int id); @Select ( "SELECT id, name AS name, money AS money FROM account" ) List findAccountList(); } </account> |
注解單詞簡單明了,就不解釋了,但要注意的是,方法名稱也要適當的取好,不然以后對數據庫操作多了,有可能會亂,需要不斷回來看代碼。
Service層:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
@Service public class MybatisAccountService { @Autowired private AccountMapper accountMapper; public int add(String name, double money) { return accountMapper.add(name, money); } public int update(String name, double money, int id) { return accountMapper.update(name, money, id); } public int delete( int id) { return accountMapper.delete(id); } public Account findAccount( int id) { return accountMapper.findAccount(id); } public List findAccountList() { return accountMapper.findAccountList(); } }</account> |
對應的Controller與上面的沒有多大區(qū)別
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
|
@RestController @RequestMapping ( "/mybatis/account" ) public class MybatisAccountController { @Autowired private MybatisAccountService mybatisAccountService; @RequestMapping (value = "/list" , method = RequestMethod.<em>GET</em>) public List getAccounts() { return mybatisAccountService.findAccountList(); } @RequestMapping (value = "/{id}" , method = RequestMethod.<em>GET</em>) public Account getAccountById( @PathVariable ( "id" ) int id) { return mybatisAccountService.findAccount(id); } @RequestMapping (value = "/{id}" , method = RequestMethod.<em>PUT</em>) public String updateAccount( @PathVariable ( "id" ) int id, @RequestParam (value = "name" , required = true ) String name, @RequestParam (value = "money" , required = true ) double money) { int t= mybatisAccountService.update(name,money,id); if (t== 1 ) { return "success" ; } else { return "fail" ; } } @RequestMapping (value = "/{id}" , method = RequestMethod.<em>DELETE</em>) public String delete( @PathVariable (value = "id" ) int id) { int t= mybatisAccountService.delete(id); if (t== 1 ) { return "success" ; } else { return "fail" ; } } @RequestMapping (value = "" , method = RequestMethod.<em>POST</em>) public String postAccount( @RequestParam (value = "name" ) String name, @RequestParam (value = "money" ) double money) { int t= mybatisAccountService.add(name,money); if (t== 1 ) { return "success" ; } else { return "fail" ; } } }</account> |
對比之下,我們再來看看基于xml的配置方式。(偷懶就只做一個了)
1
2
3
|
public interface AccountMapper1 { int update( @Param ( "money" ) double money, @Param ( "id" ) int id); } |
首先需要寫一個接口,然后在application中添加配置
1
2
|
mybatis.mapper-locations=classpath*:mybatis/*Mapper.xml mybatis.type-aliases- package =com.jinwen.www.MYBATIS.bean |
很簡單,然后編寫主要的sql語句了,由于我們的配置,后綴名必須為Mapper.xml才可以被掃描到
需要在resources下創(chuàng)建一個mybaits文件夾,并添加xml,這里我們明明為AccountMapper.xml.,代碼如下
1
2
3
4
5
6
7
|
<!--?xml version= "1.0" encoding= "UTF-8" ?--> <mapper namespace= "com.jinwen.www.MYBATIS.Dao.AccountMapper1" > <update id= "update" > UPDATE account set money=#{money} WHERE id=#{id} </update> </mapper> |
注意,命名空間那里,需要填自己的,簡單的一個update,做完這幾步,就可以了
service層:
1
2
3
4
5
6
7
8
9
10
|
@Service public class MybatisAccountService1 { @Autowired AccountMapper1 accountMapper1; @Transactional public void transfer() throws RuntimeException{ accountMapper1.update( 90 , 1 ); //用戶1減10塊 用戶2加10塊 // int i=1/0;//測試事務回滾 accountMapper1.update( 110 , 2 ); } } |
@Transactional注解可以實現事務回滾,當發(fā)生異常的時候,同樣,對于jpa,jdbcTemplate也可以添加此注解進行事務處理。
Controller層(這里注意的是@MapperScan的注解,是實體的路徑)
1
2
3
4
5
6
7
8
9
10
|
@RestController @RequestMapping ( "/mybatis/account" ) @MapperScan ( "com.jinwen.www.MYBATIS.Dao" ) public class MybatisAccountController1 { @Autowired private MybatisAccountService1 accountService; @RequestMapping (value = "/transfer" , method = RequestMethod.<em>GET</em>) public void transfer(){ accountService.transfer(); } } |
mybatis更多復雜的操作可以想見相關的mybatis資料。4.springboot整合 BeetlSQL
BeetlSQL 特點
BeetSql是一個全功能DAO工具, 同時具有Hibernate 優(yōu)點 & Mybatis優(yōu)點功能,適用于承認以SQL為中心,同時又需求工具能自動能生成大量常用的SQL的應用。
開發(fā)效率無需注解,自動使用大量內置SQL,輕易完成增刪改查功能,節(jié)省50%的開發(fā)工作量數據模型支持Pojo,也支持Map/List這種快速模型,也支持混合模型SQL 模板基于Beetl實現,更容易寫和調試,以及擴展可以針對單個表(或者視圖)代碼生成pojo類和sql模版,甚至是整個數據庫。能減少代碼編寫工作量維護性SQL 以更簡潔的方式,Markdown方式集中管理,同時方便程序開發(fā)和數據庫SQL調試。可以自動將sql文件映射為dao接口類靈活直觀的支持支持一對一,一對多,多對多關系映射而不引入復雜的OR Mapping概念和技術。具備Interceptor功能,可以調試,性能診斷SQL,以及擴展其他功能其他內置支持主從數據庫支持的開源工具支持跨數據庫平臺,開發(fā)者所需工作減少到最小,目前跨數據庫支持mysql,postgres,oracle,sqlserver,h2,sqllite,DB2. 以上來自beatlSql官網文檔。網址:https://ibeetl.com/guide/#beetlsql
總體指標比起來,比mybatis更具備優(yōu)勢,或將成為未來的主流、
首先需要添加依賴
1
2
3
4
|
<!--beetlsql支持--> <groupid>com.ibeetl</groupid> beetlsql</artifactid> <version> 2.9 . 5 </version> |
然后要在主方法類下進行配置(很關鍵,不然會報一些找不到的錯誤,或者一些奇怪的錯誤)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
|
@SpringBootApplication public class SpringbootpersistenceApplication { public static void main(String[] args) { SpringApplication.run(SpringbootpersistenceApplication. class , args); } //配置包掃描 @Bean (name = "beetlSqlScannerConfigurer" ) public BeetlSqlScannerConfigurer getBeetlSqlScannerConfigurer() { BeetlSqlScannerConfigurer conf = new BeetlSqlScannerConfigurer(); conf.setBasePackage( "com.jinwen.www.BeetlSQL.Dao" ); conf.setDaoSuffix( "Dao" ); conf.setSqlManagerFactoryBeanName( "sqlManagerFactoryBean" ); return conf; } @Bean (name = "sqlManagerFactoryBean" ) @Primary public SqlManagerFactoryBean getSqlManagerFactoryBean( @Qualifier ( "datasource" ) DataSource datasource) { SqlManagerFactoryBean factory = new SqlManagerFactoryBean(); BeetlSqlDataSource source = new BeetlSqlDataSource(); source.setMasterSource(datasource); factory.setCs(source); factory.setDbStyle( new MySqlStyle()); factory.setInterceptors( new Interceptor[]{ new DebugInterceptor()}); factory.setNc( new UnderlinedNameConversion()); //開啟駝峰 factory.setSqlLoader( new ClasspathLoader( "/sql" )); //sql文件路徑 return factory; } //配置數據庫 @Bean (name = "datasource" ) public DataSource getDataSource() { return DataSourceBuilder.create().url( "jdbc:mysql://localhost:3306/springboottest" ).username( "root" ).password( "root" ).build(); } // //開啟事務 // @Bean(name = "txManager") // public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("datasource") DataSource datasource) { // DataSourceTransactionManager dsm = new DataSourceTransactionManager(); // dsm.setDataSource(datasource); // return dsm; // } } |
注意這里的配置包掃描,需要掃描自己的包,不然會包no find
根據配置,編寫的“sql”代碼將在sql路徑下,需要在resources下創(chuàng)建這個文件夾
編寫相關操作
實體:
1
2
3
4
5
6
|
@Data public class Account { private int id ; private String name ; private double money; } |
dao層:
1
2
3
4
5
6
|
@SqlResource ( "account" ) public interface BeetlSQLAccountDao extends BaseMapper { // @SqlStatement(params = "name") Account selectAccountByName(String name); } </account> |
@SqlResource注解就是在sql目錄下對應的.md文件。如果是java.account則對應是sql目錄下的java目錄下的account.md文件。這個文件寫有相關的對數據庫的操作。
注意,這里繼承的BaseMapper是由BeetlSQL提供的。
account.md 編寫
1
2
3
4
|
<em>selectAccountByName </em><em>=== </em>*根據name獲account select * from account where name= #name# |
Controller層:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
|
@RestController @RequestMapping ( "/beetlsql/account" ) public class BeetlSQLAccountController { @Autowired private BeetlSQLAccountDao beetlSQLAccountDao; @RequestMapping (value = "/list" ,method = RequestMethod.<em>GET</em>) public List getAccounts(){ return beetlSQLAccountDao.all(); } @RequestMapping (value = "/{id}" ,method = RequestMethod.<em>GET</em>) public Account getAccountById( @PathVariable ( "id" ) int id){ return beetlSQLAccountDao.unique(id); } @RequestMapping (value = "" ,method = RequestMethod.<em>GET</em>) public Account getAccountById( @RequestParam ( "name" ) String name){ return beetlSQLAccountDao.selectAccountByName(name); } @RequestMapping (value = "/{id}" ,method = RequestMethod.<em>PUT</em>) public String updateAccount( @PathVariable ( "id" ) int id , @RequestParam (value = "name" ,required = true )String name, @RequestParam (value = "money" ,required = true ) double money){ Account account= new Account(); account.setMoney(money); account.setName(name); account.setId(id); int t= beetlSQLAccountDao.updateById(account); if (t== 1 ){ return account.toString(); } else { return "fail" ; } } @RequestMapping (value = "" ,method = RequestMethod.<em>POST</em>) public String postAccount( @RequestParam (value = "name" )String name, @RequestParam (value = "money" ) double money) { Account account = new Account(); account.setMoney(money); account.setName(name); KeyHolder t = beetlSQLAccountDao.insertReturnKey(account); if (t.getInt() > 0 ) { return account.toString(); } else { return "fail" ; } } }</account> |
注意:SpringBoot沒有提供BeetlSQL的@Transactional支持,需要自己添加事務的支持,上面被注釋的代碼中有編寫到
原文鏈接:https://www.2cto.com/database/201710/689056.html