学习目标
数据持久层操作
1.复习JDBC(Java DataBase Connectivity)
java操作数据库的基本规范(API)
2.Spring整合Mybatis
3.SpringBoot整合Mybatis Plus
今日所学
更新项目目录
JDBC
Connection:连接接口
Statement:命令对象
PreparedStatement:预编译命令
ResultSet:结果集对象
public class JdbcDemo{
Connection connection;
PreparedStatement preparedStatement;
@Before
public void init(){
//创建驱动
Class.forName("com.sql.cj.jdbc.Driver");
//建立连接
String url = "";
String username = "root";
String password = "12345678";
connection = DriverManager.getConnection(url,username,password);
}
/**
*单元测试Junit
*/
@Test
public void Update() throws Exception{
preparedStatement = connection.prepareStatement("insert into tb_**() values(?,?,?)");
preparedStatement.setObject();
int i = preparedStatement.executeUpdate();//修改
System.out.println("影响的行数:"+i);
}
}
DataSource
数据源
把URL+username+password封装
类型
数据源
定义位置
定义在javax.sql包
为什么要引入数据源对象
因为Spring框架的使用,用于管理bean
Spring通过对于DataBase类型的bean的创建和管理,完成对mysql数据库的连接
@Test
public void testDataSource(){
MysqlDatasource mysqlDatasource = new MysqlDatasource();
mysqlDatasource.setUrl(url);
mysqlDatasource.setUser(username);
mysqlDatasource.setPassword(password);
Connection connection = mysqlDatasource.getConnection();
}
为了简化和封装对于数据库的操作提出:DAO和ORM
DAO:Data Access Object 数据访问对象
ORM:Object Relation Mapping 对象关系映射
Mybatis:就是一个ORM框架,此外还有Hibernate
(JPA
Java Persistent API)
Mybatis使用流程
1.建立数据表和实体类之间的映射关系(两种方式)
配置文件方式
<resultMap>
</resultMap>
注释方式
@TableName(tb_user)
@TableId(value="id")
@TableField("name")
2.创建DAO的接口
UserMapper
public interface UserMapper{
User getByid(Integer id);
Liat<User> list;
List<User> page(Integer page,Integer size);
void inser(User);
}
//mybatis的核心应用
//sqlSessionFactoryBuilder -> sqlSessionFactory -> sqlSession
UserMapper userMapper = sqlSession.getMapper(userMapper.class);
@Test
public void testsqlSession(){
SqlSession sqlSession = null;
UserMapper userMapper = sqlSession.getMapper(userMapper.class);
}
<select id="getByid" paramterType="it">
select * from tb_user where id = #{id}
</select>
<insert>
...
</insert>
动态代理
分类
jdk
动态代理和cglib
动态代理
目标
动态生成接口或抽象类(类)的实例,同时对目标方法进行增强
区别
jdk动态代理是java自己提供的动态代理方式,cglib是第三方方案
jdk动态代理代理的目标是接口,cglib代理目标是接口或类
jdk动态代理的核心是通过Proxy代理类,cglib动态代理的核心是Enhancer
通过SpringBoot
整合Mybatis-Plus
Mybatis和Mybatis- Plus的关系
Mybatis是框架
Mybatis- Plus是基于框架之上的增强技术 https://baomidou.com
注意事项
1.必须基于mybatis才是mp
2.mp的配置和mybatis的配置完全一样
3.mp的dao也需要声明Mapper
4.mp针对单表的crud提供了大量的API
使用方法
1.导入依赖
//mp的核心依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.2</version>
</dependency>
2.配置工作
#mybatis- plus的相关配置
mybatis-plus:
configuration:
#开启驼峰命名的自动转换:将数据库中的user_id自动匹配到java中的userId(但其实这样并不符合java中命名规范)
map-underscore-to-camel-case: true
#将mybatis的执行过程(sql)打印在控制台上
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
#当所有字段值都为NULL时返回空对象,User(id=null,name=null)
return-instance-for-empty-row: true
#mapper映射文件所在的位置
mapper-locations: classpath*:mapper/**/*.xml
#别名所在的包,可以简化class属性的声明过程
type-aliases-package: com.gxa.agriculture.entity.pojo
3.数据库连接池配置
导入依赖
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.1.18</version>
</dependency>
准备实体类
通过实体类建立与数据表的映射关系
@Data
@TableName("tb_user")
public class User implements Serializable {
@TableId(value = "id",type = IdType.ASSIGN_ID)
private Integer id;
@TableField("name")
private String name;
@TableField("phone")
private String phone;
@TableField("pwd")
private String pwd;
@TableField("points")
private Integer points;
@TableField("reg_time")
private Date regTime;
@TableField("deleted")
private Boolean deleted;
}
准备Mapper
声明业务所需的Mapper接口,并基层Mp提供的BaseMapper父接口
public interface UserMapper extends BaseMapper<User> {
}
4.在Spring中声明@MapperScan
声明在主启动类中
@MapperScan(basePackages = "com.gxa.agriculture.mapper")
public class MainApp(){
...
}
5.测试UserMapper调用API
导入依赖
这样就可以使用@Test注解
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
测试代码
@SpringBootTest(classes = MainApp.class)
@RunWith(SpringRunner.class)
class UserMapperTest {
@Autowired
private UserMapper userMapper;
//查询测试
@Test
public void testSelectById(){
User user = userMapper.selectById(1);
System.out.println(user);
}
//删除测试
@Test
public void testDelete(){
int i = userMapper.deleteById(100);
System.out.println(i);
}
//增加测试
@Test
public void testInsert(){
User user = new User();
user.setName("肖恩");
user.setId(100);
user.setPhone("1234321");
user.setPwd("123456");
int insert = userMapper.insert(user);
System.out.println(insert);
}
//修改测试
@Test
public void testUpdate(){
User user = new User();
user.setName("小羊肖恩");
user.setId(100);
user.setPhone("1234321");
user.setPwd("123456");
int i = userMapper.updateById(user);
System.out.println(i);
}
}
在这个测试类中,使用了Spring Framework的@SpringBootTest
注解来指定要加载的Spring应用程序的主类MainApp
,并使用@RunWith(SpringRunner.class)
注解来指定使用Spring的测试运行器来运行测试。
@SpringBootTest(classes = MainApp.class)
: 这个注解用于指定要加载的Spring应用程序的主类,即MainApp
类。通过这个注解,测试类可以加载整个Spring应用程序上下文,以便在测试中能够使用Spring的依赖注入和其他功能。@RunWith(SpringRunner.class)
: 这个注解指定了使用Spring的测试运行器来运行测试。SpringRunner
是Spring提供的一个JUnit运行器,用于在测试中提供Spring的功能支持,如依赖注入、事务管理等。@Autowired
:@Autowired
注解用于自动装配接口类型时,Spring会根据接口的实现类来注入实际的对象,从而实现依赖注入的功能。在这段代码中,UserMapper
是一个接口,而具体的实现类(可能是通过MyBatis或其他ORM框架生成的)会在运行时被Spring容器实例化。通过@Autowired
注解,Spring会自动查找UserMapper
接口的实现类,并将其注入到测试类中的userMapper
字段。这样,测试类就可以直接调用UserMapper
接口中定义的方法来进行数据库操作,而无需关心具体的实现类是什么。
需要注意的是,UserMapper
接口本身并不是一个实例化对象,而是一个接口定义,定义了对用户数据的操作方法。要让UserMapper
接口的方法与数据库建立连接并执行相应的操作,通常需要使用ORM框架(如MyBatis)来提供具体的实现。在这种情况下,通过配置ORM框架,Spring会自动为UserMapper
接口创建一个代理对象,该代理对象会实现UserMapper
接口定义的方法,并与数据库进行交互。
因此,通过@Autowired
注入的userMapper
对象实际上是ORM框架生成的代理对象,通过这个代理对象可以调用UserMapper
接口定义的方法(如getById()
、deleteById()
等),从而与数据库进行交互。ORM框架会负责将方法调用转换为对应的SQL操作,并执行数据库操作。
综上所述,通过@Autowired
注解注入UserMapper
接口的实例化对象,实际上是通过ORM框架提供的代理对象与数据库建立连接,并可以使用UserMapper
接口定义的方法来操作数据库。
可能存在的错误
使用@Autowired
即可解决
使用@SpringBootTest(classes = MainApp.class)
和@RunWith(SpringRunner.class)
解决
此外,需要注意的是因为我当时Junit依赖的版本的写的3.8.1,版本过低所以无法写@Runwith注释,所以需要提高pom.xml中Junit版本
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
拓展
了解Hibernate的特点
Hibernate是一个开源的对象关系映射(ORM)框架,它提供了将Java对象映射到关系型数据库表的功能,简化了在Java应用程序中操作数据库的过程。Hibernate具有以下特点:
-
简化数据库操作:Hibernate通过对象关系映射(ORM)的方式,将Java对象和数据库表进行映射,使得开发人员可以直接操作Java对象,而不需要编写复杂的SQL语句。
-
提供对象导航:Hibernate允许在对象之间建立关联关系,通过对象导航可以方便地访问和操作相关联的对象。
-
自动维护对象状态:Hibernate可以自动跟踪对象的状态(持久态、游离态、临时态),并在合适的时机同步到数据库中,简化了数据持久化的管理。
-
支持事务管理:Hibernate提供了事务管理功能,可以保证数据库操作的原子性、一致性、隔离性和持久性(ACID特性)。
-
支持缓存机制:Hibernate提供了一级缓存和二级缓存机制,可以提高数据库访问性能,减少数据库访问次数。
-
支持延迟加载:Hibernate支持延迟加载(Lazy Loading)机制,可以在需要时才加载相关联的对象,提高系统性能。
-
跨数据库平台:Hibernate支持多种数据库平台,可以在不同的数据库系统中使用相同的Hibernate代码。
-
提供查询语言HQL:Hibernate提供了Hibernate Query Language(HQL),类似于SQL语句,用于查询数据库中的数据,支持面向对象的查询。
Hibernate和Mybatis对比
Hibernate和MyBatis都是Java中常用的持久层框架,但它们在设计理念、使用方式和特点上有一些区别。下面是Hibernate和MyBatis的对比:
- 设计理念:
- Hibernate是一个
全自动
的ORM框架,它通过对象关系映射
将Java对象和数据库表进行映射,开发人员可以直接操作Java对象,而不需要编写SQL语句。 - MyBatis是一个
半自动
的ORM框架,它使用XML文件
或注解
来配置SQL语句和映射关系,开发人员需要编写SQL语句,但可以更细粒度地控制SQL语句的执行。
- Hibernate是一个
- 灵活性:
- MyBatis相对于Hibernate更加灵活,开发人员可以自由地编写SQL语句,控制SQL的执行过程,适用于需要定制化SQL操作的场景。
- Hibernate提供了更高级的抽象,隐藏了大部分SQL细节,适用于快速开发和简单的CRUD操作。
- 性能:
- MyBatis在性能上通常比Hibernate更好,因为开发人员可以优化SQL语句,避免不必要的查询,提高数据库访问效率。
- Hibernate的自动化查询和关联处理可能会导致性能损失,特别是在处理复杂查询和大量数据时。
- 适用场景:
- MyBatis适用于需要定制SQL语句和对SQL有较高要求的场景,适合对SQL熟悉的开发人员。
- Hibernate适用于快速开发和简单的CRUD操作,适合对对象关系映射和ORM概念熟悉的开发人员。