java spring boot 和数据库boot 数据库用哪个好

Spring Boot:在Spring Boot中使用Mysql和JPA - 推酷
Spring Boot:在Spring Boot中使用Mysql和JPA
本文向你展示如何在Spring Boot的Web应用中使用Mysq数据库,也充分展示Spring Boot的优势(尽可能少的代码和配置)。数据访问层我们将使用Spring Data JPA和Hibernate(JPA的实现之一)。
1.Maven pom.xml文件
在你的项目中增加如下依赖文件
&dependencies&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-web&/artifactId&
&/dependency&
&dependency&
&groupId&org.springframework.boot&/groupId&
&artifactId&spring-boot-starter-data-jpa&/artifactId&
&/dependency&
&dependency&
&groupId&mysql&/groupId&
&artifactId&mysql-connector-java&/artifactId&
&/dependency&&/dependencies&
2.属性配置文件application.properties
在src/main/resources/application.properties中设置数据源和jpa配置。
spring.datasource.url = jdbc:mysql://localhost:3306/testspring.datasource.username = rootspring.datasource.password = rootspring.datasource.driverClassName = com.mysql.jdbc.Driver# Specify the DBMSspring.jpa.database = MYSQL# Show or not log for each sql queryspring.jpa.show-sql = true# Hibernate ddl auto (create, create-drop, update)spring.jpa.hibernate.ddl-auto = update# Naming strategyspring.jpa.hibernate.naming-strategy = org.hibernate.cfg.ImprovedNamingStrategy# stripped before adding them to the entity manager)spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL5Dialect
全部的配置都在如上的文件中了,不需要另外的XML配置和Java配置。
上文中的数据库配置,你需要换成你的数据库的地址和用户名密码。
hibernate的ddl-auto=update配置表名,数据库的表和列会自动创建(根据Java实体的熟悉),
可以看到更多得hibernate配置。
3.User实体
创建一个User实体,User包含三个属性id,email和name。User实体和Mysql数据库的users表相对应。
@Entity@Table(name = &users&)public class User {
// ==============
// PRIVATE FIELDS
// ==============
// An autogenerated id (unique for each user in the db)
@GeneratedValue(strategy = GenerationType.AUTO)
// The user email
// The user name
// ==============
// PUBLIC METHODS
// ==============
public User() { }
public User(long id) {
// Getter and setter methods
// ...} // class User
4.User实体的数据访问层UserDao
本例中UserDao非常简单,只需要继承CrudRespositroy即可,CrudRespositroy已经实现了save,delete,deleteAll,findOne和findAll.
(比较神奇的时这些方法其实CrudRespositroy中其实并没有实现,并且通过对dao方法的命名还可以实现新的方法)
@Transactionalpublic interface UserDao extends CrudRepository&User, Long& {
public User findByEmail(String email);}
5.测试的控制器UserController
新建一个查询控制器UserController
@Controllerpublic class UserController {
@RequestMapping(&/get-by-email&)
@ResponseBody
public String getByEmail(String email) {
String userId;
User user = userDao.findByEmail(email);
if (user != null) {
userId = String.valueOf(user.getId());
return &The user id is: & + userId;
return &user & + email + & is not exist.&;
你可以使用浏览器访问url
http://127.0.0.1:8080/get-by-email?email=
,可以获得用户的Id(你可以先在Mysql数据库中新增一条记录)。
已发表评论数()
请填写推刊名
描述不能大于100个字符!
权限设置: 公开
仅自己可见
正文不准确
标题不准确
排版有问题
主题不准确
没有分页内容
图片无法显示
视频无法显示
与原文不一致引言&近期开发的几个项目,均是基于Spring boot框架的web后端项目,使用JdbcTemplate执行数据库操作,实际开发过程中,掌握了一些有效的开发经验,踩过一些坑,在此做个记录及总结,与各位读者分享。欢迎留言与我交流。正确使用JdbcTemplate执行数据库操作&1、Bean声明&新增类型DatabaseConfiguration,添加注解@Configuration该类型用于DataSource及JdbcTempate Bean的声明&基础代码如下&@Configurationclass DatabaseConfiguration {& & @Bean& & public DataSource dataSource() {& & & & DataSource dataS& & & & ...& & & & return dataS& & }&& & @Bean& & public JdbcTemplate jdbcTemplate() {& & & & return new JdbcTemplate(dataSource());& & }}&注意这里将DataSource定义为Bean,Spring boot默认创建的TransactionManager对象依赖DataSource,若未将DataSource声明为Bean,则无法使用数据库事务&2、封装Dao类型&对于每一个数据库表,构建独立的Dao类型,提供供业务层调用的接口,注入JdbcTemplate对象,以实际操作db可以定义基类如下&/**&* Created by Ant on .&*/public abstract class AntSoftDaoBase {& & @Resource(name = &jdbcTemplate&)& & private JdbcTemplate jdbcT&& & private String tableN&& & protected AntSoftDaoBase(String tableName) {& & & & this.tableName = tableN& & }&& & protected JdbcTemplate getJdbcTemplate() {& & & & return jdbcT& & }&& & public void clearAll() {& & & & getJdbcTemplate().update(&DELETE FROM & + tableName);& & }&& & public int count() {& & & & return getJdbcTemplate().queryForObject( &SELECT count(*) FROM & + tableName, Integer.class);& & }}&&通过@Resource注入jdbcTemplate对象,由于我仅定义了一个jdbcTemplate bean,可以这里可以省略掉name参数,及@Resource即可,或者使用@Autowired&如对于数据库中的table app&&&/**&* Created by Ant on .&*/@Repositorypublic class AppDao extends AntSoftDaoBase{& & private Logger logger = LoggerFactory.getLogger(getClass());&& & private static final String TABLE_NAME = &app&;&& & private static final String COLUMN_NAMES = &name, user_id, title, description, ctime, status&;&& & public AppDao() {& & & & super(TABLE_NAME);& & }&& & public int create(final AppInfo appInfo) {& & & &...& & }&& & public List&AppInfo& list(int pageNo, int pageSize) {& & & & ...& & }&& & public AppInfo get(int appId) {& & & &...& & }&& & public void update(AppInfo appInfo) {& & & & ...& & }}&&该Dao类型提供了对AppInfo数据的增删查改接口,对这些接口的具体实现,后面再进行详细介绍&&&&3、使用Tomcat-jdbc数据库连接池&引入数据库连接池,将大幅度提升数据库操作性能本例描述Tomcat-jdbc数据库连接池使用方式Pom文件中引入tomcat-jdbc依赖项& & & & &dependency&& & & & & & &groupId&org.apache.tomcat&/groupId&& & & & & & &artifactId&tomcat-jdbc&/artifactId&& & & & & & &version&7.0.42&/version&& & & & &/dependency&&创建连接池DataSource的逻辑封装在如下方法中,DatabaseConfiguration.dataSource方法内部可以直接调用此方法获取具备连接池功能的DataSource&& & private DataSource getTomcatPoolingDataSource(String databaseUrl, String userName, String password) {& & & & org.apache.tomcat.jdbc.pool.DataSource dataSource = new org.apache.tomcat.jdbc.pool.DataSource();& & & & dataSource.setDriverClassName(&com.mysql.jdbc.Driver&);& & & & dataSource.setUrl(databaseUrl);& & & & dataSource.setUsername(userName);& & & & dataSource.setPassword(password);&& & & & dataSource.setInitialSize(5); // 连接池启动时创建的初始化连接数量(默认值为0)& & & & dataSource.setMaxActive(20); // 连接池中可同时连接的最大的连接数& & & & dataSource.setMaxIdle(12); // 连接池中最大的空闲的连接数,超过的空闲连接将被释放,如果设置为负数表示不限& & & & dataSource.setMinIdle(0); // 连接池中最小的空闲的连接数,低于这个数量会被创建新的连接& & & & dataSource.setMaxWait(60000); // 最大等待时间,当没有可用连接时,连接池等待连接释放的最大时间,超过该时间限制会抛出异常,如果设置-1表示无限等待& & & & dataSource.setRemoveAbandonedTimeout(180); // 超过时间限制,回收没有用(废弃)的连接& & & & dataSource.setRemoveAbandoned(true); // 超过removeAbandonedTimeout时间后,是否进 行没用连接(废弃)的回收& & & & dataSource.setTestOnBorrow(true);& & & & dataSource.setTestOnReturn(true);& & & & dataSource.setTestWhileIdle(true);& & & & dataSource.setValidationQuery(&SELECT 1&);& & & & dataSource.setTimeBetweenEvictionRunsMillis(1000 * 60 * 30); // 检查无效连接的时间间隔 设为30分钟& & & & return dataS& & }&关于各数值的配置请根据实际情况调整&配置重连逻辑,以在连接失效是进行自动重连。默认情况下mysql数据库将关闭掉超过8小时的连接,开发的第一个java后端项目,加入数据库连接池后的几天早晨,web平台前几次数据库操作总是失败,配置重连逻辑即可解决&&&使用HSQL进行数据库操作单元测试&忠告:数据库操作需要有单元测试覆盖本人给出如下理由:1、对于使用JdbcTemplate,需要直接在代码中键入sql语句,如今编辑器似乎还做不到对于java代码中嵌入的sql语句做拼写提示,经验老道的高手,拼错sql也不罕见2、更新db表结构后,希望快速知道哪些代码需要更改,跑一便单测比人肉搜索来的要快。重构速度*103、有单测保证后,几乎可以认为Dao层完全可靠。程序出错,仅需在业务层排查原因。Debug速度*104、没有单测,则需要在集成测试时构建更多更全面的测试数据,实际向mysql中插入数据。数据构建及维护麻烦、测试周期长1、内嵌数据库HSQLDB&HSQLDB是一个开放源代码的JAVA数据库,其具有标准的SQL语法和JAVA接口a)配置HSQL DataSource&引入HSQLDB依赖项& & & & &dependency&& & & & & & &groupId&org.hsqldb&/groupId&& & & & & & &artifactId&hsqldb&/artifactId&& & & & & & &version&2.3.0&/version&& & & & &/dependency&生成DataSource的方法可以如下方式实现&& & @Bean& & public DataSource antsoftDataSource() {& & & & DataSource dataS& & & & if (antsoftDatabaseIsEmbedded) {& & & & & & dataSource = getEmbeddedHsqlDataSource();& & & & } else {& & & & & & dataSource =& & & & & & & & & & getTomcatPoolingDataSource(antsoftDatabaseUrl, antsoftDatabaseUsername, antsoftDatabasePassword);& & & & }& & & & return dataS& & }&其中antsoftDatabaseIsEmbedded等对象字段值的定义如下&&& & @Value(&${antsoft.database.isEmbedded}&)& & private boolean antsoftDatabaseIsE&& & @Value(&${antsoft.database.url}&)& & private String antsoftDatabaseU&& & @Value(&${antsoft.database.username}&)& & private String antsoftDatabaseU&& & @Value(&${antsoft.database.password}&)& & private String antsoftDatabaseP&通过@Value指定配置项key名称,运行时通过key查找配置值替换相应字段&配置文件为resources/application.properties&antsoft.database.isEmbedded=falseantsoft.database.url=jdbc:mysql://127.0.0.1:3306/antsoft_appantsoft.database.username=rootantsoft.database.password=ant单元测试配置文件为resources/application-test.properties&antsoft.database.isEmbedded=true表示单测使用内嵌数据库&b)HSQL数据库初始化脚本&创建Hsql DataSource时,同时执行数据库初始化操作,构建所需的表结构,插入初始数据getEmbeddedHsqlDataSource方法实现如下& & private DataSource getEmbeddedHsqlDataSource() {& & & & log.debug(&create embeddedDatabase HSQL&);& & & & return new EmbeddedDatabaseBuilder().setType(EmbeddedDatabaseType.HSQL).addScript(&classpath:db/hsql_init.sql&).build();& & }通过addScript指定初始化数据库SQL脚本resources/db/hsql_init.sql,内容如下&SET DATABASE SQL SYNTAX MYS TRUE;&CREATE TABLE app (& id int GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL,& name varchar(64) NOT NULL,& user_id varchar(64) NOT NULL,& title varchar(64) NOT NULL,& description varchar(1024) NOT NULL,& ctime datetime NOT NULL,& status int NOT NULL,& PRIMARY KEY (id),& UNIQUE (name));&CREATE TABLE app_unique_name (& id int GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL,& unique_name varchar(64) NOT NULL UNIQUE,& PRIMARY KEY (id));&...&HSQL语法与MySql语法存在差异,使用是需注意,我在开发过程中注意到的不同点列举如下&  - 不支持tinyint等数据类型,int后不允许附带表示数据长度的括号,如不支持int(11)&  - 不支持index索引,但支持unique index&  - 不支持AUTO_INCREMENT语法&c)验证你的HSQL脚本&可采用如下方式验证hsql语句正确性&在本地maven仓库中找到hsqldb(正确引入过hsqldb),博主本机目录 C:/Users/ant/.m2/repository/org/hsqldb/hsqldb/2.3.2&执行hsqldb-2.3.2.jar &(java -jar hsqldb-2.3.2.jar)&默认窗体一个提示框,点击ok。在右侧输入SQL语句,执行工具栏中中Execuete SQL&&&&上图SQL语句如下&CREATE TABLE app_message (& id bigint GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) NOT NULL,& app_id int NOT NULL,& message varchar(1024) NOT NULL,& ctime datetime NOT NULL,& status int NOT NULL,& PRIMARY KEY (id));&该SQL语句中使用 &GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1) &替代 AUTO_INCREMENT,似乎是HSQL不支持该语法,读者亲自尝试一下AUTO_INCREMENT替代方案来源如下/questions//create-table-syntax-not-working-in-hsql&2、编写单元测试覆盖Dao数据库操作&使用JUnit及Spring-test。单测可以直接注入所需的Bean统一定义单元测试注解复制代码@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.TYPE)@SpringApplicationConfiguration(classes = Application.class)@WebAppConfiguration@IntegrationTest(&server.port=0&)@ActiveProfiles(&test&)public @interface AntSoftIntegrationTest {}&定义测试类型,添加如下注解&@AntSoftIntegrationTest@RunWith(SpringJUnit4ClassRunner.class)我对自己代码的期望是,尽可能100%的Dao方法都被单元测试覆盖。&以下代码演示对AppService(其接口实现转发调用AppDao相应接口)进行的基本单元测试,其中测试了create、update及get三种操作&&@AntSoftIntegrationTest@RunWith(SpringJUnit4ClassRunner.class)public class AppServiceTests {& & @Autowired& & private AppService appS&& & @Autowired& & private TestService testS&& & @Before& & public void clearApp() {& & & & testService.clearApp();& & }&& & @Test& & public void testApp() {& & & & final String name = &xxx&;& & & & final String userId = &Ant&;& & & & final String title = &Hello World&;& & & & final String description = &Description for Hello World&;&& & & & final String updatedName = &xxx&;& & & & final String updatedUserId = &Ant&;& & & & final String updatedTitle = &Hello World&;& & & & final String updatedDescription = &Description for Hello World&;&& & & & int appId;& & & & {& & & & & & // 创建应用& & & & & & AppInfo appInfo = new AppInfo();& & & & & & appInfo.setName(name);& & & & & & appInfo.setUserId(userId);& & & & & & appInfo.setTitle(title);& & & & & & appInfo.setDescription(description);& & & & & & appId = appService.createApp(appInfo);& & & & }&& & & & CheckAppInfo(appId, name, userId, title, description, AppStatus.NORMAL);&& & & & {& & & & & & // 更新应用& & & & & & AppInfo appInfo = new AppInfo();& & & & & & appInfo.setId(appId);& & & & & & appInfo.setName(updatedName);& & & & & & appInfo.setUserId(updatedUserId);& & & & & & appInfo.setTitle(updatedTitle);& & & & & & appInfo.setDescription(updatedDescription);& & & & & & appService.updateApp(appInfo);& & & & }&& & & & CheckAppInfo(appId, updatedName, updatedUserId, updatedTitle, updatedDescription, AppStatus.NORMAL);& & }&& & // 获取应用,并验证数据& & private void CheckAppInfo(int appId, String name, String userId, String title, String description,& & & & & & & & & & & & & & & AppStatus appStatus) {& & & & AppInfo appInfo = appService.getApp(appId);& & & & assertEquals(appId, appInfo.getId());& & & & assertEquals(name, appInfo.getName());& & & & assertEquals(userId, appInfo.getUserId());& & & & assertEquals(title, appInfo.getTitle());& & & & assertEquals(description, appInfo.getDescription());& & & & assertEquals(appStatus, appInfo.getStatus());& & }}&&&&开发经验分享&本节记录笔者在实际项目开发过程中遇到的问题及解决方法、以及一些良好的开发实践1、失效的事务&在使用Spring提供的事务处理机制时,事务的start与commit rollback操作由TransactionManager对象维护,开发中,我们只需在需要进行事务处理的方法上添加@Transactional注解,即可轻松开启事务&见Spring boot源码spring-boot/spring-boot-autoconfigure/src/main/java/org/springframework/boot/autoconfigure/jdbc/DataSourceTransactionManagerAutoConfiguration.java&&* {@link EnableAutoConfiguration Auto-configuration} for&* {@link DataSourceTransactionManager}.&*&* @author Dave Syer&*/@Configuration@ConditionalOnClass({ JdbcTemplate.class, PlatformTransactionManager.class })public class DataSourceTransactionManagerAutoConfiguration implements Ordered {&& & @Override& & public int getOrder() {& & & & return Integer.MAX_VALUE;& & }&& & @Autowired(required = false)& & private DataSource dataS&& & @Bean& & @ConditionalOnMissingBean(name = &transactionManager&)& & @ConditionalOnBean(DataSource.class)& & public PlatformTransactionManager transactionManager() {& & & & return new DataSourceTransactionManager(this.dataSource);& & }&& & @ConditionalOnMissingBean(AbstractTransactionManagementConfiguration.class)& & @Configuration& & @EnableTransactionManagement& & protected static class TransactionManagementConfiguration {&& & }&}&由此可见,若未将DataSource什么为Bean,将导致transactionManager得不到创建,@Transactional注解将毫无作用&&当然,也有另一种方法,及不使用默认的transactionManager,而是自行定义,如下,在DatabaseConfiguration类中增加如下方法& & @Bean& & public PlatformTransactionManager transactionManager() {return new DataSourceTransactionManager(myDataSource());& & }默认会使用方法名作为bean的命名,因此此处覆盖了默认的transactionManager Bean对象&&如何多数据源启用事务(此处描述的非分布式事务)?如果项目中涉及操作多个数据库,则存在多个数据源DataSource。解决方案同上例,即自行声明transactionManager Bean,与每个DataSource一一对应。需要注意的是,在使用@Transactional注解是,需要添加transactionManager Bean的名称,如@Transactional(&myTransactionManager&)&2、获取新增数据的自增id&&如下Dao类型,方法create演示了如何创建一条MessageInfo记录,同时,获取该新增数据的主键,即自增id&&@Repositorypublic class MessageDao extends AntSoftDaoBase {& & private static final String TABLE_NAME = &app_message&;&& & private static final String COLUMN_NAMES = &app_id, message, ctime, status&;&& & protected MessageDao() {& & & & super(TABLE_NAME);& & }&& & private static final String SQL_INSERT_DATA =& & & & & & &INSERT INTO & + TABLE_NAME + & (& + COLUMN_NAMES + &) && & & & & & & & & & + &VALUES (?, ?, ?, ?)&;& &&& & public int create(final MessageInfo messageInfo) {& & & & KeyHolder keyHolder = new GeneratedKeyHolder();& & & & getJdbcTemplate().update(new PreparedStatementCreator() {& & & & & & & & & & & & & & & & & & &public PreparedStatement createPreparedStatement(Connection connection) throws& & & & & & & & & & & & & & & & & & & & & & &SQLException {& & & & & & & & & & & & & & & & & & & & &PreparedStatement ps =& & & & & & & & & & & & & & & & & & & & & & & & &connection.prepareStatement(SQL_INSERT_DATA, Statement.RETURN_GENERATED_KEYS);& & & & & & & & & & & & & & & & & & & & &int i = 0;& & & & & & & & & & & & & & & & & & & & &ps.setInt(++i, messageInfo.getAppId());& & & & & & & & & & & & & & & & & & & & &ps.setString(++i, messageInfo.getMessage());& & & & & & & & & & & & & & & & & & & & &ps.setTimestamp(++i, new Timestamp(new Date().getTime()));& & & & & & & & & & & & & & & & & & & & &ps.setInt(++i, 0); // 状态默认为0& & & & & & & & & & & & & & & & & & & & && & & & & & & & & & & & & & & & & & &}& & & & & & & & & & & & & & & & &}, keyHolder& & & & );& & & & return keyHolder.getKey().intValue();& & }& & ...}&&&3、SQL IN 语句&&IN语句中的数据项由逗号分隔,数量不固定,&?&仅支持单参数的替换,因此无法使用。此时只能拼接SQL字符串,如更新一批数据的status值,简单有效的实现方式如下&& & private static final String SQL_UPDATE_STATUS =& & & & & & &UPDATE & + TABLE_NAME + & SET && & & & & & & & & & + &status = ? && & & & & & & & & & + &WHERE id IN (%s)&;&& & public void updateStatus(List&Integer& ids, Status status) {& & & & if (ids == null || ids.size() == 0) {& & & & & & throw new IllegalArgumentException(&ids is empty&);& & & & }& & & & String idsText = StringUtils.join(ids, &, &);& & & & String sql = String.format(SQL_UPDATE_STATUS , idsText);& & & & getJdbcTemplate().update(sql, status.toValue());& & }&&&&&4、查询数据一般方法,及注意事项&&AppDao类型中提供get方法,以根据一个appId获取该APP数据,代码如下&&& & private static final String SQL_SELECT_DATA =& & & & & & &SELECT id, & + COLUMN_NAMES + & FROM & + TABLE_NAME + & WHERE id = ?&;&& & public AppInfo get(int appId) {& & & & List&AppInfo& appInfoList = getJdbcTemplate().query(SQL_SELECT_DATA, new Object[] {appId}, new AppRowMapper());& & & & return appInfoList.size() & 0 ? appInfoList.get(0) :& & }&&&&注意点:由于主键id会唯一标识一个数据项,有些人会使用queryForObject获取数据项,若未找到目标数据时,该方法并非返回null,而是抛异常EmptyResultDataAccessException。应使用query方法,并检测返回值数据量&&AppRowMapper用于解析每行数据并转成Model类型,其代码如下&&& & private static class AppRowMapper implements RowMapper&AppInfo& {& & & & @Override& & & & public AppInfo mapRow(ResultSet rs, int i) throws SQLException {& & & & & & AppInfo appInfo = new AppInfo();& & & & & & appInfo.setId(rs.getInt(&id&));& & & & & & appInfo.setName(rs.getString(&name&));& & & & & & appInfo.setUserId(rs.getString(&user_id&));& & & & & & appInfo.setTitle(rs.getString(&title&));& & & & & & appInfo.setDescription(rs.getString(&description&));& & & & & & appInfo.setCtime(rs.getTimestamp(&ctime&));& & & & & & appInfo.setStatus(AppStatus.fromValue(rs.getInt(&status&)));& & & & & & return appI& & & & }& & }4721人阅读
Spring(30)
本文将介绍如何在Spring Boot 工程中添加JPA作为持久化方式。
修改 pom.xml 依赖
与上一篇介绍的 jdbc 不同的是 spring-boot-starter-jdbc 修改为 spring-boot-starter-data-jpa 即可,当然数据库驱动包也是不可少的,如下:
&mysql-connector-java&
&org.springframework.boot&
&spring-boot-starter-data-jpa&
注意:如果你想JDBC和JPA可以一起使用,Spring Boot 是支持的,你只需要把JDBC和JPA的依赖都添加在pom.xml 中即可。无需其他特殊处理,有关JDBC的使用介绍请看上一篇 “”。
修改属性配置文件
在属性配置文件中添加 JPA 相关属性,注意这些并非必须,我们如果只添加dataSource 的 url\username\password\driver-class-name 也可以正常使用,有关JPA的其他配置都是可选的。
spring.jpa.database=
spring.jpa.show-sql=
spring.jpa.properties=
spring.jpa.generate-ddl=
spring.jpa.open-in-view=
spring.jpa.database-platform=
spring.jpa.hibernate.ddl-auto=
spring.data.jpa.repositories.enabled=
spring.jpa.hibernate.naming-strategy=
熟悉JPA的根据名字应基本知道这些分别的作用了。
传统上,JPA实体类在persistence.xml文件中指定的。使用Spring Boot,这个文件是没有必要的,因为它使用“实体扫描”,默认情况下主配置 @EnableAutoConfiguration 或 @SpringBootApplication 下面的所有包都将会被扫描。任何使用注解 @Entity, @Embeddable 或 @MappedSuperclass 的类都将被管理。
Java代码实例
一个Controller
我们创建一个接口 IScoreDao.java ,然后我们继承框架为我们提供好的接口
Repository 或 CrudRepository (CrudRepository 继承自 Repository),其中为我们提供了对数据库的基本操作方法。
package org.springboot.sample.dao
import java.util.List
import javax.transaction.Transactional
import org.springboot.sample.entity.Score
import org.springframework.data.jpa.repository.Modifying
import org.springframework.data.jpa.repository.Query
import org.springframework.data.repository.CrudRepository
import org.springframework.data.repository.query.Param
public interface IScoreDao extends CrudRepository&Score, Integer& {
@Transactional
@Modifying
@Query("update Score t set t.score = :score where t.id = :id")
int updateScoreById(@Param("score") float score, @Param("id") int id)
@Query("select t from Score t ")
List&Score& getList()
注意,如果你其中使用了修改、新增、删除操作,则必须要在接口上面或者对应的方法上面添加 @Transactional 注解,否则会抛出异常。
实体类 Score.java
package org.springboot.sample.
import java.io.S
import java.util.D
import javax.persistence.C
import javax.persistence.E
import javax.persistence.GeneratedV
import javax.persistence.Id;
import javax.persistence.T
* 单红宇()
* http://blog.csdn.net/catoop/
@Table(name = "score")
public class Score implements Serializable {
private static final long serialVersionUID = 1338189L;
@GeneratedValue
private int
@Column(nullable = false, name="STUDENTID")
private int stuId;
@Column(nullable = false, name="SUBJECTNAME")
private String subjectN
@Column(nullable = false)
private float
@Column(nullable = false, name="EXAMTIME")
private Date examT
ScoreController.java
package org.springboot.sample.controller
import java.util.List
import org.slf4j.Logger
import org.slf4j.LoggerFactory
import org.springboot.sample.dao.IScoreDao
import org.springboot.sample.entity.Score
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
@RestController
@RequestMapping("/score")
public class ScoreController {
private static final Logger logger = LoggerFactory.getLogger(ScoreController.class)
@Autowired
private IScoreDao scoreService
@RequestMapping("/scoreList")
public List&Score& getScoreList(){
logger.info("从数据库读取Score集合")
// 测试更新数据库
logger.info("更新的行数:" + scoreService.updateScoreById(88.8f, 2))
scoreService.delete(23)
return scoreService.getList()
然后在浏览器访问地址: 测试。
最后要说明的是,Spring 会自动为我们继承CrudRepository接口的接口创建实现类。我们只需要在使用的时候直接使用注解 @Autowired 注入即可(IScoreDao 接口上也没有必要增加 @Component 、 @Repository 等注解)。
还有,我这里为了简单起见,直接将操作数据库的在Controller中使用,实际项目中,是不建议这样做的,IScoreDao 的所属角色是数据库持久,我们还应当有 Service(如ScoreService) 来调用 IScoreDao 的方法,然后在Controller 中调用 Service 中的方法。原因是因为,我们数据库访问层,都是接口定义方法,上面注解注入SQL和参数,没有具体的代码逻辑处理。如果我们想在执行SQL之前或之后执行逻辑处理,只能在 Service 中或者Controller(不建议)中。
我们严格按照这种方式去做(持久层只与SQL有关,通过接口定义无逻辑处理),这样才是彻彻底底的持久层。越严格的规范制度,在某种程度上来说其实越有利于代码的管理和项目代码的迭代发展。
当然,如果你实在想要实现自己的 class 实现类,下面会附上一个实例代码,在此之前,我们先看一个图片:
这个图是Spring 使用动态代理创建的接口实例,可以看出,其使用的是 SimpleJpaRepository 类,所以如果我们实现自己的 Repository ,可以扩展 SimpleJpaRepository 并 实现自己的 factory-class 入手,这里不做详解。注意凡事实现 Repository 接口的实现类都不需要添加 @Repository 注解,否则你会遇到问题。
本文介绍JPA 相比上一篇关于JDBC 的介绍增加的文件工程截图为:
熟悉其中一种持久数据的方法后,其他类似的都大同小异。
参考知识库
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
访问:1197097次
积分:13074
积分:13074
排名:第624名
原创:235篇
转载:39篇
译文:10篇
评论:519条
文章:22篇
阅读:113166
(10)(12)(10)(25)(17)(17)(10)(13)(21)(12)(5)(1)(9)(4)(6)(8)(2)(3)(2)(5)(2)(6)(4)(2)(1)(2)(1)(2)(1)(7)(14)(7)(5)(3)(1)(2)(19)(9)(3)

我要回帖

更多关于 spring boot 和数据库 的文章

 

随机推荐