整合MyBatis
在pom.xml引入依赖
xml
<!--整合Mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<!--需指定版本,2.2.0也可以-->
<version>2.2.2</version>
</dependency>
<!--连接mysql的驱动包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>在application.yaml文件中配置数据库连接
yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC
username: root
password: yuxingxuan
mybatis:
# 将目标目录下的bean都设置别名,方便后面在xxxMapper.xml中使用
type-aliases-package: com.atguigu.boot.pojo
# 开启驼峰命名规则自动转换
configuration: # 也可以直接加载全局配置文件——classpath:mybatis-config.xml
map-underscore-to-camel-case: true创建User.java
java
package com.atguigu.boot.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
@AllArgsConstructor
@Data
public class User {
private Integer id;
private String name;
private String password;
}创建UserDao.java
java
package com.atguigu.boot.Dao;
import com.atguigu.boot.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
@Mapper //给mapper接口自动生成一个实现类,让Spring对mapper接口的bean进行管理,并且可以省略去写复杂的xml文件
public interface UserDao {
@Select("select * from users where id = #{id}") //IOC容器会自动匹配使用对应的Bean去匹配
User selectById(@Param("id") Integer id);
@Update("update users set name = #{name},password = #{password} where id = #{id}")
int update(User user);
}通过@Mapper可以让IOC容器获取到Mappre接口的实现类,从而通过自动装配可以直接调用
测试功能
java
@Resource
private UserDao userDao;
@Test
public void testUserDao(){
System.out.println(userDao.selectById(2)); //返回查询结果
System.out.println(userDao.update(new User(2,"jack","123"))); //返回受影响的行数
}关于@Mapper和Mapper.xml
@Mapper和Mapper.xml两者是可以共存的,但它们不能同时应用于同一个方法上,也就是说,对于同一个方法,只能选择注解方式或XML配置方式之一
@Mapper虽然可以简化开发,但是需要使用
@Select和<script>实现动态sql,使用xml的方式可以更为简洁明了的实现动态sql
与UserDao.java同包名(默认开启了同包下匹配),在resources目录下创建UserDao.xml
xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.atguigu.boot.Dao.UserDao">
<select id="selectById" resultType="User">
select * from users where id = #{id}
</select>
</mapper>对象模型
- POJO(Plain Old Java Object):最基本的Java对象,是一个简单的、传统的Java对象,不包含任何特定的框架或业务逻辑。POJO通常用来表示数据库中的一条记录,它强调的是简单的属性和getter/setter方法
- Entity:通常与数据库表一一对应,是JPA(Java Persistence API)中的一个概念,用于持久化到数据库。Entity类通常使用注解来定义映射关系,如
@Entity、@Table、@Column等 - Domain:领域模型,通常指代业务逻辑相关的对象,它不仅包含数据(状态),还包含操作数据的行为(方法)。在DDD(领域驱动设计)中,Domain对象是核心
- DTO(Data Transfer Object):用于在不同层之间传输数据,尤其是在跨进程或网络调用时。DTO减少了对远程接口的调用次数,它通常包含类的getter/setter方法,没有业务逻辑
- VO(Value Object):代表数据传输对象的一种形式,通常用于表示UI层需要展示的数据。VO中通常不包含业务逻辑,只是数据的容器
- BO(Business Object):封装业务逻辑的对象,可以包含多个DTO或Entity。BO主要用于服务层,将业务逻辑封装在一个对象中
- DO(Data Object):与DTO类似,用于在进程内传递数据,但DO更侧重于数据本身,而不是数据的传输。通常在数据访问层和业务逻辑层之间使用
注解开发
@One:用于分步查询,将分步查询的结果映射为一个pojo对象(javaType = User.class)- xml
<!-- association:处理多对一的映射关系(处理实体类类型的属性) property:设置需要处理映射关系的属性的属性名 javaType:设置要处理的属性的类型 --> <association property="dept" javaType="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> </association>
@Many:用于分步查询,将分步查询的结果保存为集合对象(javaType = List.class)- xml
<!--将查出来的值depy_id作为下一步查询的参数--> <collection property="emps" select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpStepTwo" column="dept_id"></collection>
可以手动映射复杂的pojo对象,但是无法直接处理对象中的查询的结果集(orderList),即
@Many注解无法使用@Result代替。如果映射对象本身就为结果集(UserAndOrder),就只要将方法的返回结果定义为List即可- java
// 手动映射复杂对象 // id为true表示为主键 @Result(id = true, property = "user.id", column = "id"), @Result(property = "user.name", column = "name"), @Result(property = "user.password", column = "password"),
UserAndOrder.java
java
public class UserAndOrder {
private Integer createUser;
private User user;
private List<Order> orderList;
}Mapper.java
java
@Select("select id,name,password,create_user FROM tb_users where tb_users.id=#{id}")
@Results({
@Result(property = "createUser", column = "create_user"),
// 手动映射复杂对象
// id为true表示为主键
// @Result(id = true, property = "user.id", column = "id"),
// @Result(property = "user.name", column = "name"),
// @Result(property = "user.password", column = "password"),
// 使用分步查询(column代表从数据库提取的字段)
@Result(property = "user", column = "id",
javaType = User.class,
one = @One(select = "com.atguigu.boot.Mapper.UserMapper.getUserById")
),
// 映射多个结果集
@Result(property = "orderList", column = "id",
javaType = List.class,
many = @Many(select = "com.atguigu.boot.Mapper.UserMapper.getOrderListByUserId")
)
})
UserAndOrder getUserAndOrder(@Param("id") String id);
@Select("select order_id,user_id,order_name from tb_orders where user_id = #{userId}")
Order getOrderListByUserId(@Param("userId") String userId);
@Select("select id,name,password,create_user FROM tb_users where tb_users.id=#{id}")
User getUserById(@Param("userId") String userId);==> Preparing: select id,name,password,create_user FROM tb_users where tb_users.id=? ==> Parameters: 1(String) <== Columns: id, name, password, create_user <== Row: 1, yuuuuu, 123456, 1 ====> Preparing: select id,name,password,create_user FROM tb_users where tb_users.id=? ====> Parameters: 1(String) <==== Columns: id, name, password, create_user <==== Row: 1, yuuuuu, 123456, 1 <==== Total: 1 ====> Preparing: select order_id,user_id,order_name from tb_orders where user_id = ? ====> Parameters: 1(String) <==== Columns: order_id, user_id, order_name <==== Row: 1, 1, 测试 <==== Row: 2, 1, 测试1 <==== Total: 2 <== Total: 1json{ "code": 1, "msg": null, "data": { "createUser": 1, "user": { "id": 1, "name": "yuuuuu", "password": "123456" }, "orderList": [ { "orderId": 1, "userId": 1, "orderName": "测试" }, { "orderId": 2, "userId": 1, "orderName": "测试1" } ] }, "map": {} }
