SpringBoot持久化層操作支持技巧
SpringBoot的持久化層可以是Spring內(nèi)置的輕量級JdbcTemplate、也可以是Hibernate或Mybatis等等,只需要在在工程pom.xml文件中添加對應(yīng)的依賴就可以了。
新建工程我們能發(fā)現(xiàn),SpringBoot對數(shù)據(jù)庫操作的支持有以下幾種:


可見SpringBoot對各種的支持還是挺多的。
入正題??纯磳QL的支持。主要選了比較傳統(tǒng)/流行/有前景的4個進行操作:
均是采用mysql。
所以應(yīng)該添加對mysql操作的依賴:
<!--MySQL--> <dependency> <groupid>mysql</groupid> mysql-connector-java</artifactid> <scope>runtime</scope> </dependency>
同時,需要對web進行支持,添加web相關(guān)依賴
<!--web支持--> <dependency> <groupid>org.springframework.boot</groupid> spring-boot-starter-web</artifactid> </dependency>
需要在application.properties中配置mysql相關(guān)信息(也可以使用*.yml)。配置如下:
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
實際應(yīng)用的時候,需要添加數(shù)據(jù)庫連接池,為了方便,就暫時不添加了。
1. SpringBoot用JdbcTemplates訪問Mysql
首先需要添加對JdbcTemplates的依賴,可以在新建工程中點擊添加,或手動添加
<!--JDBC支持--> <dependency> <groupid>org.springframework.boot</groupid> spring-boot-starter-jdbc</artifactid> </dependency>

目錄結(jié)構(gòu)如上,代碼如下:
@Data
public class Account {
private int id ;
private String name ;
private double money;
}
這里是安裝了一個插件,然后只需要添加如下依賴,添加@Data注解,就會幫我們自動生成getter和setter,也可以用@getter或@Setter注解進行標(biāo)注。
<dependency> <groupid>org.projectlombok</groupid> lombok</artifactid> </dependency>
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>
實現(xiàn)類:
@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的操作了,詳情也可以查相關(guān)資料
Service層:
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>
實現(xiàn)
@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:
@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>
難度不大,只是簡單的對數(shù)據(jù)庫進行訪問和修改,注意注解不要忘記標(biāo)注了。
2.SpringBoot 整合JPA
Jpa算是比較方便的,用起來只需注意相關(guān)規(guī)則就可以了,不管jpa還是mybatis,都是有各自優(yōu)點的,在那里使用方便,就采用哪個,沒好壞之分。
首先,也是需要添加相關(guān)的依賴
<!--JPA支持--> <dependency> <groupid>org.springframework.boot</groupid> spring-boot-starter-data-jpa</artifactid> </dependency>
創(chuàng)建實體(注意注解)
Dao層:這里只做了簡單的演示,所以沒有添加特殊的操作,直接繼承jpa給我們提供的接口,就可以了,后續(xù)需要添加一些東西的話,可以添加對應(yīng)的方法
public interface AccountDao extends JpaRepository {
}</account,integer>
Controller層:
@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代碼很簡潔,也很強大,能夠?qū)崿F(xiàn)一些常規(guī)的操作,對于開發(fā)者來說還是挺高效的,對于一些特殊的需求,也可以看官方給我們的文檔,3.springboot整合mybatisMybatis在現(xiàn)在也是一個非常流行的持久化層框架了,和Hibernate比起來,可以自己編寫sql語句,從而利用高效的sql語句制作好的產(chǎn)品。但缺點也是在編寫sql語句,這方面有點花時間,相比jpa來說。入正題:
添加依賴:
<!--MyBatis支持--> <dependency> <groupid>org.mybatis.spring.boot</groupid> mybatis-spring-boot-starter</artifactid> <version>1.2.0</version> </dependency>
Mybatis可以采用兩種方式進行編寫,一種是基于xml的配置方式,一種是基于注解的方式,選擇何種方式,當(dāng)然是蘿卜白菜啦,選最合適自己的。
實體還是上一個例子的實體,這里就不添加了,dao層設(shè)計我們先來說一下用注解的方式:注解的方式相比下還是挺方便的,
@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>
注解單詞簡單明了,就不解釋了,但要注意的是,方法名稱也要適當(dāng)?shù)娜『?,不然以后對?shù)據(jù)庫操作多了,有可能會亂,需要不斷回來看代碼。
Service層:
@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>
對應(yīng)的Controller與上面的沒有多大區(qū)別
@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的配置方式。(偷懶就只做一個了)
public interface AccountMapper1 {
int update(@Param("money") double money, @Param("id") int id);
}
首先需要寫一個接口,然后在application中添加配置
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.,代碼如下
<!--?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層:
@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;//測試事務(wù)回滾
accountMapper1.update(110,2);
}
}
@Transactional注解可以實現(xiàn)事務(wù)回滾,當(dāng)發(fā)生異常的時候,同樣,對于jpa,jdbcTemplate也可以添加此注解進行事務(wù)處理。
Controller層(這里注意的是@MapperScan的注解,是實體的路徑)
@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更多復(fù)雜的操作可以想見相關(guān)的mybatis資料。4.springboot整合 BeetlSQL
BeetlSQL 特點
BeetSql是一個全功能DAO工具, 同時具有Hibernate 優(yōu)點 & Mybatis優(yōu)點功能,適用于承認以SQL為中心,同時又需求工具能自動能生成大量常用的SQL的應(yīng)用。
開發(fā)效率無需注解,自動使用大量內(nèi)置SQL,輕易完成增刪改查功能,節(jié)省50%的開發(fā)工作量數(shù)據(jù)模型支持Pojo,也支持Map/List這種快速模型,也支持混合模型SQL 模板基于Beetl實現(xiàn),更容易寫和調(diào)試,以及擴展可以針對單個表(或者視圖)代碼生成pojo類和sql模版,甚至是整個數(shù)據(jù)庫。能減少代碼編寫工作量維護性SQL 以更簡潔的方式,Markdown方式集中管理,同時方便程序開發(fā)和數(shù)據(jù)庫SQL調(diào)試。可以自動將sql文件映射為dao接口類靈活直觀的支持支持一對一,一對多,多對多關(guān)系映射而不引入復(fù)雜的OR Mapping概念和技術(shù)。具備Interceptor功能,可以調(diào)試,性能診斷SQL,以及擴展其他功能其他內(nèi)置支持主從數(shù)據(jù)庫支持的開源工具支持跨數(shù)據(jù)庫平臺,開發(fā)者所需工作減少到最小,目前跨數(shù)據(jù)庫支持mysql,postgres,oracle,sqlserver,h2,sqllite,DB2. 以上來自beatlSql官網(wǎng)文檔。網(wǎng)址:https://ibeetl.com/guide/#beetlsql
總體指標(biāo)比起來,比mybatis更具備優(yōu)勢,或?qū)⒊蔀槲磥淼闹髁鳌?/p>
首先需要添加依賴
<!--beetlsql支持--> <groupid>com.ibeetl</groupid> beetlsql</artifactid> <version>2.9.5</version>
然后要在主方法類下進行配置(很關(guān)鍵,不然會報一些找不到的錯誤,或者一些奇怪的錯誤)
@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;
}
//配置數(shù)據(jù)庫
@Bean(name = "datasource")
public DataSource getDataSource() {
return DataSourceBuilder.create().url("jdbc:mysql://localhost:3306/springboottest").username("root").password("root").build();
}
// //開啟事務(wù)
// @Bean(name = "txManager")
// public DataSourceTransactionManager getDataSourceTransactionManager(@Qualifier("datasource") DataSource datasource) {
// DataSourceTransactionManager dsm = new DataSourceTransactionManager();
// dsm.setDataSource(datasource);
// return dsm;
// }
}
注意這里的配置包掃描,需要掃描自己的包,不然會包no find
根據(jù)配置,編寫的“sql”代碼將在sql路徑下,需要在resources下創(chuàng)建這個文件夾
編寫相關(guān)操作
實體:
@Data
public class Account {
private int id ;
private String name ;
private double money;
}
dao層:
@SqlResource("account")
public interface BeetlSQLAccountDao extends BaseMapper {
// @SqlStatement(params = "name")
Account selectAccountByName(String name);
}
</account>
@SqlResource注解就是在sql目錄下對應(yīng)的.md文件。如果是java.account則對應(yīng)是sql目錄下的java目錄下的account.md文件。這個文件寫有相關(guān)的對數(shù)據(jù)庫的操作。
注意,這里繼承的BaseMapper是由BeetlSQL提供的。
account.md 編寫
<em>selectAccountByName </em><em>=== </em>*根據(jù)name獲account select * from account where name= #name#
Controller層:
@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支持,需要自己添加事務(wù)的支持,上面被注釋的代碼中有編寫到
相關(guān)文章
elasticsearch集群cluster主要功能詳細分析
這篇文章主要為大家介紹了elasticsearch集群cluster主要功能詳細分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2022-04-04
Spring實現(xiàn)資源的動態(tài)加載和卸載的方法小結(jié)
這篇文章主要介紹了Spring實現(xiàn)資源的動態(tài)加載和卸載的方法小結(jié),文中通過代碼示例講解的非常詳細,對大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2024-06-06
Maven打包沒有指定主類問題(xxx.jar中沒有主清單屬性)
這篇文章主要介紹了Maven打包沒有指定主類問題(xxx.jar中沒有主清單屬性),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-04-04
java Apache poi 對word doc文件進行讀寫操作
這篇文章主要介紹了Apache poi 對word doc文件進行讀寫操作的相關(guān)資料,需要的朋友可以參考下2017-01-01
配置idea將Java與數(shù)據(jù)庫連接起來實現(xiàn)一個簡單的圖書管理系統(tǒng)
這篇文章主要給大家介紹了關(guān)于配置idea將Java與數(shù)據(jù)庫連接起來實現(xiàn)一個簡單的圖書管理系統(tǒng)的相關(guān)資料,本文從基于Java的圖書管理系統(tǒng)的背景、系統(tǒng)設(shè)計、數(shù)據(jù)庫設(shè)計和系統(tǒng)實現(xiàn)等方面進行了詳細的研究,需要的朋友可以參考下2023-12-12
SpringBoot?@InitBinder注解綁定請求參數(shù)的過程詳解
這篇文章主要介紹了SpringBoot?@InitBinder注解綁定請求參數(shù),本文給大家介紹的非常詳細,對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-04-04
Java全面細致講解Cookie與Session及kaptcha驗證碼的使用
web開發(fā)階段我們主要是瀏覽器和服務(wù)器之間來進行交互。瀏覽器和服務(wù)器之間的交互就像人和人之間進行交流一樣,但是對于機器來說,在一次請求之間只是會攜帶著本次請求的數(shù)據(jù)的,但是可能多次請求之間是會有聯(lián)系的,所以提供了會話機制2022-06-06
SSH框架網(wǎng)上商城項目第20戰(zhàn)之在線支付平臺
這篇文章主要為大家詳細介紹了SSH框架網(wǎng)上商城項目第20戰(zhàn)之在線支付平臺,關(guān)于第三方支付的內(nèi)容從本文開始,感興趣的小伙伴們可以參考一下2016-06-06
SpringBoot之HandlerInterceptor攔截器的使用詳解
這篇文章主要介紹了SpringBoot之HandlerInterceptor攔截器的使用詳解,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-10-10

