SpringBoot的持久化层可以是Spring内置的轻量级JdbcTemplate、也可以是Hibernate或Mybatis等等,只需要在在工程pom.xml文件中添加对应的依赖就可以了。
新建工程我们能发现,SpringBoot对数据库操作的支持有以下几种:
可见SpringBoot对各种的支持还是挺多的。
入正题。看看对SQL的支持。主要选了比较传统/流行/有前景的4个进行操作:
均是采用mysql。
所以应该添加对mysql操作的依赖:
同时,需要对web进行支持,添加web相关依赖mysql mysql-connector-java runtime
org.springframework.boot spring-boot-starter-web
需要在application.properties中配置mysql相关信息(也可以使用*.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
实际应用的时候,需要添加数据库连接池,为了方便,就暂时不添加了。
org.springframework.boot spring-boot-starter-jdbc
目录结构如上,代码如下:
@Data public class Account { private int id ; private String name ; private double money; }这里是安装了一个插件,然后只需要添加如下依赖,添加@Data注解,就会帮我们自动生成getter和setter,也可以用@getter或@Setter注解进行标注。
<dependency>Dao层:org.projectlombok lombok 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(); }
@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后续也可以添加更多的操作,包括分页等等。这里主要就是jdbcTemplate的操作了,详情也可以查相关资料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; } }
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(); }
@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 ListController:findAccountList() { return accountDao.findAccountList(); } }
@RestController @RequestMapping("/jdbc/account") public class JdbcAccountController { @Autowired private IAccountService accountService; @RequestMapping(value = "/list",method = RequestMethod.GET) public List难度不大,只是简单的对数据库进行访问和修改,注意注解不要忘记标注了。getAccounts(){ return accountService.findAccountList(); } @RequestMapping(value = "/{id}",method = RequestMethod.GET) public Account getAccountById(@PathVariable("id") int id){ // return accountService.findAccountById(id); return accountService.selectAccountById(id); } @RequestMapping(value = "/{id}",method = RequestMethod.PUT) 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"; } } }
首先,也是需要添加相关的依赖
创建实体(注意注解) 在实体类注解 @Entity 就会自动进行表的 DDL 操作org.springframework.boot spring-boot-starter-data-jpa
@Data @Entity public class Account { @Id @GeneratedValue private int id ; @Column private String name ; private double money; }Dao层:这里只做了简单的演示,所以没有添加特殊的操作,直接继承jpa给我们提供的接口,就可以了,后续需要添加一些东西的话,可以添加对应的方法
public interface AccountDao extends JpaRepositoryController层:,Integer> { }
@RestController @RequestMapping("/jpa/account") public class JpaAccountController { @Autowired private AccountDao accountDao; @RequestMapping(value = "/list",method = RequestMethod.GET) public List总体来说,jpa代码很简洁,也很强大,能够实现一些常规的操作,对于开发者来说还是挺高效的,对于一些特殊的需求,也可以看官方给我们的文档,getAccounts(){ return accountDao.findAll(); } @RequestMapping(value = "/{id}",method = RequestMethod.GET) public Account getAccountById(@PathVariable("id") int id){ return accountDao.findOne(id); } @RequestMapping(value = "/{id}",method = RequestMethod.PUT) 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(); } }
网址:
http://docs.spring.io/spring-data/jpa/docs/1.10.2.RELEASE/reference/html/
添加依赖:
Mybatis可以采用两种方式进行编写,一种是基于xml的配置方式,一种是基于注解的方式,选择何种方式,当然是萝卜白菜啦,选最合适自己的。org.mybatis.spring.boot mybatis-spring-boot-starter 1.2.0
实体还是上一个例子的实体,这里就不添加了,dao层设计我们先来说一下用注解的方式:注解的方式相比下还是挺方便的,
@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(); }
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对应的Controller与上面的没有多大区别findAccountList() { return accountMapper.findAccountList(); } }
@RestController @RequestMapping("/mybatis/account") public class MybatisAccountController { @Autowired private MybatisAccountService mybatisAccountService; @RequestMapping(value = "/list", method = RequestMethod.GET) public ListgetAccounts() { return mybatisAccountService.findAccountList(); } @RequestMapping(value = "/{id}", method = RequestMethod.GET) public Account getAccountById(@PathVariable("id") int id) { return mybatisAccountService.findAccount(id); } @RequestMapping(value = "/{id}", method = RequestMethod.PUT) 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.DELETE) 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.POST) 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"; } } }
对比之下,我们再来看看基于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下创建一个mybaits文件夹,并添加xml,这里我们明明为AccountMapper.xml.,代码如下
xml version="1.0" encoding="UTF-8"?> mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">注意,命名空间那里,需要填自己的,简单的一个update,做完这几步,就可以了namespace="com.jinwen.www.MYBATIS.Dao.AccountMapper1"> id="update"> UPDATE account set money=#{money} WHERE id=#{id}
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;//测试事务回滚 accountMapper1.update(110,2); } }@Transactional注解可以实现事务回滚,当发生异常的时候,同样,对于jpa,jdbcTemplate也可以添加此注解进行事务处理。
Controller层(这里注意的是@MapperScan的注解,是实体的路径)
@RestController @RequestMapping("/mybatis/account") @MapperScan("com.jinwen.www.MYBATIS.Dao") public class MybatisAccountController1 { @Autowired private MybatisAccountService1 accountService; @RequestMapping(value = "/transfer", method = RequestMethod.GET) public void transfer(){ accountService.transfer(); } }mybatis更多复杂的操作可以想见相关的mybatis资料。
BeetlSQL 特点
BeetSql是一个全功能DAO工具, 同时具有Hibernate 优点 & Mybatis优点功能,适用于承认以SQL为中心,同时又需求工具能自动能生成大量常用的SQL的应用。
总体指标比起来,比mybatis更具备优势,或将成为未来的主流、
首先需要添加依赖
然后要在主方法类下进行配置(很关键,不然会报一些找不到的错误,或者一些奇怪的错误)com.ibeetl beetlsql 2.9.5
@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下创建这个文件夹
编写相关操作
实体:
@Data public class Account { private int id ; private String name ; private double money; }dao层:
@SqlResource("account") public interface BeetlSQLAccountDao extends BaseMapper@SqlResource注解就是在sql目录下对应的.md文件。如果是java.account则对应是sql目录下的java目录下的account.md文件。这个文件写有相关的对数据库的操作。{ // @SqlStatement(params = "name") Account selectAccountByName(String name); }
注意,这里继承的BaseMapper是由BeetlSQL提供的。
account.md 编写
selectAccountByName === *根据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.GET) public ListgetAccounts(){ return beetlSQLAccountDao.all(); } @RequestMapping(value = "/{id}",method = RequestMethod.GET) public Account getAccountById(@PathVariable("id") int id){ return beetlSQLAccountDao.unique(id); } @RequestMapping(value = "",method = RequestMethod.GET) public Account getAccountById(@RequestParam("name") String name){ return beetlSQLAccountDao.selectAccountByName(name); } @RequestMapping(value = "/{id}",method = RequestMethod.PUT) 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.POST) 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"; } } }
注意:SpringBoot没有提供BeetlSQL的@Transactional支持,需要自己添加事务的支持,上面被注释的代码中有编写到
(持续更新中。。。)