SpringBoot访问数据库
步骤:
【1-建项目加依赖】创建Maven项目,pom.xml中添加 < parent> 启动器、spring-boot-start-web 启动器(springboot必须)、spring-boot-starter-test(springboot自己提供的用于测试的启动器)、mysql和jpa(用于数据库连接使用);
【2-建实体类加注解】① 数据库中新建数据库和数据表:User(id、name、createDate(Util中Date类))、Role(id、name)、Department(id、name);
② main/java 中创建 com.asd.springbootdb 包:entity包中新建 User、Role、Department类;再让实体和表关联:实体类上即字段上添加以下注解:
@Entity
@Table(name = “department”): 都是(javax.persistence包中)@Entity表示这个类是一个实体,实体类与数据库表有映射关系;@Table表示实体类与数据库中相应的表有映射关系,设置数据库的表名;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY): @Id指明数据库的主键列, @GeneratedValue指明逐渐列值的生成方式;
@DateTimeFormat(pattern = “yyyy-MM-dd HH:mm:ss”): 设置日期类型的格式;
一个用户属于一个部门、对应多个角色权限:(User类中添加Department department、List< Role> roles;)
@ManyToOne
@JoinColumn(name = “did”):@ManyToOne表示多对一关联关系;@JoinColumn设置关联对象的外键列,如当前 User类所关联到的对象是 department,要设的是关联对象 department在 user表中的外键列即 did;
@ManyToMany(cascade = {},fetch = FetchType.EAGER)
@JoinTable(name = “user_role”,joinColumns = {@JoinColumn(name = “user_id”)},inverseJoinColumns = {@JoinColumn(name = “roles_id”)}):@ManyToMany表示多对多:cascade用来设级联、fetch设置是否启用懒加载;@JoinTable保存多对多关联关系表的信息的设置:name表示第三张关联关系表的表名、joinColumns(加s是一个数组,所以用{}括起来)表示当前对象(User)在关联关系表(user_role)中的外键名(即user_id)、inverseJoinColumns (加s是一个数组,所以用{}括起来)表示关联的另一个多方(Role)在关联关系表(user_role)中的外键名(即roles_id);
【3-建接口写方法(实体类对应的持久化接口)】实体持久化即对实体类对象的CRUD操作,springboot中使用 spring-boot-data-jpa来操作数据库,所以增删改查只需要继承一个接口,接口中自己编写符合规范的方法即可,无需自己实现接口,由系统自动实现:main/java 中创建 com.asd.springbootdb.repositories 包:包中建三个对应的接口继承 JpaRepository<User,Long>,即可做增删改查操作(父接口中指定泛型类型<是哪个类的,此类主键的数据类型>; 在 UserRepository.java类中编写方法public List<User> findByNameLike(String name);
;
底层类的实现(以下都是接口):
XxRepository extends JpaRepository —>
JpaRepository extends PagingAndSortingRepository —>
PagingAndSortingRepository extends CrudRepository —>
CrudRepository extends Repository;
Repository: 标识的接口,不提供任何方法 ;
CrudRepository: 继承了 Repository,提供了一系列CRUD相关的方法;
PagingAndSortingRepository: 继承了 CrudRepository,提供了排序和分页相关的方法;
JpaRepository: 提供了一组符合Jpa操作规范的方法;
)
【4-写配置类加注解(test测试包下)】(配置数据库连接)配置类上加注解:
@Configuration
@EnableJpaRepositories(basePackages = “com.asd.springbootdb.repositories”): @Configuration表示当前类是一个配置类,作用类似于spring中的xml文件;@EnableJpaRepositories用来指定Repository类的包路径;
【5-写测试类加注解(test测试包下,且 pom.xml中要添加测试类启动器)】:
① pom.xml文件中添加有关测试的依赖,它是springboot自己提供了一个用于测试的starter启动器,它已经包含了像junit等测试模块,无需自己去添加具体的(入junit等)测试模块;
② 创建测试类,类上添加注解:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = JpaConfiguration.class): @RunWith表示采用什么形式run:表示当前程序的运行是在spring的容器的环境下运行,而 junit可直接拿到 spring容器的对象,不需要再进行为重新得到 spring容器而进行的配置,简化了因为测试而生成相应的关于 spring容器的配置;@ContextConfiguration指明 jpa的配置文件,这里不是用xml文件进行配置,而是用 java的配置类进行配置的;
详细步骤:
1. New——》Mave项目 ,添加SpringBoot基本依赖、mysql依赖、jpa依赖(jpa 是一组接口,没有实现,它是在具体的 orm框架中实现,若想使用 jpa则必须要使用实现了 jpa接口的 orm框架,如Hibernate)
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
2. Mysql中创建数据库和数据表
3. 实体建模
- 创建 User、Role、Department 三个实体类
- @Entity : 表示实体类与数据库表有映射关系
@Table : 设置数据库的表名
@Id : 表示属性对应的是数据库的主键列
@GeneratedValue : 表示主键列的生成方式
@DateTimeFormat : 设置日期类型格式
(包名最好与创建 maven 项目的 groupId 相同:)
(Date类型的字段是 Util 包中的Date:)
(User类:)
4. MySQL的依赖配置
例子中三个实体之间关联关系:
User(N)——>Department(1)
User(N)——>Role(N)
User类中添加 private List< Role > roles;private Department department;以及对应的get、set方法;并添加相应的注解。如下图:。
@ManyToOne:多对一的关联关系
@JoinColumn(name=" did "):设置关联对象(department)的外键列
@ManyToMany(cascade = {},fetch = FetchType.EAGER):多对多; cascade: 级联; fetch: 设置是否启用懒加载。
@JoinTable(name = “user_role”,joinColumns = {@JoinColumn(name = “user_id”)},
inverseJoinColumns={@JoinColumn(name=“roles_id”)}):
@JoinTable: 设置多对多关联关系表信息。
name: 关联关系表表名;joinColumns: 当前对象(User)在关联关系表中的外键名;inverseJoinColumns: 关联的另一方对象在关联关系表中的外键名。
5. 实体持久化
新建包 repositories,创建对应的 xxRepository 接口,继承 JpaRepository 接口;UserRepository 中添加方法findByNameLike(String name)。
底层类的实现:
Repository: 标识的接口,不提供任何方法;
CrudRepository: 继承了 Repository,提供了一系列CRUD相关的方法;
PagingAndSortingRepository: 继承了 CrudRepository,提供了排序和分页相关的方法;
JpaRepository: 提供了一组复核Jpa操作规范的方法。
Jpa 会为接口中符合 jpa 规范的方法提供实现:
SpringData JPA定义的方法规范:
1、查询方法以 find| read| get开头;
2、使用连接关键词连接查询属性,属性名首字母大写;方法的参数位置和个数要和条件的属性名称对应;
3、条件的关键字,上述表中的关键字一列。(eg:UserRepository 中添加方法 findByNameLike(String name))
6. 配置数据库连接(使用Java配置)
test 包下新建测试包,包中新建配置类 JpaConfiguration,类中进行代码编写
import java.util.Properties;
@Configuration //表示当前类是一个配置类,作用类似于Spring框架中的xml配置文件
@EnableJpaRepositories(basePackages = "com.mdd.springbootdb.repositories")
//指定Repository类的包路径
public class JpaConfiguration {
// 1.DataSource
@Bean //告诉Spring框架这个方法的返回值需要注册成Spring中的Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource=new DriverManagerDataSource();
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/springbootdb?charaterEncoding=utf8");
dataSource.setUsername("root");
dataSource.setPassword("12345");
return dataSource;
}
// 2.LocalContainerEntityManagerFactoryBean
// 管理EntityManager类对象,用于后续的crud操作
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
LocalContainerEntityManagerFactoryBean entityManagerFactoryBean=
new LocalContainerEntityManagerFactoryBean();
entityManagerFactoryBean.setDataSource(dataSource());
entityManagerFactoryBean.setPackagesToScan("com.mdd.springbootdb.domain");
entityManagerFactoryBean.setJpaProperties(buildHibernateProperties());
//设置Jpa接口实现的厂商,用Hibernate
entityManagerFactoryBean.setJpaVendorAdapter(new HibernateJpaVendorAdapter(){
{
setDatabase(Database.MYSQL);
}
});
return entityManagerFactoryBean;
}
// 针对Hibernate的配置
protected Properties buildHibernateProperties(){
Properties hibernateProperties=new Properties();
hibernateProperties.setProperty("hibernate.dialect","org.hibernate.dialect.MySQL5Dialect");
hibernateProperties.setProperty("hibernate.show_sql","true");
hibernateProperties.setProperty("hibernate.format_sql","true");
hibernateProperties.setProperty("hibernate.hbm2ddl.auto","update");
return hibernateProperties;
}
// 3.事务管理器
@Bean
public PlatformTransactionManager transactionManager(){
return new JpaTransactionManager();
}
// 想看到Spring的异常体系,而不是底层Hibernate的异常体系
@Bean
PersistenceExceptionTranslationPostProcessor persistenceExceptionTranslationPostProcessor(){
return new PersistenceExceptionTranslationPostProcessor();
}
// 用于操作具体的sql
@Bean
public TransactionTemplate transactionTemplate(){
return new TransactionTemplate(transactionManager());
}
}
7. 测试
pom文件中添加 SpringBoot 自带的测试依赖(不是junit了);新建的test包中创建测试类SpringbootMysqlTest测试类:注入实体类接口对象 XxRepository; 在写具体的测试方法之前(@Before)先写生成数据库的方法:方法中先删除完实体类接口对象对应的数据库中原有的方法,再重新对各个实体类接口对象进行持久化:departmentRepository.save(department);
实体类接口对象来保存即持久化,Assert.notNull(department.getId());
通过getId()来测试保存是否成功、对于userRepository:User类中包含 department对象和 roles集合,先找出数据库中所有的roles,找到后先判断一下查到的 roles集合是否为空,不为空再 set进 user中,再持久化 user保存进 userRepository中;再编写具体的测试方法(@Test)中:调用实体类接口对象中的方法,再对结果进行判断,运行查看测试是否通过;
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
</dependency>
import java.util.List;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = JpaConfiguration.class)
public class SpringbootMysqlTest {
@Autowired
DepartmentRepository departmentRepository;
@Autowired
RoleRepository roleRepository;
@Autowired
UserRepository userRepository;
@Before
public void initData(){
departmentRepository.deleteAll();
roleRepository.deleteAll();
userRepository.deleteAll();
Department department=new Department();
department.setName("Dep01");
departmentRepository.save(department);
Assert.assertNotNull(department.getId());
Role role=new Role();
role.setName("Stefan");
roleRepository.save(role);
Assert.assertNotNull(role.getId());
User user=new User();
user.setName("user1");
user.setCreateDate(new Date());
user.setDepartment(department);
List<Role> roles=roleRepository.findAll();
Assert.assertNotNull(roles);
user.setRoles(roles);
userRepository.save(user);
Assert.assertNotNull(user.getId());
}
@Test
public void test(){
List<User> userList=userRepository.findByNameLike("u%");
Assert.assertNotNull(userList);
}
}