• day16:MyBatis注解开发


    MyBatis注解开发

    MyBatis的常用注解

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

    使用MyBatis实现简单的增删改查操作

    1、配置文件方式

    我们完成简单的user表的增删改查的操作

    Mybatis的核心文件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>
    	
        <typeAliases>
            <typeAlias type="com.domain.User" alias="user">typeAlias>
        typeAliases>
    
        <environments default="development">
            <environment id="development">
                <transactionManager type="JDBC">transactionManager>
                <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>
            <mapper resource="com/mapper/UserMApper.xml">mapper>
        mappers>
    configuration>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    User的映射文件UserMapper.xml配置
    
    DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    
    <mapper namespace="com.mapper.UserMapper">
        <insert id="save" parameterType="user">
            insert into user values(#{id},#{username},#{password},#{birthday})
        insert>
    
        <select id="findById" parameterType="int" resultType="user">
            select * from user where id=#{id}
        select>
    
        <select id="findAll" resultType="user">
            select * from user
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    操作User的接口
    public interface UserMapper {
        public void save(User user);
    
        public void update(User user);
    
        public void delete(int id);
    
        public User findById(int id);
    
        public List<User> findAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    测试如下
    public class MybatisTest {
        private UserMapper mapper;
    
    //@Before – 表示在任意使用@Test注解标注的public void方法执行之前执行这个方法
        @Before
        public void before() throws IOException {
            InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
    
            SqlSession sqlSession = sqlSessionFactory.openSession(true);
            mapper = sqlSession.getMapper(UserMapper.class);
        }
    
        @Test
        public void testSave(){
            User user = new User();
            user.setUsername("jack");
            user.setPassword("abc");
    
            mapper.save(user);
        }
    
        @Test
        public void testUpdate(){
            User user = new User();
            user.setId(10);
            user.setUsername("jack");
            user.setPassword("abcupdate");
    
            mapper.update(user);
        }
    
        @Test
        public void testDelete(){
    
            mapper.delete(10);
        }
    
        @Test
        public void testFindById(){
    
            User user = mapper.findById(1);
            System.out.println(user);
        }
    
        @Test
        public void testFindAll(){
            List<User> userList = mapper.findAll();
            for (User user : userList) {
                System.out.println(user);
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53

    2、注解方式

    使用注解的方式实现增删改查操作时,我们就不在需要创建映射文件了,可以直接在接口配置相关的注解,并提供查询的语句

    public interface UserMapper {
        @Insert("insert into user values(#{id},#{username},#{password},#{birthday})")
        public void save(User user);
    
        @Update("update user set username=#{username},password=#{password} where id=#{id}")
        public void update(User user);
    
        @Delete(" delete from user where id=#{id}")
        public void delete(int id);
    
        @Select("select * from user where id=#{id}")
        public User findById(int id);
    
        @Select("select * from user")
        public List<User> findAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

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

    <mappers>
    	
    	<mapper class="com.itheima.mapper.UserMapper">mapper>
    mappers>
    
    • 1
    • 2
    • 3
    • 4

    或者指定扫描包含映射关系的接口所在的包也可以

    <mappers>
    	
    	<package name="com.itheima.mapper">package>
    mappers>
    
    • 1
    • 2
    • 3
    • 4

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

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

    注解说明
    @Results代替的是标签该注解中可以使用单个@Result注解,也可以使用@Result集合。使用格式:@Results({@Result(),@Result()})@Results(@Result())
    @Resut代替了标签和标签
    @Result中属性介绍:
    column: 数据库的列名(字段名称,要对应与实体的相关属性进行映射封装)
    property: 需要装配的属性名
    one(一对一查询): 需要使用的@One 注解(@Result(one=@One)()))
    many(一对多或多对多): 需要使用的@Many 注解(@Result(many=@many)()))
    @One (一对一)代替了 标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
    @One注解属性介绍:
    select: 指定用来多表查询的 sqlmapper
    使用格式:@Result(column=" ",property="",one=@One(select=""))
    @Many (多对一)代替了标签, 是是多表查询的关键,在注解中用来指定子查询返回对象集合。使用格式:@Result(property="",column="",many=@Many(select=""))

    一对一查询

    1. 一对一查询的模型

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

    2. 一对一查询的语句

    对应的sql语句:
    select * from orders;
    select * from user where id=查询出订单的uid;
    查询的结果如下:
    在这里插入图片描述

    创建Order和User实体

    public class Order {
    	private int id;
    	private Date ordertime;
    	private double total;
    	//代表当前订单从属于哪一个客户
    	private User user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    public class User {
    	private int id;
    	private String username;
    	private String password;
    	private Date birthday;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    其中还需要提供get、set方法和toString方法

    创建OrderMapper接口,并使用注解配置Mapper

    方式一
    public interface OrderMapper {
        @Select("select *,o.id oid from orders o,user u where o.uid=u.id")
        @Results({
                @Result(column = "oid",property = "id"),
                @Result(column = "ordertime",property = "ordertime"),
                @Result(column = "total",property = "total"),
                @Result(column = "uid",property = "user.id"),
                @Result(column = "username",property = "user.username"),
                @Result(column = "password",property = "user.password")
        })
        public List<Order> findAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    方式二

    public interface OrderMapper {
        @Select("select * from orders")
        @Results({
        		//根据语句“select * from orders”查询下面的属性值
                @Result(column = "oid",property = "id"),
                @Result(column = "ordertime",property = "ordertime"),
                @Result(column = "total",property = "total"),
                //根据uid来查询封装,这里使用的方法是UserMapper中的findById方式
                @Result(
                        //根据uid查询User,在UserMapper当中已经存在一个语句是findById(),我们可以将其引用
                        property = "user",  //要封装的属性名称
                        column = "uid",        //根据哪个字段查询User表中的数据
                        javaType = User.class,       //要封装的实体类型
                        //select 属性 代表查询哪个接口的方法获得数据
                        one = @One(select = "com.mapper.UserMapper.findById")//一对一查询,根据UserMapper中的方法查询
                )
        })
        public List<Order> findAll();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    在这里插入图片描述

    测试

    @Test
    public void testSelectOrderAndUser() {
    	List<Order> all = orderMapper.findAll();
    	for(Order order : all){
    		System.out.println(order);
    	}
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    一对多查询

    1. 一对多查询的模型

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

    2. 一对多查询的语句

    对应的sql语句:
    select * from user;
    select * from orders where uid=查询出用户的id;
    查询的结果如下:
    在这里插入图片描述

    修改User实体

    在这里插入图片描述

    创建UserMapper接口,并使用注解配置Mapper

    这里我们只需要创建findUserAndOrderAll()方法,并使用注解配置即可

    @Select("select * from user")
    @Results({
            @Result(id=true ,column ="id" ,property ="id" ),//id=true表示id属性为主键
            @Result(column ="username" ,property ="username" ),
            @Result(column ="password" ,property ="password" ),
            @Result(
                    property = "orderList",
                    column = "id",
                    javaType = List.class,
                    many = @Many(select = "com.mapper.OrderMapper.findByUid")
            )
    })
    public List<User> findUserAndOrderAll();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    测试结果

        @Test
        public void test(){
            List<User> all = mapper.findUserAndOrderAll();
            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("-----------------------------");
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    多对多查询

    1. 多对多查询的模型

    用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用多对多查询的需求:查询用户同时查询出该用户的所有角色
    在这里插入图片描述

    多对多查询的语句

    对应的sql语句:
    select * from user;
    select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=用户的id
    查询的结果如下:
    在这里插入图片描述

    创建Role实体,修改User实体

    在这里插入图片描述

    添加UserMapper接口方法,并使用注解配置Mapper

    这里我们需要在UserMapper中创建方法,并使用注解配置

    @Select("SELECT * FROM USER")
    @Results({
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "username",property = "username"),
            @Result(column = "password",property = "password"),
    
            @Result(
                    property = "roleList",
                    column = "id",
                    javaType = List.class,
                    many = @Many(select = "com.mapper.RoleMapper.findByUserId")
            )
    })
    public List<User> findUserAndRoleAll();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    在使用注解配置时,我们需要使用到RoleMapper中的方法,这里我们创建一下

    public interface RoleMapper {
        @Select("SELECT * FROM sys_user_role ur,sys_role r WHERE ur.roleId=r.id AND ur.userId=#{uid}")
        public List<Role> findByUserId(int uid);
    }
    
    • 1
    • 2
    • 3
    • 4

    在这里插入图片描述

    测试结果

    @Test
    public void test2(){
        List<User> all = mapper.findUserAndRoleAll();
        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("----------------------------------");
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

  • 相关阅读:
    Python学习笔记(一)
    还在使用mybatis的xml逐个映射字段?来看看mybatis返回Map(三种使用方式)
    linux 查看 io使用率iotop
    高精度乘除法(超详细)
    css-transform:rotate()没效果
    46. 从零开始学springboot: spel结合aop实现动态传参
    【无标题】
    数位排序(蓝桥杯)
    Conda 创建、激活、克隆、删除虚拟环境
    Rust开发问题汇总
  • 原文地址:https://blog.csdn.net/weixin_45804632/article/details/126231824