上一篇我们讲述了springboot和各种常见的数据库连接池融合,此篇将讲述 一下springboot与各种常见的持久层框架融合。
这里简单描述一下连接池与持久层框架的区别,连接池是简化了我们的程序
连接数据库操作,而持久层框架更多的关注将编程语言映射成sql结构化语言,
两者协同操作,并且后者依赖于前者。常见的持久层框架有jpa,mybatis,dbUtils,jooq以及spring自带的jdbcTemplate,接下来我们将一一实现springboot与之融合并完成简单的数据库交互。
springboot&jpa
JPA是Java Persistence API的简称,中文名Java持久层API,是JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。其优点是用户不用关心操作的sql实现,缺点就是开发人员离sql太遥远,对一些复杂的操作不太好实现。
1.引入jpa依赖
我们使用druid连接池,此处除了要引入jpa依赖,还要添加druid和mysql驱动依赖:
<!-- druid数据库连接池 -->
<!-- jpa -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
</dependency>
<!-- mysql connector -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2.添加数据库连接属性配置
数据库连接属性配置文件druid.properties:
#数据库设置
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&autoReconnect=true&useSSL=true
spring.datasource.username=username
spring.datasource.password=password
3.数据库连接配置类
使用@Configuration注解类替代传统的xml配置,DruidConfiguration:
@Configuration
@PropertySource(value = "classpath:druid.properties")
public class DruidConfiguration {
@Bean(destroyMethod = "close", initMethod = "init",name = "druidDataSource")
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource druidDataSource() {
DruidDataSource druidDataSource = new DruidDataSource();
return druidDataSource;
}
}
到这里我们的数据源DataSource已经配置好了。
4.编写jpa接口
首先编写entity:
@Entity
@Table( name = "User")
@Setter
@Getter
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id; // 主键ID
private String name; // 姓名
@Column(name = "createTime")
private Date createTime;
private Integer sex;
private Integer age;
}
由于我们数据库中表名是驼峰命名法,所以jpa默认的命名方式无法解析映射,在主属性配置文件application.properties中添加内容:
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
不使用默认的命名策略。
然后编写jpa接口:
@Repository
public interface UserRepository extends CrudRepository<User,Long> {
}
只需要继承CrudRepository就能满足我们基本的crud操作。
5.编写测试代码&测试
为了测试方便不再写service层代码,直接controller操作dao:
/**
* @author shuya | dongfeng.zdf@alibaba-inc.com
* @description
* @date 2018/10/10 下午7:50
* @description
* @modified by
* @since V2.0.0
*/
@RestController
@RequestMapping("/user")
public class IndexController {
@Autowired
private UserRepository userRepository;
@GetMapping("/jpa/list")
private Object list() {
return this.userRepository.findAll();
}
}
运行门面类App启动应用,然后浏览器输入http://localhost:8080/user/jpa/list看到如下结果:
查询到了数据,说明我们已经通过jpa完成了数据库操作。
springboot&mybatis
springboot融合mybatis实现由两种方式,一种是基于mapper.xml,另外一种是基于@Mapper配置,此处鉴于我们使用springboot尽量少使用配置文件的原则,选择第二种基于注解的方式。
1.引入mybatis依赖
前边已经引入了druid和mysql驱动,后续不在重复引入和赘述。
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
</dependency>
2.编写mapper接口
继续使用前边配置的druid数据源,这里不用再配置:
@Mapper
public interface UserDao {
@Select(value = "select * from User")
public List<User> findAll();
}
3.编写测试代码&测试
/**
* @author shuya | dongfeng.zdf@alibaba-inc.com
* @description
* @date 2018/10/10 下午7:50
* @description
* @modified by
* @since V2.0.0
*/
@RestController
@RequestMapping("/user")
public class IndexController {
@Autowired
private UserDao userDao;
@GetMapping("/mybatis/list")
private Object mybatis() {
return this.userDao.findAll();
}
}
运行门面类App启动应用,然后浏览器输入http://localhost:8080/user/mybatis/list看到如下结果:
查询到了数据,说明我们已经通过mybatis完成了数据库操作。
springboot&jdbcTemplate
jdbcTemplate是spring自带的jdbc操作框架,其封装提供了更原生更接近数据库的操作,对于一些轻便型的项目,如果不想因如果过多框架导致应用变得太笨重,使用jdbcTemplate也是一种不错的选择。
1.引入jdbc依赖
<!-- jdbcTemplate -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
2.编写dao
引入jdbc后,使用jdbcTemplate时,如果不需要动态切换数据源,直接使用@Autowired就能注入了,不需要主动配置暴露bean。
@Repository
public class User2Dao {
@Autowired
private JdbcTemplate jdbcTemplate;
public List<User> findAll() {
return this.jdbcTemplate.query("select * from User", BeanPropertyRowMapper.newInstance(User.class));
}
}
3.编写测试代码&测试
/**
* @author shuya | dongfeng.zdf@alibaba-inc.com
* @description
* @date 2018/10/10 下午7:50
* @description
* @modified by
* @since V2.0.0
*/
@RestController
@RequestMapping("/user")
public class IndexController {
@Autowired
private User2Dao user2Dao;
@GetMapping("/jdbctemplate/list")
private Object jdbcTemplateList() {
return this.user2Dao.findAll();
}
}
运行门面类App启动应用,然后浏览器输入http://localhost:8080/user/jdbctemplate/list看到如下结果:
查询到了数据,说明我们已经通过jdbcTemplate完成了数据库操作。
springboot&dbUtils
dbUtils是apache提供的一个开源的轻量级的jdbc操作工具,翻阅过其源码,其实现原理与jdbcTemplate大同小异。
1.引入dbUtils依赖
<dependency>
<groupId>commons-dbutils</groupId>
<artifactId>commons-dbutils</artifactId>
</dependency>
2.编写dbUtils配置类
dbUtils与数据库的操作通过核心类QueryRunner实现,将数据源注入QueryRunner并暴露bean:
@Configuration
public class DbUtilsConfiguration {
@Bean
public QueryRunner queryRunner(@Qualifier("dataSource") DataSource dataSource) {
QueryRunner queryRunner = new QueryRunner(dataSource);
return queryRunner;
}
}
3.编写dao
@Repository
public class User3Dao {
@Autowired
private QueryRunner queryRunner;
public List<User> findAll() {
List<User> list = null;
try {
list = this.queryRunner.query("select * from User",new BeanListHandler<>(User.class));
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
}
4.编写测试代码&测试
/**
* @author shuya | dongfeng.zdf@alibaba-inc.com
* @description
* @date 2018/10/10 下午7:50
* @description
* @modified by
* @since V2.0.0
*/
@RestController
@RequestMapping("/user")
public class IndexController {
@Autowired
private User3Dao user3Dao;
@GetMapping("/dbutils/list")
private Object dbUtilsList() {
return this.user3Dao.findAll();
}
}
运行门面类App启动应用,然后浏览器输入http://localhost:8080/user/dbutils/list看到如下结果:
查询到了数据,说明我们已经通过dbUtils完成了数据库操作。
springboot&jooq
JOOQ被称为"ORM"大杀器, 是基于Java访问关系型数据库的工具包,轻量,简单,并且足够灵活,可以轻松的使用Java面向对象语法来实现各种复杂的sql。JOOQ 既吸取了传统ORM操作数据的简单性和安全性,又保留了原生sql的灵活性,它更像是介于 ORMS和JDBC的中间层。对于喜欢写sql的码农来说,JOOQ可以完全满足你控制欲,可以是用Java代码写出sql的感觉来。
1.引入jooq依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
2.编写jooq配置类
jooq中与数据库交互的核心类是DSLContext,将数据源注入DSLContext并暴露bean:
@Configuration
public class JooqConfiguration {
@Bean
public DSLContext dslContext(@Qualifier("dataSource") DataSource dataSource) {
TransactionAwareDataSourceProxy proxy = new TransactionAwareDataSourceProxy(dataSource);
DataSourceTransactionManager txMgr = new DataSourceTransactionManager(dataSource);
org.jooq.Configuration configuration = new DefaultConfiguration().set(new DataSourceConnectionProvider(proxy))
.set(new SpringTransactionProvider(txMgr)).set(SQLDialect.MYSQL);
return DSL.using(configuration);
}
}
3.编写dao类
@Repository
public class User4Dao {
@Autowired
private DSLContext dslContext;
public List<User> findAll() {
List<User> list = this.dslContext.select()
.from("User")
.fetch()
.map(record -> record.into(User.class));
return list;
}
}
从dao编写中我们能够明显感觉到,查询语句我们完全是用java语法模拟mysql语法。
4.编写测试代码&测试
/**
* @author shuya | dongfeng.zdf@alibaba-inc.com
* @description
* @date 2018/10/10 下午7:50
* @description
* @modified by
* @since V2.0.0
*/
@RestController
@RequestMapping("/user")
public class IndexController {
@Autowired
private User4Dao user4Dao;
@GetMapping("/jooq/list")
private Object jooqList() {
return this.user4Dao.findAll();
}
}
运行门面类App启动应用,然后浏览器输入http://localhost:8080/user/jooq/list看到如下结果:
查询到了数据,说明我们已经通过jooq完成了数据库操作。
总结
经过上边一系列描述,我们实现了springboot与各种持久层框架的融合,并且简单的介绍了其差异和各自的优缺点以及使用场景,大致可以归为三类:
1.偏向原生操作
dbUtils和jdbcTemplate偏向原生sql操作,使用更灵活,更轻便。mybatis也可归为此类,但是有时候需要引入更多配置。
2.偏向自动化操作
jpa更好的封装了底层sql操作,对上层开发者透明,对于一些简单的操作场景效率特别高,但是对于一些复杂的操作和场景还是需要自己实现。
3.偏向敏捷操作
jooq使用java编程语言模拟了mysql操作,开发人员使用jooq写出来的java代码更像是sql语言。
本文分享自 PersistentCoder 微信公众号,前往查看
如有侵权,请联系 cloudcommunity@tencent.com 删除。
本文参与 腾讯云自媒体同步曝光计划 ,欢迎热爱写作的你一起参与!