LOMBOK是一款可以在编译期在类中自动生成某些代码的工具,通常用于自动生成:
hashCode() and equals()toString()在使用时,需要添加依赖项:
- <dependency>
- <groupId>org.projectlombokgroupId>
- <artifactId>lombokartifactId>
- <version>1.18.20version>
- <scope>providedscope>
- dependency>
在POJO类的声明上,添加@Data注解,此注解可以帮助生成所有属性对应的Setters & Getters、规范的hashCode()和equals()、toString(),并且,要求此类的父类中存在无参数构造方法。
- package cn.tedu.csmall.product.pojo.entity;
-
- import lombok.Data;
-
- import java.io.Serializable;
- import java.time.LocalDateTime;
-
- @Data
- public class Album implements Serializable {
-
- private Long id;
- private String name;
- private String description;
- private Integer sort;
- private LocalDateTime gmtCreate;
- private LocalDateTime gmtModified;
-
- }
注意:Lombok是在**编译期(将Java源代码文件.java编译成目标文件.class)**添加各方法,所以,在IntelliJ IDEA或其它开发工具中,默认情况下,直接调用以上各属性对应的Setter或Getter方法,在开发工具将无法提示这些方法,并且,已经写出来的调用这些方法的代码会报错,为了解决此问题,需要在开发工具中安装Lombok插件。
另外,Lombok还提供了以下注解:
@Data
@Setter
@Getter
@EqualsAndHashCode
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Accessors
@Accessors(chain = true)时,将支持链式调用方法@Slf4j
Mybatis框架主要实现了简化持久层编程的问题。
持久层:实现数据持久化的一系列组件。
数据持久化:通常,在开发领域中,讨论的数据大多是在内存中的,而内存默认特指内存条(RAM:Random Access Memory),RAM的特性包含“一旦断电,数据将全部丢失”,且“正在执行的程序和数据都是在内存中的”,由程序处理的数据最终应该永久的保存下来,则不能将这些数据一直只存储在内存中,通常,会将数据存储到可以永久保存数据的存储介质中,典型的永久存储数据的存储介质有:硬盘、U盘、光盘等,所以,数据持久化就是将内存中的数据存储到硬盘等介质中,而硬盘中的数据是以文件的形式存在的,所以,通常可以将数据存储到文本文件中、XML文件、数据库中,这些存储方案中,只有数据库是便于实现增、删、改、查这4种操作的,所以,一般“数据持久化”默认指的就是将数据存储到数据库中。
在Java语言中,实现数据库编程需要先建立与数据库的连接,然后准备SQL语句,然后执行,然后获取执行结果并处理结果,最后,关闭或归还数据库连接,这是一套非常固定的流程,无论对哪个数据表执行哪种操作,其流程大致是固定的,所以,就产生了一些框架,用于简化这部分的编程。
在使用Mybatis时,只需要关注2点:
在Spring Boot项目中,当需要使用Mybatis时,需要添加相关的依赖:
- <dependency>
- <groupId>mysqlgroupId>
- <artifactId>mysql-connector-javaartifactId>
- <scope>runtimescope>
- dependency>
- <dependency>
- <groupId>org.mybatis.spring.bootgroupId>
- <artifactId>mybatis-spring-boot-starterartifactId>
- <version>2.2.2version>
- dependency>
当添加以上依赖项后,如果启动项目,会提示以下错误:
- ***************************
- APPLICATION FAILED TO START
- ***************************
-
- Description:
-
- Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
-
- Reason: Failed to determine a suitable driver class
因为Spring Boot启动时,如果检测到当前已经添加数据库编程的依赖项,会自动读取连接数据库的配置信息,由于目前尚未配置这些信息,所以,启动会报错!
所以,需要在application.properties中添加配置:
- # 连接数据库的参数
- spring.datasource.url=jdbc:mysql://localhost:3306/mall_pms?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
- spring.datasource.username=root
- spring.datasource.password=root
由于Spring Boot在启动项目时只会读取以上配置并应用,并不会实际的连接数据库,所以,即使以上配置值是错误的,启动项目时并不会报告错误!
可以在src/test/java的根包下的测试类中进行测试连接:
- @SpringBootTest
- class CsmallProductApplicationTests {
-
- @Test
- void contextLoads() {
- }
-
- @Autowired
- DataSource dataSource;
-
- @Test
- void testConnection() throws Exception {
- dataSource.getConnection();
- }
-
- }
当配置的URL错误(含主机名错误、端口号错误),或MySQL未启动时,将出现以下错误:
- com.mysql.cj.jdbc.exceptions.CommunicationsException: Communications link failure
-
- The last packet sent successfully to the server was 0 milliseconds ago. The driver has not received any packets from the server.
如果数据库名称错误,或无此数据库,将出现以下错误:
java.sql.SQLSyntaxErrorException: Unknown database 'mall_pmsxzxxxxx'
如果用户或密码错误,将出现以下错误:
java.sql.SQLException: Access denied for user 'rootx'@'localhost' (using password: YES)
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: YES)
java.sql.SQLException: Access denied for user 'root'@'localhost' (using password: NO)
Mybatis要求抽象方法必须存在于接口中(因为其实现原理是基于接口的代理模式的),所以,在项目的根包下创建mapper.AlbumMapper接口。
提示:可以在接口上添加@Repository注解,避免在自动装配时IntelliJ IDEA误判而提示错误。
关于接口中的抽象方法:
int作为返回值类型,表示“受影响的行数”,不建议使用voidget做前缀list做前缀count做前缀save/insert做前缀remove/delete做前缀update做前缀则,插入相册时需要执行的SQL语句大致是:
insert into pms_album (name, description, sort, gmt_create, gmt_modified) values (?, ?, ?, ?, ?);
则抽象方法为:
int insert(Album album);
在首次使用时,需要让Mybatis知道哪些接口是Mapper接口,可以(二选一):
@Mapper注解@MapperScan并指定Mapper接口所在的包
@Configuration注解,即是配置类config.MybatisConfiguration类,同时添加@Configuration和@MapperScan("cn.tedu.csmall.product.mapper")即可另外,在使用Mybatis时,还需要为每个抽象方法配置其映射的SQL语句,可以使用@Insert等注解来配置SQL语句,但不推荐,因为:
建议的做法是使用XML文件来配置SQL语句,可以从 http://doc.canglaoshi.org/config/Mapper.xml.zip 下载得到所需的文件,然后,在项目的src/main/resources下创建mapper文件夹,将得下载、解压得到的XML文件复制到此文件夹中。
关于配置SQL的XML文件:
上必须配置namespace属性,取值为对应的接口的全限定名的子级,根据需要执行的SQL语句,选择使用、、、中的某个节点,准备配置SQL语句,这些节点必须配置id属性,取值为抽象方法的名称(不包括括号和参数列表),并在这些节点内部配置SQL语句提示:在本项目中,当插入数据时,不需要关注
gmtCreate、gmtModified这2个字段的值的插入,后续将使用Xxx自动完成。
例如:
- mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
-
- <mapper namespace="cn.tedu.csmall.product.mapper.AlbumMapper">
-
-
- <insert id="insert">
- INSERT INTO pms_album (
- name, description, sort
- ) VALUES (
- #{name}, #{description}, #{sort}
- )
- insert>
-
- mapper>
在首次使用时,需要在application.properties中配置以上XML文件的位置:
- # Mybatis的配置SQL的XML文件的位置
- mybatis.mapper-locations=classpath:mapper/*.xml
至此,“插入相册数据”的功能开发完成!
然后,应该及时测试以上功能是否正确,可以在src/test/java下的根包下创建mapper.AlbumMapperTests测试类,
- package cn.tedu.csmall.product.mapper;
-
- import cn.tedu.csmall.product.pojo.entity.Album;
- import org.junit.jupiter.api.Test;
- import org.springframework.beans.factory.annotation.Autowired;
- import org.springframework.boot.test.context.SpringBootTest;
-
- @SpringBootTest
- public class AlbumMapperTests {
-
- @Autowired
- AlbumMapper mapper;
-
- @Test
- void testInsert() {
- Album album = new Album();
- album.setName("某电视的相册");
- album.setDescription("某电视的相册的描述");
- album.setSort(63);
- int rows = mapper.insert(album);
- System.out.println("rows = " + rows);
- }
-
- }
在执行测试时,如果此前配置的@MapperScan有误,会出现如下错误:
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'cn.tedu.csmall.product.mapper.AlbumMapperTests': Unsatisfied dependency expressed through field 'mapper'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'cn.tedu.csmall.product.mapper.AlbumMapper' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
如果在XML文件中,的namespace属性值配置有误,或者节点的id属性值配置有误,或者在application.properties中没有正确的配置mybatis.mapper-locations属性,都将出现以下错误:
org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.tedu.csmall.product.mapper.AlbumMapper.insert
【练习】
#{}中的名称是类中的属性名在配置节点时,配置useGeneratedKeys和keyProperty这2个属性,就可以得到自动编号的id,例如:
- <insert id="insert" useGeneratedKeys="true" keyProperty="id">
其中,useGeneratedKeys="true"表示“需要获取自动编号的键的值”,keyProperty="id"表示将得到的自动编号的id值放回到参数对象的id属性中去!
开发规范上,对于自动编号的表进行插入数据时,都应该配置这2个属性!
需求:根据id删除相册数据
需要执行的SQL语句大致是:
delete from pms_album where id=?
在AlbumMapper接口中添加抽象方法:
int deleteById(Long id);
在AlbumMapper.xml中配置以上抽象方法映射的SQL:
- <delete id="deleteById">
- DELETE FROM pms_album WHERE id=#{id}
- delete>
完成后,在AlbumMapperTests中添加新的测试方法:
- @Test
- void testDeleteById() {
- Long id = 1L;
- int rows = mapper.deleteById(id);
- System.out.println("rows = " + rows);
- }
【练习】
每个创建好的Spring Boot项目的src/main/java下都有一个默认的包,且包下有一个带main()方法的类,此类就是整个项目的启动类,执行此类的main()方法将启动整个项目。
在Spring Boot项目中,在src/main/resources下,默认就存在application.properties文件,此文件是Spring Boot会自动读取的配置文件。
Spring Boot使用了许多自动配置的机制,以至于我们只需要按照规定的名称去填写配置值,这些配置就会生效!
实现以下数据表的“插入数据”和“根据id删除数据”的功能: