ssm之MyBatis(6)注解开发

数据准备

数据库表

DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (
  `id` int NOT NULL AUTO_INCREMENT COMMENT '用户id',
  `username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `password` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `birthday` datetime NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `user` VALUES (1, 'xrkhy', '0000', NULL);
INSERT INTO `user` VALUES (2, 'gtxy', '0000', NULL);
INSERT INTO `user` VALUES (3, 'mll', '0000', NULL);
INSERT INTO `user` VALUES (4, 'fbpc', '0000', NULL);
INSERT INTO `user` VALUES (7, 'hsh', '123', NULL);

DROP TABLE IF EXISTS `orders`;
CREATE TABLE `orders`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `ordertime` datetime NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP,
  `total` int NULL DEFAULT NULL,
  `uid` int NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `orders` VALUES (1, '2025-07-30 19:44:07', 3000, 1);
INSERT INTO `orders` VALUES (2, '2025-07-25 19:44:34', 5800, 1);
INSERT INTO `orders` VALUES (3, '2025-07-10 19:44:51', 323, 2);
INSERT INTO `orders` VALUES (4, '2025-07-13 19:45:04', 2345, 1);
INSERT INTO `orders` VALUES (5, '2025-07-15 19:45:36', 100, 2);
INSERT INTO `orders` VALUES (6, '2025-07-26 19:45:50', 2009, 3);


DROP TABLE IF EXISTS `userrole`;
CREATE TABLE `userrole`  (
  `userId` int NOT NULL,
  `roleId` int NOT NULL,
  PRIMARY KEY (`userId`, `roleId`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `userrole` VALUES (1, 1);
INSERT INTO `userrole` VALUES (1, 2);
INSERT INTO `userrole` VALUES (2, 2);
INSERT INTO `userrole` VALUES (2, 3);


DROP TABLE IF EXISTS `role`;
CREATE TABLE `role`  (
  `id` int NOT NULL AUTO_INCREMENT,
  `roleName` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  `roleDesc` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,
  PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;

INSERT INTO `role` VALUES (1, '院长', '负责全面工作');
INSERT INTO `role` VALUES (2, '研究员', '课程研发工作');
INSERT INTO `role` VALUES (3, '讲师', '授课工作');
INSERT INTO `role` VALUES (4, '助教', '协助解决学生问题');
INSERT INTO `role` VALUES (5, '班主任', '负责学生生活');
INSERT INTO `role` VALUES (6, '就业指导', '负责学生就业工作');

pom.xml

<dependencies>
    <!--JDBC-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>8.0.33</version>
    </dependency>
    <!-- mybatis -->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.13</version>
    </dependency>

    <!--Spring 6默认不再绑定Log4j 1.x,建议使用Log4j 2.x(性能更强、安全性更高)。-->
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-core</artifactId>
      <version>2.23.1</version>
    </dependency>
    <dependency>
      <groupId>org.apache.logging.log4j</groupId>
      <artifactId>log4j-slf4j2-impl</artifactId>
      <version>2.23.1</version>
    </dependency>
    <!-- 单元测试 -->
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <scope>test</scope>
    </dependency>

    <!-- lombok -->
    <dependency>
      <groupId>org.projectlombok</groupId>
      <artifactId>lombok</artifactId>
      <version>1.18.38</version>
      <scope>provided</scope>
    </dependency>
    
  </dependencies>

resources

JDBC.properties

# 数据库驱动
jdbc.driver=com.mysql.cj.jdbc.Driver
# 数据库地址
jdbc.url=jdbc:mysql://127.0.0.1:3306/test?useUnicode=true&characterEncoding=utf-8&useSSL=false
# 用户名
jdbc.username=root
# 密码
jdbc.password=root

sqlMapConfig.xml

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>

    <!-- 加载外部配置文件 -->
    <properties resource="JDBC.properties"></properties>

    <settings>
        <!-- value="STDOUT_LOGGING" 配置打印SQL语句 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>


    <typeAliases>
        <!-- 单个创建别名 -->
        <!-- 需手动指定别名,通过type属性设置类的全限定名,alias属性设置自定义别名-->
        <typeAlias type="com.hsh.pojo.User" alias="User"></typeAlias>
        <!-- 批量创建别名 -->
        <!-- 自动扫描包路径下所有类,默认以类名(不区分大小写)作为别名 -->
        <package name="com.hsh.pojo"/>
    </typeAliases>

    <!-- default: 指定默认环境的名称 -->
    <environments default="development">
        <!-- id="development": 指定当前环境的名称 -->
        <environment id="development">
            <!-- type="JDBC": 指定事务管理类型是JDBC -->
            <transactionManager type="JDBC"/>
            <!-- type="POOLED": 指定当前数据源类型是连接池 -->
            <dataSource type="POOLED">
                <!-- 数据源配置的基本参数 -->
                <property name="driver" value="${jdbc.driver}"/>
                <property name="url" value="${jdbc.url}"/>
                <property name="username" value="${jdbc.username}"/>
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!-- 加载上面的UserMapper映射文件 -->
        <mapper resource="com/hsh/mapper/UserMapper.xml"/>
        <mapper resource="com/hsh/mapper/OrderMapper.xml"/>
    </mappers>
</configuration>

com/hsh/mapper/UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hsh.mapper.UserMapper">


</mapper>

com/hsh/mapper/OrderMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hsh.mapper.OrderMapper">


</mapper>

pojo层

User

package com.hsh.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
    private Integer id;
    private String username;
    private String password;
    private Date birthday;
    private List<Order> orderList;
    private List<Role> roleList;
}

Order

package com.hsh.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import java.util.Date;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Order {
    private Integer id;
    private Date orderTime;
    private Integer total;
    private User user;

}

Role

package com.hsh.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@Data
@AllArgsConstructor
@NoArgsConstructor
public class Role {
    private Integer id;
    private String roleName;
    private String roleDesc;
}

Mapper层

UserMapper

package com.hsh.mapper;

import com.hsh.pojo.User;

import java.util.List;

public interface UserMapper {
    void  save(User user);
    void update(User user);
    void delete(Integer id);
    User findById(Integer id);
    List<User> findAll();
}

OrderMapper

public interface OrderMapper {
    
}

Test

OrderMapperTest

public class OrderMapperTest {

}

UserMapperTest

public class UserMapperTest {
package mapper;

import com.hsh.mapper.UserMapper;
import com.hsh.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

/**
 * @author xrkhy
 * @date 2025/7/31 20:07
 * @description
 */
public class UserMappeTest {
    private UserMapper userMapper;
    @Before
    public void setUp() throws Exception {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void save() throws Exception {
        User user = new User();
        user.setUsername("hsh");
        user.setPassword("123456");
        userMapper.save(user);
    }

    @Test
    public void update() throws Exception {
        User user = new User();
        user.setId(7);
        user.setUsername("hsh");
        user.setPassword("123456");
        userMapper.update(user);
    }

    @Test
    public void delete() throws Exception {
        userMapper.delete(7);
    }

    @Test
    public void findById() throws Exception {
        User user = userMapper.findById(1);
        System.out.println(user);
    }
    @Test
    public void findAll() throws Exception {
        List<User> users = userMapper.findAll();
        users.forEach(System.out::println);
    }
}

目录如下

在这里插入图片描述

MyBatis的常用注解

这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装

MyBatis的简单增删改查

修改sqlMapConfig.xml

修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可。

<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
	<!-- 省略....... -->
	
    <mappers>
        <!-- 加载上面的UserMapper映射文件 这个注释掉,-->
        <!-- <mapper resource="com/hsh/mapper/UserMapper.xml"/>-->
        <!-- <mapper resource="com/hsh/mapper/OrderMapper.xml"/>-->

        <!--扫描使用注解的类 开启注解 -->
        <!-- <mapper class="com.hsh.mapper.UserMapper"></mapper>-->
        <!--扫描使用注解的类所在的包 或者使用下面这个开启注解 -->
        <package name="com.hsh.mapper"></package>
    </mappers>
    
</configuration>

注释掉UserMapper.xml中所有

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.hsh.mapper.UserMapper">
    <!--全注释-->

</mapper>

编写UserMapper

package com.hsh.mapper;

import com.hsh.pojo.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface UserMapper {
    @Insert("insert into user values(null,#{username},#{password},#{birthday})")
    void  save(User user);
    @Update("update user set username = #{username},password = #{password},birthday = #{birthday} where id = #{id}")
    void update(User user);
    @Delete("delete from user where id = #{id}")
    void delete(Integer id);
    @Select("select * from user where id = #{id}")
    User findById(Integer id);
    @Select("select * from user")
    List<User> findAll();
}

依次运行测试类

package mapper;

import com.hsh.mapper.UserMapper;
import com.hsh.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;

import java.io.InputStream;
import java.util.List;

/**
 * @author xrkhy
 * @date 2025/7/31 20:07
 * @description
 */
public class UserMappeTest {
    private UserMapper userMapper;
    @Before
    public void setUp() throws Exception {
        InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = sqlSessionFactory.openSession(true);
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    @Test
    public void save() throws Exception {
        User user = new User();
        user.setUsername("hsh");
        user.setPassword("123456");
        userMapper.save(user);
    }

    @Test
    public void update() throws Exception {
        User user = new User();
        user.setId(7);
        user.setUsername("hsh");
        user.setPassword("123456");
        userMapper.update(user);
    }

    @Test
    public void delete() throws Exception {
        userMapper.delete(7);
    }

    @Test
    public void findById() throws Exception {
        User user = userMapper.findById(1);
        System.out.println(user);
    }
    @Test
    public void findAll() throws Exception {
        List<User> users = userMapper.findAll();
        users.forEach(System.out::println);
    }
}

结果都能正常运行

MyBatis的注解实现复杂映射开发

实现复杂关系映射之前我们可以在映射文件中通过配置来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置

注解说明
@Results代替的是标签<resultMap>该注解中可以使用单个@Result注解,也可以使用@Result集 合。使用格式:@Results({@Result(),@Result()})@Results(@Result())
@Resut代替了<id>标签和<result>标签 @Result中属性介绍: column:数据库的列名 property:需要装配的属性名 one:需要使用的@One注解(@Result(one=@One)())) many:需要使用的@Many注解(@Result(many=@many)()))
注解说明
@ One ( 一 对 一 )代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。 @One注解属性介绍: select:指定用来多表查询的sqlmapper 使用格式:@Result(column=“”,property=“”,one=@One(select=“”))
@Many(多对 一 )代替了<collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。 使用格式:@Result(property=“”,column=“”,many=@Many(select=“”))

1 一对一查询

1. 一对一查询的模型

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
在这里插入图片描述

2. 一对一查询的语句

对应的sql语句:

select * from orders;
select * from user where id=查询出订单的uid;

查询的结果如下:
在这里插入图片描述

3. 创建Order和User实体

在这里插入图片描述

4. 创建OrderMapper接口

public interface OrderMapper {
	List<Order> findAll();
}

5. 使用注解配置Mapper

在这里插入图片描述

package com.hsh.mapper;

import com.hsh.pojo.Order;
import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import java.util.List;

public interface OrderMapper {
    @Select("select * from `order`")
    @Results({
            @Result(id = true, property = "id", column = "id"),
            @Result(property = "orderTime", column = "ordertime"),
            @Result(property = "total", column = "total"),
            @Result(property = "user",column = "uid",
                    javaType = com.hsh.pojo.User.class,
                    one = @One(select = "com.hsh.mapper.UserMapper.findById"))
    })
    List<Order> findAll();
}
package com.hsh.mapper;

import com.hsh.pojo.User;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;

import java.util.List;

public interface UserMapper {
    @Insert("insert into user values(null,#{username},#{password},#{birthday})")
    void  save(User user);
    @Update("update user set username = #{username},password = #{password},birthday = #{birthday} where id = #{id}")
    void update(User user);
    @Delete("delete from user where id = #{id}")
    void delete(Integer id);
    @Select("select * from user where id = #{id}")
    User findById(Integer id);
    @Select("select * from user")
    List<User> findAll();
}

6. 测试结果

@Test
public void testSelectOrderAndUser() {
	List<Order> all = orderMapper.findAll();
	for(Order order : all){
		System.out.println(order);
	}
}

在这里插入图片描述

2 一对多查询

1. 一对多查询的模型

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
在这里插入图片描述

2. 一对多查询的语句

对应的sql语句:

select * from user;
select * from orders where uid=查询出用户的id;

查询的结果如下:
在这里插入图片描述

3. 修改User实体

在这里插入图片描述

4. 创建UserMapper接口

List<User> findAllUserAndOrder();

5. 使用注解配置Mapper

在这里插入图片描述

6. 测试结果

List<User> all = userMapper.findAllUserAndOrder();
for(User user : all){
	System.out.println(user.getUsername());
	List<Order> orderList = user.getOrderList();
	for(Order order : orderList){
		System.out.println(order);
	}
	System.out.println("-----------------------------");
}

3 多对多查询

1. 多对多查询的模型

用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色

在这里插入图片描述

2. 多对多查询的语句

对应的sql语句:

select * from user;
select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=用户的id

查询的结果如下:

在这里插入图片描述

3. 创建Role实体,修改User实体

在这里插入图片描述

4. 添加UserMapper接口方法

List<User> findAllUserAndRole();

5. 使用注解配置Mapper

在这里插入图片描述

6. 测试结果

UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> all = mapper.findAllUserAndRole();
for(User user : all){
	System.out.println(user.getUsername());
	List<Role> roleList = user.getRoleList();
	for(Role role : roleList){
		System.out.println(role);
	}
	System.out.println("----------------------------------");
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值