目录
第五步:在mybatis下面新建一个UserMapper.xml的文件夹
resultType属性:用于标记返回的是什么类型,同时指定返回的对象是哪个
第一步:在UserMapper当中编写一个根据id查询用户对象的方法
第一步:在UserMapper当中新建一个以User为参数的方法
第三步:在测试类当中使用@Autowired来获取bean进行测试
如何避免测试的数据影响正常数据库的数据(@Test @Transactional)
一、Mybatis是什么
mybatis是一款优秀的持久层框架(主要与数据库层,也就是mysql层打交道的),它支持自定义sql、存储过程以及数据库对应到实体的映射等等。
也就是把数据库当中的每一行记录与对象建立起来映射的关系。
三个映射关系如下图:
数据库当中的属性 | Java程序当中的属性 |
数据库表(table) | 类(class) |
记录(record) | 对象(object) |
字段(field) | 对象的属性(attribute) |
二、mybatis的使用(前置工作+简单案例)
第一步:导入MAVEN依赖
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
第二步: 在spring项目当中新建数据源
下面我选择的是application.properties文件配置的
需要在resource目录下面新建一个文件夹,文件夹的名称被命名为:mybatis。
后续的xml配置文件就需要在这个mybatis文件夹当中编写了。
配置文件的内容:
spring.datasource.url=jdbc:mysql://localhost:3306/my_blog_system?characterEncoding=utf8&useSSL=false
spring.datasource.username=root
spring.datasource.password=20021111aA#
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
############设置mybatis的保存路径
mybatis.mapper-locations=classpath:/mybatis/*Mapper.xml
第三步:新建一个实体类,是和数据库进行交互的实体类
在这个类当中,需要满足上面的一一对应的关系。
/**
* @author 25043
*/
@Data
public class User {
private int id;
private String username;
private String password;
}
第四步:新建一个mapper文件夹(src目录下面)
这个文件夹用于存放和数据库进行直接交互的实体类,但是这些类一般都是接口,我们只需要在这些接口当中定义一些方法即可。
例如在下面这个类当中,定义一个查询所有用户的方法:
/**
* 使用这个注解,标记这个类是一个持久层的类
* @author 25043
*/
@Mapper
public interface UserMapper {
/**
* 查询所有用户
* 查询用户@return
*/
List<User> getAll();
}
第五步:在mybatis下面新建一个UserMapper.xml的文件夹
在这个文件夹当中,黏贴下面的内容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybati
s.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.springLearning.Mapper.UserMapper">
</mapper>
需要注意的是:mapper namespace这个标签的内容为需要返回的User对象的全限定名。
第六步:在两个mapper标签之间编写查询的sql语句
其中,select标签为查询标签,其余的还有update标签(用于修改),指定的id为查询的方法
以及insert标签,用于新增。
<mapper namespace="com.example.springLearning.Mapper.UserMapper">
<select id="getAll" resultType="com.example.springLearning.Entity.User">
select *from user
</select>
</mapper>
resultType属性:用于标记返回的是什么类型,同时指定返回的对象是哪个
第七步:在其他类当中调用getAll方法
需要注意的是,其他类调用的时候,一定要确保
@Service
public class UserServiceImpl implements UserService {
@Autowired
private UserMapper userMapper;
public List<User> getAll(){
return userMapper.getAll();
}
}
总结一下,mybatis的执行流程:
三、复杂操作
3.1根据id查询用户对象
第一步:在UserMapper当中编写一个根据id查询用户对象的方法
/**
* 根据id查询用户
* 用户的id@param id
* 单个实体用户@return
*/
User getUserById(@Param("id") Integer id);
第二步:在配置文件当中编写查询的方法
<select id="getUserById" resultType="com.example.springLearning.Entity.User">
select *from user where userId=${id};
</select>
mybatis两种占位符:$和#的区别
占位符 | 主要区别 | 优缺点 |
${} | 直接替换,相当于直接拼接 | ①不可以解决sql注入; ②当查询的数据类型需要手动添加引号的时候,会报错(因为是直接拼接数据) |
#{} | 占位符,也就是"?"进行替换 | ①可以解决sql注入; ②无需手动添加引号。 |
3.2把一个对象作为参数进行传递
第一步:在UserMapper当中新建一个以User为参数的方法
/**
* 处理用户登录
* 用户对象@param user
* 用户对象@return
*/
User login(User user);
第二步:在配置文件当中直接获取user的属性
第三步:进行测试
@Test
void login() {
User user=new User();
user.setUsername("zhangSan");
user.setPassword("123");
User userGet=userMapper.login(user);
System.out.println(userGet);
}
3.3删改的操作
第一步:在mapper层编写增删改的方法
/**
* 删除user
* user对象@param user
* 删除@return
*/
Integer delete(User user);
注意这里的返回值一定要设置为包装类型,不可以是基本数据类型
第二步:在xml文件当中配置增删改的方法(无需返回值)
和查询操作类似,但是无需在标签当中指定resultType。
<delete id="delete">
delete from user where username=#{username};
</delete>
第三步: 编写测试的方法
@Test
void testInsert(){
User user=new User();
user.setUsername("lisi");
userMapper.delete(user);
}
3.4新增数据操作(以新增一个User对象为例)
第一步:在mapper当中新建一个方法:
Integer insert(User user);
第二步:在xml文件当中配置一个新增方法
<!--返回影响行数-->
<insert id="insert">
insert into user(username,password) values(#{username},#{password});
</insert>
第三步:新建一个方法用于测试
public int insert(User user){
return userMapper.insert(user);
}
3.4新增数据并且返回这个新增数据的主键
第一步:在mapper当中新建一个方法:
/**
* 新增用户
* 新增的用户对象@param user
* 影响的行数@return
*/
Integer insertUserGetId(User user);
第二步:在xml文件当中配置一个新增方法
useGeneratedKeys属性设置为true的含义是自动生成主键id,keyProperty指的是把主键作为实体类当中的某一个字段。
<!--新增一个user,并且返回主键id,注意useGeneratedKeys属性设置为true的含义是自动生成主键id,keyProperty指的是把主键作为实体类当中的某一个字段-->
<insert id="insertUserGetId" useGeneratedKeys="true" keyProperty="userId">
insert into user(username,password) values(#{username},#{password});
</insert>
第三步:新建一个方法用于测试
@Test
void insertUserGetId() {
User user=new User();
user.setUsername("123");
user.setPassword("456");
//方法的返回值为insert影响的行数
int result=userMapper.insertUserGetId(user);
//userId为实体类的主键
int userId=user.getUserId();
System.out.println("result:"+result+"; userId:"+userId);
}
运行之后,可以看到result输出的结果为1;userId为:15(数据库当中的主键Id)
3.5模糊查询
第一步:在UserMapper当中新建一个方法
/**
* 根据username模糊查询
* 用户名@param username
* user集合@return
*/
List<User> getUserListByName(@Param("username") String username);
第二步:在xml文件当中配置查询的sql语句
在下面的sql语句当中,采用concat来进行拼接,拼接的内容为:%+查询的内容+%;
<select id="getUserListByName" resultType="com.example.springLearning.Entity.User">
select *from user where username like concat('%',#{username},'%');
</select>
四、springBoot单元测试
4.1添加springBoot的测试依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
4.2生成需要测试方法的测试等价类
第一步:右键需要测试的方法,然后生成get和set方法
然后,就可以看到生成了测试的目录,并且在测试的目录下面生成了这样的代码:
第二步:为测试类添加@SpringBootTest注解
第三步:在测试类当中使用@Autowired来获取bean进行测试
@SpringBootTest
class UserServiceImplTest {
@Autowired
private UserMapper userMapper;
@Test
void getAll() {
}
@Test
void getUserById() {
User user=userMapper.getUserById(2);
System.out.println(user);
}
}
如何避免测试的数据影响正常数据库的数据(@Test @Transactional)
只需要在一个测试的方法上面标注:@Test注解加上@Transactional两个注解即可。
@Test
@Transactional
void testInsert(){
User user=new User();
user.setUsername("张三");
userMapper.delete(user);
}
这样子,即使插入了数据,也会在方法调用结束之后,回滚事物。