后端Web实战-Java代码操作数据库
目录
1.JDBC
1.1概述
1.2快速入门
1.3 API详解
1.3.1 DriverManager
1.3.1.1 注册驱动
1.3.1.2 获取链接
1.3.2 Connection & Statement
1.3.3 ResultSet
1.3.4 PreparedStatement
2.Mybtis基础
2.1 介绍
2.2 快速入门
2.2.1 准备工作
2.2.2 编写SQL语句
2.2.3 单元测试
2.3 辅助配置
2.3.1 配置SQL提示
2.3.2 配置Mybatis的日志输出
2.4 JDBC VS Mybatis
2.5 数据库连接池
2.5.1 介绍数据库连接池
2.5.2 如何实现数据库连接?
2.6 Mybatis的XML配置文件
2.6.1 XML配置文件规范
2.6.3 MybatisX的使用
3.部门列表查询
3.1 功能实现
3.1.1 需求
3.1.2 实现
3.2 数据封装
1.JDBC
1.1概述
我们做为后端程序开发人员,通常会使用Java程序来完成对数据库的操作。Java程序操作数据库的技术呢,有很多啊。
-
JDBC:(Java DataBase Connectivity),就是使用Java语言操作关系型数据库的一套API。 【是操作数据库最为基础、底层的技术】
那现在在企业项目开发中呢,一般都会使用基于JDBC的封装的高级框架,比如:Mybatis、MybatisPlus、Hibernate、SpringDataJPA。
我们会学习目前最为主流的就是Mybatis,其次是MybatisPlus。
JDBC:(Java DataBase Connectivity),就是使用Java语言操作关系型数据库的一套API。
本质:
sun公司官方定义的一套操作所有关系型数据库的规范,即接口。
各个数据库厂商去实现这套接口,提供数据库驱动jar包。
我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类。
1.2快速入门
public class JDBCTest {@Testpublic void testUpdate() throws Exception {//1.准备工作//1.1 注册驱动Class.forName("com.mysql.cj.jdbc.Driver");//固定步骤//1.2 获取数据库连接对象ConnectionConnection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/java147_db02", "root", "456789");//1.3 获取SQL语句执行对象StatementStatement statement = connection.createStatement();//2.执行SQL语句//需求:修改用户表id为1的密码,修改为12345678int i = statement.executeUpdate("update user set password = '12345678' where id = 1;");System.out.println("i == " + i);//3.释放资源statement.close();connection.close();}
}
1.3 API详解
1.3.1 DriverManager
作用:
-
注册驱动
-
获取数据库链接 Connection
1.3.1.1 注册驱动
上述的代码中我们是通过class.forName("com.mysql.cj.jdbc.Driver")来注册的,看似和DriverManager没什么联系。其实不然,这段代码只是将Driver这个类加载到JVM中。而在Driver这个类中定义了静态代码块,内容如下:
当 Driver
这个类被加载时,就会自动执行静态代码块中的代码,然后就完成了注册驱动的操作。
备注:
而其实啊,class.forName("com.mysql.cj.jdbc.Driver") 这句代码呢,是可以省略的,省略了,也可以正常的完成驱动的注册。 原因是因为在MySQL的驱动jar包中,在 META-INF/services 目录中提供了一个文件 java.sql.Driver
,在这个文件中编写了一行内容,就是驱动类的全类名 :
当在程序需要用到这个类时,java会自动加载这个类,这个类一加载 就会自动执行静态代码块中的内容,就完成了注册驱动的操作 ,而java中的这个机制称之为 SPI。
SPI机制:Service Provider Interface,JDK内置的一种服务提供发现机制,可以轻松的扩展你的程序(切换实现),实现接口与实现类之间的解耦。
1.3.1.2 获取链接
1.3.2 Connection & Statement
-
Connection的作用:获取执行SQL的对象
-
执行普通SQL对象的Statement:
connection.createStatement();
-
执行预编译SQL对象PreparedStatement:
connection.prepareStatement();
【后面单独讲解】
-
-
Statement的作用:执行SQL
-
执行DDL(数据库定义语句,一般不用)、DML(增删改)语句:
executeUpdate(sql);
如果是执行DML语句完毕,返回值int代表 DML 语句影响的行数。 -
执行SQL(查询)语句:
executeQuery(sql);
返回值为ResultSet,里面封装了查询结果。
-
1.3.3 ResultSet
@Testpublic void testSelect() throws Exception {//1.准备工作//1.1 注册驱动//Class.forName("com.mysql.cj.jdbc.Driver");//固定步骤//省略注册驱动也可以运行成功,//1.2 获取数据库连接对象ConnectionConnection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/java147_db02", "root", "456789");//1.3 获取SQL语句执行对象StatementStatement statement = connection.createStatement();//2.执行SQL语句//需求:根据用户名和密码查询用户信息,模拟用户登录ResultSet resultSet = statement.executeQuery("select * from user where username = 'xiaoqiao' and password = '123456'");//判断是否有值while(resultSet.next()) {//输出结果--解析Resulet//int id = resultSet.getInt(1); //下标从1开始int id = resultSet.getInt("id");String username = resultSet.getString("username");String password = resultSet.getString("password");String name = resultSet.getString("name");int age = resultSet.getInt("age");User user = new User(id,username,password,name,age);System.out.println(user);}//3.释放资源statement.close();connection.close();}
在上述的单元测试中,我们在SQL语句中,将用户名和密码的值都写死了,而这两个值应该是动态的,是将来页面传递到服务端的。那么,我们可以基于前面所讲的JUnit中的参数化测试进行单元测试,代码改造如下:
@ParameterizedTest //参数化测试//@ValueSource(strings = {"xiaoqiao","123456"}) //代表一个参数分两次测试//所以@ValueSource只适合对一个参数进行测试的@CsvSource(value = {"xiaoqiao, 123456", "zhangsan, 123456"})public void testSelect(String uname,String pwd) throws Exception {//1.准备工作//1.1 注册驱动//Class.forName("com.mysql.cj.jdbc.Driver");//固定步骤//省略注册驱动也可以运行成功,//1.2 获取数据库连接对象ConnectionConnection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/java147_db02", "root", "456789");//1.3 获取SQL语句执行对象StatementStatement statement = connection.createStatement();//2.执行SQL语句//需求:根据用户名和密码查询用户信息,模拟用户登录ResultSet resultSet = statement.executeQuery("select * from user where username = '"+uname+"' and password = '"+pwd+"'");//判断是否有值while(resultSet.next()) {//输出结果--解析Resulet//int id = resultSet.getInt(1); //下标从1开始int id = resultSet.getInt("id");String username = resultSet.getString("username");String password = resultSet.getString("password");String name = resultSet.getString("name");int age = resultSet.getInt("age");User user = new User(id,username,password,name,age);System.out.println(user);}//3.释放资源statement.close();connection.close();}
如果在测试时需要用一个参数就用@ValueSource(strings = {"xiaoqiao","123456"}) //代表一个参数分两次测试,如果需要用到一组参数就用 @CsvSource(value = {"xiaoqiao, 123456", "zhangsan, 123456"})进行注解。
1.3.4 PreparedStatement
-
作用:预编译SQL语句并执行,可以防止SQL注入问题。
-
SQL注入:通过控制输入来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。
@ParameterizedTest //参数化测试//@ValueSource(strings = {"xiaoqiao","123456"}) //代表一个参数分两次测试//所以@ValueSource只适合对一个参数进行测试的@CsvSource(value = {"xiaoqiao, 123456", "zhangsan, ' or '1' = '1"})public void testSelect(String uname,String pwd) throws Exception {//1.准备工作//1.1 注册驱动//Class.forName("com.mysql.cj.jdbc.Driver");//固定步骤//省略注册驱动也可以运行成功,//1.2 获取数据库连接对象ConnectionConnection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/java147_db02", "root", "456789");//1.3 获取SQL语句执行对象Statement -- ?代表占位符PreparedStatement ps = connection.prepareStatement("select * from user where username = ? and password = ?");//1.4设置参数值ps.setString(1,uname);ps.setString(2,pwd);//2.执行SQL语句//需求:根据用户名和密码查询用户信息,模拟用户登录ResultSet resultSet = ps.executeQuery();//判断是否有值while(resultSet.next()) {//输出结果--解析Resulet//int id = resultSet.getInt(1); //下标从1开始int id = resultSet.getInt("id");String username = resultSet.getString("username");String password = resultSet.getString("password");String name = resultSet.getString("name");int age = resultSet.getInt("age");User user = new User(id,username,password,name,age);System.out.println(user);}//3.释放资源ps.close();connection.close();}
在预编译SQL语句中,当我们执行的时候,会把整个' or '1'='1
作为一个完整的参数,赋值给第2个问号(' or '1'='1
进行了转义,只当做字符串使用)
那么此时再查询时,就查询不到对应的数据了,登录失败。
注意:在以后的项目开发中,我们使用的基本全部都是预编译SQL语句。
预编译SQL的优势:
安全(防止SQL注入)
性能更高
PreparedStatement性能更高的主要原因与其预编译机制和数据库的执行优化有关:
1.SQL预编译与重用
PreparedStatement
会在创建时将 SQL 语句发送给数据库进行预编译(解析、优化、生成执行计划),后续执行时只需传入参数即可。
而 Statement
每次执行都需要重新发送完整 SQL、重新编译,这会产生额外的网络传输和数据库解析开销。
对于多次执行相同结构(仅参数不同)的 SQL(如批量插入、更新),PreparedStatement
的预编译结果可以重复使用,大幅减少重复工作。
2.数据库执行计划缓存
数据库通常会缓存预编译生成的执行计划,当再次执行相同 SQL 结构时,可直接复用缓存的计划,避免重复优化和计算,进一步提升效率。
3.参数高效处理
PreparedStatement
通过 setXxx()
方法设置参数,数据库会高效处理参数绑定,避免了字符串拼接 SQL 带来的额外解析成本(例如 Statement
中用 +
拼接参数的字符串操作)。
4.批量操作优化
PreparedStatement
支持 addBatch()
和 executeBatch()
进行批量操作,数据库可以对批量命令进行合并处理,减少网络交互次数和事务提交开销,这在大量数据操作时优势明显。
2.Mybtis基础
2.1 介绍
什么是MyBatis?
-
MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。
-
MyBatis本是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
-
官网:https://mybatis.org/mybatis-3/zh/index.html
在上面我们提到了两个词:一个是持久层,另一个是框架。
-
持久层:指的是就是数据访问层(dao),是用来操作数据库的。
框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。
2.2 快速入门
2.2.1 准备工作
项目工程创建完成后,自动在pom.xml文件中,导入Mybatis依赖和MySQL驱动依赖
<dependencies><!-- Mybatis的起步依赖 --><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency><!-- MySQL驱动 --><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope></dependency><!-- lombok驱动 --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- 单元测试 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
2.2.2 编写SQL语句
在创建出来的springboot工程中,在引导类所在包下,再创建一个包mapper。在,mapper包下创建一个接口UserMapper,这是一个持久层接口(Mybatis的持久层接口规范一般都叫XxxMapper)
UserMapper的内容如下:
import com.itheima.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper //作用:程序启动时,会自动生成该接口的的代理对象,交由IOC容器管理
public interface UserMapper {//查询所有用户数据@Select("select * from user")public List<User> list();
}
@Mapper注解:表示是mybatis中的Mapper接口,在程序运行时,框架会自动生成接口的实现类对象(代理对象),并交给Spring的IOC容器管理
@Select注解:代表的就是select查询,用于书写select查询语句
2.2.3 单元测试
在创建出来的SpringBoot工程中,在src下的test目录下,我们创建测试类UserMapperTest,并且在测试类上已经添加了注解@SpringBootTest,代表该测试类已经与SpringBoot整合。
该测试类在运行时,会自动通过引导类加载Spring的环境(IOC容器(控制反转,对象的创建控制权由程序自身转移到外部(容器),这种思想称为控制反转))。我们要测试上面的bean对象,就可以直接通过@Autowired注解直接将其注入进行,然后就可以测试了。
import com.itheima.entity.User;
import com.itheima.mappeer.UserMapper;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;import java.util.List;@SpringBootTest //作用:会加载Spring环境(IOC容器)
public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testList() {List<User> list = userMapper.list();for (User user : list) {System.out.println(user);}}
}
运行结果:
<span style="background-color:#f8f8f8">User(id=1, username=daqiao, password=1234567890, name=大乔, age=22) User(id=2, username=xiaoqiao, password=123456, name=小乔, age=18) User(id=3, username=diaochan, password=123456, name=貂蝉, age=24) User(id=4, username=lvbu, password=123456, name=吕布, age=28) User(id=5, username=zhaoyun, password=12345678, name=赵云, age=27)</span>
注意:测试类所在包,需要与引导类所在包相同。
如果测试类UserMapperTest类不在com.itheima这个包下,而是被移动到了com.itbaima,此时我们需要在UserMapperTest类里加上(class = SpringbootMybatisQuickstartApplication.class)
@SpringBootTest(classes = SpringbootMybatisQuickstartApplication.class)
//作用:会加载Spring环境(IOC容器)
//@SpringBootTest //作用:会加载Spring环境(IOC容器)
//注意:测试类所在包必须与启动类所在包或子包一致
public class UserMapperTest {@Autowiredprivate UserMapper userMapper;@Testpublic void testList() {List<User> list = userMapper.list();for (User user : list) {System.out.println(user);}}
}
2.3 辅助配置
2.3.1 配置SQL提示
默认我们在UserMapper接口上的 @Select
注解中编写SQL语句是没有提示的。如果想让idea给出提示,可以做如下配置:
配置完成之后,发现SQL语句中的关键字有提示了,但还存在不识别表名(列名)的情况:
产生原因:Idea和数据库没有建立连接,不识别表信息
解决方案:在Idea中配置MySQL数据库连接
注意:该配置的目的,仅仅是为了在编写SQL语句时,有语法提示(写错了会报错),不会影响运行,即使不配置也是可以的。
2.3.2 配置Mybatis的日志输出
默认情况下,在Mybatis中,SQL语句执行时,我们并看不到SQL语句的执行日志。 加入如下配置,即可查看日志:
打开上述开关之后,再次运行单元测试,就可以看到控制台输出的SQL语句是什么样子的。
2.4 JDBC VS Mybatis
JDBC程序的缺点:
-
url、username、password 等相关参数全部硬编码在java代码中。
-
查询结果的解析、封装比较繁琐。
-
每一次操作数据库之前,先获取连接,操作完毕之后,关闭连接。 频繁的获取连接、释放连接造成资源浪费。
分析了JDBC的缺点之后,我们再来看一下在mybatis中,是如何解决这些问题的:
-
数据库连接四要素(驱动、链接、用户名、密码),都配置在springboot默认的配置文件 application.properties中
-
查询结果的解析及封装,由mybatis自动完成映射封装,我们无需关注
-
在mybatis中使用了数据库连接池技术,从而避免了频繁的创建连接、销毁连接而带来的资源浪费。
使用SpringBoot+Mybatis的方式操作数据库,能够提升开发效率、降低资源浪费
而对于Mybatis来说,我们在开发持久层程序操作数据库时,需要重点关注以下两个方面:
1.application.properties
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/web01
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234
2.Mapper接口(编写SQL语句)
@Mapper
public interface UserMapper {@Select("select * from user")public List<User> list();
}
2.5 数据库连接池
前面我们说过mybatis中,使用了数据库连接池技术,避免频繁的创建连接、销毁连接而带来的资源浪费
2.5.1 介绍数据库连接池
没有使用数据库连接池:
- 客户端执行SQL语句:要先创建一个新的连接对象,然后执行SQL语句,SQL语句执行后有需要关闭连接对象来从而释放资源,每次执行SQL时都需要创建连接、销毁连接,这种频繁的重复创建和销毁的过程是比较耗费计算机的性能的。
使用数据库连接池,数据库连接池是一个容器,负责分配,管理数据库连接(Connection)
- 程序在启动时,会在数据库连接池(容器)中创建一定数量的Connection对象允许应用程序重复使用一个现有的数据库连接,而不是重新创建一个
- 客户端在执行SQL时,先从连接池中获取一个Connection对象,然后在执行SQL语句,SQL语句执行完之后,释放Connection时就会把Connection对象归还给连接池(Connection对象可以重复使用)
数据库连接池会自动释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏
最大空闲时间核心作用是:规定一个连接在连接池中保持空闲状态的最长时间。当某个连接的空闲时间超过这个阈值时,连接池会自动将其关闭并从池中移除,释放相关资源。
- 客户端获取到Connection对象了,但是Connection对象并没有去访问数据库(处于空闲),数据库连接池发现Connection对象的空闲时间 > 连接池中预设的最大空闲时间,此时数据库连接池就会自动释放掉这个连接对象
数据库连接池的好处:
资源重用
提升系统响应速度
避免数据库连接遗漏
2.5.2 如何实现数据库连接?
- 官方(sun)提供了数据库连接池标准(javax.sql.DataSource接口)
功能:获取连接
public Connection getConnection() throw SQLException;
常见的数据库连接池:C3P0、DBCP、Druid、Hikari(springboot默认)
现在更多使用的是Druid和Hikari(性能更加优越)
1). Hikari(追光者) [默认的连接池]
2). Druid(德鲁伊)
-
Druid连接池是阿里巴巴开源的数据库连接池项目
-
功能强大,性能优秀,是Java语言最好的数据库连接池之一
如果我们想把默认的数据库连接池切换为Druid数据库连接池,只需要完成一下两步操作即可:
1.在pom.xml文件中引入依赖
<dependency><!-- Druid连接池依赖 --><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.19</version>
</dependency>
2.在application.properties中引入数据库连接配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.druid.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.druid.url=jdbc:mysql://localhost:3306/mybatis
spring.datasource.druid.username=root
spring.datasource.druid.password=1234
2.6 Mybatis的XML配置文件
Mybatis的开发有两种方式:
1.注解
2.XML
2.6.1 XML配置文件规范
使用Mybatis的注解方式主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句,也就是将SQL语句写在XML配置文件中。
在Mybatis中使用XML映射文件方式开发,需要符合一定的规范:
-
XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
-
XML映射文件的namespace属性为Mapper接口全限定名一致
-
XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型resultType一致。
注意:
- 在resources下创建文件夹要用 / 来分级创建,用点并没有分级效果。
- 名称一致指的是全限定名一致,含包名和类名的全称
- resultType如果有返回值就要用实体类的全称(指的是查询返回的单条记录所封装的类型,如User类),如果无返回值就不需要写
2.6.3 MybatisX的使用
可以通过MybatisX快速定位
3.部门列表查询
3.1 功能实现
3.1.1 需求
查询数据库表中的所有部门数据,展示在页面上
3.1.2 实现
1.准备数据库表dept及实体类Dept
-- 部门管理
create table dept(id int unsigned primary key auto_increment comment '主键ID',name varchar(10) not null unique comment '部门名称',create_time datetime comment '创建时间',update_time datetime comment '修改时间'
) comment '部门表';INSERT INTO `dept` VALUES (1,'学工部','2023-09-25 09:47:40','2023-09-25 09:47:40'),(2,'教研部','2023-09-25 09:47:40','2023-09-25 09:47:40'),(3,'咨询部','2023-09-25 09:47:40','2023-09-25 09:47:40'),(4,'就业部','2023-09-25 09:47:40','2023-09-25 09:47:40'),(5,'人事部','2023-09-25 09:47:40','2023-09-25 09:47:40'),(6,'行政部','2023-09-27 14:00:00','2023-09-27 14:00:00'),(7,'综合部','2023-09-25 14:44:19','2023-09-25 14:44:19');
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.time.LocalDateTime;@Data
@NoArgsConstructor
@AllArgsConstructor
public class Dept {private Integer id;private String name;private LocalDateTime createTime;private LocalDateTime updateTime;
}
2.在项目中引入Mybatis的起步依赖,mysql的驱动包
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version>
</dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency>
3.在项目的application.properties 中引入Mybatis的配置信息 (数据库连接、日志输出)
#数据库连接信息
spring.datasource.url=jdbc:mysql://localhost:3306/web01
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root@1234#mybatis 日志
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
4.定义mapper包,并且定义DeptMapper接口,并声明接口方法。
import com.itheima.pojo.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;@Mapper
public interface DeptMapper {@Select("select * from dept")public List<Dept> list();}
5.改造之前编写的dao、service的代码,在service实现中注入mapper接口
-
dao层的代码不需要了(备份之后,可以删除)
-
service层的代码,需要注入Mapper接口,调用mapper接口方法查询数据库中的数据
package com.itheima.service.impl;import com.itheima.entity.Dept;
import com.itheima.mapper.DeptMapper;
import com.itheima.service.DeptService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;/*** 业务逻辑处理层*/@Service
public class DeptServiceImpl implements DeptService {@Autowired //从IOC容器中,自动寻找bean对象,为该变量赋值--依赖注入DI的实现private DeptMapper deptMapper;public List<Dept> list(){//1.调用mapper的方法,获取列表数据并返回return deptMapper.list();}
}
6.启动服务,打开apifox进行测试
经过测试,我们发现,创建时间 createTime,修改时间 updateTime 属性并未成功封装。 接下来,我们就需要来处理数据封装问题。
3.2 数据封装
我们看到查询返回的结果中大部分字段是有值的,但是createTime,updateTime这两个字段是没有值的,而数据库中是有对应的字段值的,这是为什么呢?
原因:
- 实体类属性名和数据库表查询返回的字段名一致,mybatis会自动封装。
-
如果实体类属性名和数据库表查询返回的字段名不一致,不能自动封装。
解决方案:
-
起别名
-
结果映射
-
开启驼峰命名
package com.itheima.mapper;import com.itheima.entity.Dept;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface DeptMapper {/*** 查询所有部门信息** @return*///数据封装方式一:手动结果映射
// @Results({
// @Result(column = "create_time", property = "createtime"),
// @Result(column = "update_time", property = "updatetime")
// })//数据封装方式二:起别名//@Select("select id, name, create_time createTime, update_time updateTime from dept")//数据封装方式三:全局配置,开启驼峰命名规则映射@Select("select * from dept")public List<Dept> list();
}
3.开启驼峰命名(推荐):如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射
驼峰命名规则: abc_xyz => abcXyz
表中字段名:abc_xyz
类中属性名:abcXyz
# 在application.properties中添加:
mybatis.configuration.map-underscore-to-camel-case=true
要使用驼峰命名前提是 实体类的属性 与 数据库表中的字段名严格遵守驼峰命名。