一、引入依赖包
要想连接数据源必须先引入依赖包,下面以连接mysql为例
<!-- JPA数据源 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!-- mysql驱动包 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
二、添加配置
springBoot的配置有两种方式
- 在application.properties中配置
- 在application.yml中配置
由于properties文件中不能写中文,而yml中可以写中文,所以建议使用yml配置,而且yml还可以使用简写的形式写配置项。
2-1 配置数据源
先看下在application.properties中怎么配置
######### Data source ###########
spring.datasource.url = jdbc:mysql://localhost:3306/cms
spring.datasource.username = root
spring.datasource.password = 123456
spring.datasource.driver = com.mysql.jdbc.Driver
在看下在application.yml文件中怎么配置
######### Data source ###########
spring.datasource:
url: jdbc:mysql://localhost:3306/cms
username: root
password: 123456
driver: com.mysql.jdbc.Driver
把’=‘换成’: ',而且前面的重复文字可以省略不写,是不是很方便。下面就使用yml的方式配置了
2-2 配置JPA
JPA是Java Persistence API的简称,中文名Java持久层API。是用注解或xml描述对象和数据库表之间的映射关系的一个ORM框架
JPA是JDK1.5中自带的,无需引入其他包
在application.yml中配置JPA
######## Hibernate ############
spring.jpa.hibernate:
#配置成update,在项目启动时@Entity注解标注的实体类在数据库中不存在则新建,存在则不作任何操作
hbm2ddl.auto: update
#此项是配置@Entity中的字段和数据库表中字段的映射策略, 该项是默认策略,会将entity中驼峰式的字段名转换成下划线式的。比如"userName"将转换成"user_name"
#需要注意的是如果使用此策略,则@Column注解的name属性就算配置了也无
#naming.implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyLegacyJpaImpl
#下面一项的映射策略是会将数据库表的列映射成和@Entity中的字段名一致,如果某些字段需要映射成特殊名字可以在@Column注解的name属性中配置
naming.physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
#使用InnoDB引擎
dialect: org.hibernate.dialect.MySQL5InnoDBDialect
#在日志或控制台中显示SQL语句
spring.jpa.show-sql: true
2-3 创建实体类
package cn.lgc.study.spboot.domain;
import java.util.Date;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity //标识这是一个实体类
public class User {
@Id //表示主键
@GeneratedValue //表示要自动生成值,相当于mysql的主键值递增
private int id;
/*
* @Column表示映射到一列,其中nullable表示该列是否可以有空值, false表示不能有空值。
* unique表示值是否唯一, true表示是唯一的
*/
@Column(nullable = false, unique = true)
private String username;
@Column(nullable = false)
private String password;
@Column(nullable = true)
private Date lastLoginTime;
/*
* name表示映射到数据库表中哪一列
* 如果yml中没有配置'spring.jpa.hibernate.naming.physical-strategy'则默认将属性名映射成下划线形式的,比如"userName"会映射成"user_name",并且name属性不生效
*
* 如果想让name属性生效可以将'spring.jpa.hibernate.naming.physical-strategy'配置成'org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl'
* 需要注意的是此时默认映射成的字段会和类属性同名,可以使用name属性指定映射成什么名字。比如此处会将 roleId 映射为 'role_id'
*/
@Column(nullable = false, name = "role_id")
private int roleId;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Date getLastLoginTime() {
return lastLoginTime;
}
public void setLastLoginTime(Date lastLoginTime) {
this.lastLoginTime = lastLoginTime;
}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", lastLoginTime="
+ lastLoginTime + ", roleId=" + roleId + "]";
}
}
数据库表结构是这样的
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`userName` varchar(16) NOT NULL COMMENT '用户名',
`password` varchar(18) NOT NULL COMMENT '密码',
`lastLoginTime` datetime DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '最后登录时间',
`role_id` int(11) NOT NULL COMMENT 'Role表的外键',
PRIMARY KEY (`id`),
UNIQUE KEY `UK_userName_User` (`userName`) USING BTREE,
KEY `FK_role_id_Role_id` (`role_id`),
CONSTRAINT `FK_role_id_Role_id` FOREIGN KEY (`role_id`) REFERENCES `role` (`id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=909 DEFAULT CHARSET=utf8;
注意:role_id字段中间是带下划线的,所有就需要在实体类中使用@Column注解的name属性
2-4 创建dao
JPA最强大的地方就在dao这,无需写sql,只要继承CrudRepository接口就可以了,此接口中提供了一些基础的增删改查方法。外部可以直接调用,连实现方法都不用写
package cn.lgc.study.spboot.dao;
import org.springframework.data.repository.CrudRepository;
import cn.lgc.study.spboot.domain.User;
/*
* CrudRepository有两个泛型,第一个指定是哪个实体类的dao,第二个指定实体类中主键的数据类型
*/
public interface UserDao extends CrudRepository<User, Integer> {
}
查看CrudRepository接口的源码可以看到里面定义了一些基本的增删改查方法
CrudRepository.java
/*
* Copyright 2008-2017 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.data.repository;
import java.util.Optional;
/**
* Interface for generic CRUD operations on a repository for a specific type.
*
* @author Oliver Gierke
* @author Eberhard Wolff
*/
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {
/**
* Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
* entity instance completely.
*
* @param entity must not be {@literal null}.
* @return the saved entity will never be {@literal null}.
*/
<S extends T> S save(S entity);
/**
* Saves all given entities.
*
* @param entities must not be {@literal null}.
* @return the saved entities will never be {@literal null}.
* @throws IllegalArgumentException in case the given entity is {@literal null}.
*/
<S extends T> Iterable<S> saveAll(Iterable<S> entities);
/**
* Retrieves an entity by its id.
*
* @param id must not be {@literal null}.
* @return the entity with the given id or {@literal Optional#empty()} if none found
* @throws IllegalArgumentException if {@code id} is {@literal null}.
*/
Optional<T> findById(ID id);
/**
* Returns whether an entity with the given id exists.
*
* @param id must not be {@literal null}.
* @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
* @throws IllegalArgumentException if {@code id} is {@literal null}.
*/
boolean existsById(ID id);
/**
* Returns all instances of the type.
*
* @return all entities
*/
Iterable<T> findAll();
/**
* Returns all instances of the type with the given IDs.
*
* @param ids
* @return
*/
Iterable<T> findAllById(Iterable<ID> ids);
/**
* Returns the number of entities available.
*
* @return the number of entities
*/
long count();
/**
* Deletes the entity with the given id.
*
* @param id must not be {@literal null}.
* @throws IllegalArgumentException in case the given {@code id} is {@literal null}
*/
void deleteById(ID id);
/**
* Deletes a given entity.
*
* @param entity
* @throws IllegalArgumentException in case the given entity is {@literal null}.
*/
void delete(T entity);
/**
* Deletes the given entities.
*
* @param entities
* @throws IllegalArgumentException in case the given {@link Iterable} is {@literal null}.
*/
void deleteAll(Iterable<? extends T> entities);
/**
* Deletes all entities managed by the repository.
*/
void deleteAll();
}
三、测试
我就不写service层了,直接controller调用dao
package cn.lgc.study.spboot.web;
import java.util.Optional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.lgc.study.spboot.dao.UserDao;
import cn.lgc.study.spboot.domain.User;
@RestController
public class UserController {
@Autowired
private UserDao userDao;
@RequestMapping("/user/findById")
public User findById(Integer id) {
Optional<User> findById = userDao.findById(id);
User user = findById.get();
return user;
}
}