【Mybatis】Mybatis 注解开发

Mybatis的注解开发

这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper
映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。

@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装

MyBatis用注解实现增删改查

  • 编写User实体
public class User {
    private int id;//用户id
    private String username;//用户名
    private String password;//密码
    //省略set和get方法及ToString方法
}
  • 编写UserMapper接口
public interface UserMapper {
    //增
    @Insert("insert into user (id,username,password) value (#{id}, #{username}, #{password})")
    void save(User user);

    //删
    @Delete("delete from user where id = #{id}")
    void delete(int id);

    //改
    @Update("update user set username = #{username}, password = #{password} where id = #{id}")
    void update(User user);

    //根据id查
    @Select("select * from user where id = #{id}")
    User findById(int id);

    //查找全部
    @Select("select * from user")
    List<User> findAll();
}
  • 编写核心配置文件

这里要注意 :

Mapper 加载的不是映射文件,因为使用的是注解,所以没有映射文件;

Mapper 加载的是映射关系,即 UserMapper 接口,可以使用mapper扫描接口,也可以用package扫描类所在的包

<configuration>
    <!--jdbc配置文件-->
    <properties resource="jdbc.properties"/>

    <!--定义别名-->
    <typeAliases>
        <typeAlias type="com.xiafanjun.domain.User" alias="user"/>
    </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/xiafanjun/mapper/userMapper.xml"/>
    </mappers>-->

    <!--加载映射关系-->
    <mappers>
        <!--扫描接口-->
        <!--<mapper resource="com.xiafanjun.mapper.UserMapper"/>-->
        <!--扫描接口所在的包-->
        <package name="com.xiafanjun.mapper"/>
    </mappers>
</configuration>
  • 编写测试方法
public class MybatisTest {
    
    private UserMapper userMapper;
    
    //加载配置文件
    @Before
    public void before() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession = build.openSession(true);
        userMapper = sqlSession.getMapper(UserMapper.class);
    }

    //增
    @Test
    public void testSave(){
        User user = new User();
        user.setUsername("zhangsan");
        user.setPassword("738sdfj");
        userMapper.save(user);
    }

    //删
    @Test
    public void testDelete(){
        userMapper.delete(1);
    }

    //改
    @Test
    public void testUpdate(){
        User user = new User();
        user.setId(7);
        user.setUsername("wanwu");
        user.setPassword("738903");
        userMapper.update(user);
    }

    //通过id查找
    @Test
    public void findById(){
        User user = userMapper.findById(2);
        System.out.println(user);
    }
    //User{id=2, username='lucy', password='abcde'}

    //查找全部
    @Test
    public void findAll(){
        List<User> userList = userMapper.findAll();
        for(User user:userList){
            System.out.println(user);
        }
    }
    /*
    User{id=1, username='tom', password='123456'}
    User{id=2, username='lucy', password='abcde'}
    User{id=3, username='jack', password='xyz'}
    User{id=4, username='zhangsan', password='qwerew'}
    User{id=5, username='xiafanjun', password='abcdefg'}
    User{id=6, username='lisi', password='hskdne'}
    User{id=7, username='wanwu', password='738903'}
    */
}

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. 一对一查询的模型

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

2. 一对一查询的语句

对应的sql语句:
select * from orders;
select * from user where id=查询出订单的uid;

期望查询出的结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-JqqgfUxC-1658655319359)(C:\Users\w\AppData\Roaming\Typora\typora-user-images\image-20220511093654620.png)]

3. 创建Order和User实体

Order实体

public class Order {
    private int id;//订单id
    private String orderTime;//订购时间
    private double total;//价格
    private User user;//代表当前订单从属哪一个客户
    //省略set和get方法及ToString方法
}

User实体

public class User {
    private int id;//用户id
    private String username;//用户名
    private String password;//密码
    //省略set和get方法及ToString方法
}

4. 创建OrderMapper接口

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

5. 使用注解配置Mapper

public interface OrderMapper {
    @Select("select * from orders")
    @Results({
        	//id=true表明是主键
            @Result(id = true,column = "id",property = "id"),
            @Result(column = "ordertime",property = "orderTime"),
            @Result(column = "total",property = "total"),
            @Result(column = "uid",//根据哪个字段去查询user表中的数据
                    property = "user",//要封装的属性名称
                    javaType = User.class,//要封装的实体类型
                    //UserMapper接口中的findById方法,相当于将uid传入到该方法中
                    one = @One(select = "com.xiafanjun.mapper.UserMapper.findById"))
    })
    List<Order> findAll();
}

6. 测试结果

public class OrderMapperTest {

    private OrderMapper orderMapper;

    @Before
    public void before() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
        SqlSession sqlSession = build.openSession(true);
        orderMapper = sqlSession.getMapper(OrderMapper.class);
    }

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-oOynXpcC-1658655319360)(C:\Users\w\AppData\Roaming\Typora\typora-user-images\image-20220511133645086.png)]

一对多查询

1. 一对多查询的模型

用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单

2. 一对多查询的语句

对应的sql语句:
select * from user;
select * from orders where uid=查询出用户的id;

先查出user表中的数据,再根据user表中的id查找order表

期望查询出的结果

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KZadJoZ2-1658655319361)(C:\Users\w\AppData\Roaming\Typora\typora-user-images\image-20220511135639074.png)]

3. 修改User实体

public class User {
    private int id;//用户id
    private String username;//用户名
    private String password;//密码
    private List<Order> orderList;//代表当前用户具备那些订单
    //省略set和get方法及ToString方法
}

4. 创建UserMapper接口

List<User> findAllUserAndOrder();

5. 使用注解配置Mapper

因为要通过Order中的uid来查找user相应的order,所以在OrderMapper中添加findByUid方法

@Select("select * from orders where uid=#{uid}")
Order findByUid(int uid);

UserMapper中的方法

@Select("select * from user")
@Results({
        @Result(id = true,column = "id",property = "id"),
        @Result(column = "username",property = "username"),
        @Result(column = "password",property = "password"),
        @Result(column = "id",property = "orderList",
                javaType = List.class,
                //一对多的查询用many
                many = @Many(select = "com.xiafanjun.mapper.OrderMapper.findByUid"))
})
List<User> findAllUserAndOrder();

6. 测试结果

@Before
public void before() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
    SqlSession sqlSession = build.openSession(true);
    userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void findAllUserAndOrder(){
    List<User> allUserAndOrder = userMapper.findAllUserAndOrder();
    for(User user:allUserAndOrder){
        System.out.println(user);
    }
}

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TwNfeZtV-1658655319361)(C:\Users\w\AppData\Roaming\Typora\typora-user-images\image-20220511142102011.png)]

多对多查询

1. 多对多查询的模型

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

其实多对多的查询与一对多的查询差不多,只是中间多了一张关系表

2. 多对多查询的语句

对应的sql语句:
select * from user;
select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=用户的id

先查询出user表中的数据,再通过user表中的id,在user_role中查询出对应的roleid,在用roleid在role表中查出相应的角色名称

期望查询出的结果: select * from user u,user_role ur,role r where u.id = ur.userid and ur.roleid = r.id

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-O6nyXBT9-1658655319362)(C:\Users\w\AppData\Roaming\Typora\typora-user-images\image-20220511144549306.png)]

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

创建Role实体

public class Role {
    private int id;//角色id
    private String rolename;//角色名
    //省略set和get方法及ToString方法
}

修改User实体

public class User {
    private int id;//用户id
    private String username;//用户名
    private String password;//密码
    private List<Order> orderList;//代表当前用户具备那些订单
    private List<Role> roleList;// 代表当前用户具备哪些角色
    //省略set和get方法及ToString方法
}

4. 添加UserMapper接口方法

List<User> findAllUserAndRole();

5. 添加RoleMapper接口使用注解配置Mapper

因为要通过roleid在role表中查询角色,所以要添加RoleMapper接口并添加方法

public interface RoleMapper {
    @Select("select * from role r,user_role ur where r.id=ur.roleid and ur.userid=#{uid}")
    List<Role> findByUid(int uid);
}

UserMapper 接口中添加注解

//多对多查询
@Select("select * from user")
@Results({
        @Result(id = true,column = "id",property = "id"),
        @Result(column = "username",property = "username"),
        @Result(column = "password",property = "password"),
        @Result(column = "id",property = "roleList",
                javaType = List.class,
                //多对多的查询用many
                many = @Many(select = "com.xiafanjun.mapper.RoleMapper.findByUid"))
})
List<User> findAllUserAndRole();

6. 测试结果

@Before
public void before() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
    SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
    SqlSessionFactory build = sqlSessionFactoryBuilder.build(resourceAsStream);
    SqlSession sqlSession = build.openSession(true);
    userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void findAllUserAndRole(){
    List<User> allUserAndRole = userMapper.findAllUserAndRole();
    for(User user:allUserAndRole){
        System.out.println(user);
    }
}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值