mybatis执行增删改查

1.条件查询

我们需要传入查询条件,假如我们希望传入用户名,返回用户信息。

xml:

 
    

 我们通过使用#{xxx}或是${xxx}来填入我们给定的属性,实际上Mybatis本质也是通过PreparedStatement首先进行一次预编译,有效地防止SQL注入问题,但是如果使用${xxx}就不再是通过预编译,而是直接传值,因此我们一般都使用#{xxx}来进行操作。 

接口:

public interface UserMapper {
    List selectByUsername(String username);
}

2.插入语句

xml: 


        insert into accounting_ledger.user(username, password) VALUES (#{username},#{password})
    

接口: 

package Mybatis.Mapper;

import Mybatis.User;

import java.util.List;

public interface UserMapper {
    List selectUser();
    List selectByUsername(String username);
    int insertUser(User user);
}

调用这个方法:

User user3=new User();
            user3.setPassword("password");
            user3.setUsername("lyj不做饭");
            int i=testMapper.insertUser(user3);
            System.out.println(i);

我们发现虽然xml语句中有两个接受的参数,但是我们在接口中可以直接传入user类,而不必把user分解为两个字段。所以显然mybatis为我们自动分解了。

由于我们并没有指定如何分解user类,而默认的分解方式是根据字段的名字对应的。也就是说我们要保证

VALUES (#{username},#{password})

user类的字段名称相同。

3.复杂查询

考虑如下情况:

目前3个表:老师表(tid,tname),学生表(sid,sname),课程表(tid,sid)

目标是选择出老师1号的所有学生。所以我们通过tid链接老师和课程表,通过sid链接学生表和课程表,然后把老师1号上的课程的所有学生选择出来即可。

首先我们的老师类定义如下:

@Data
public class Teacher {
    int tid;
    String name;
    List studentList;
}

选择出来的学生会存放到student list中。

这样的复杂查询需要我们自己指定映射规则,我们来看xml语句:




    
    
    
        
        
        
    

1.先看,这里和的作用类似,都是把数据库里名叫tid的列映射到java里teacher类中tid的字段。不同点在于,如果用id,当sql语句返回相同的tid时,剩余的数据依旧会存放到指针目前所在的teacher对象里。

举例,sql语句返回了(1)tid=1,name=lyj,sid=1  (2)tid=1,name=lyj,sid=2

这时由于(1)(2)两条语句的tid是一样的,第二条语句的sid就会自动成为lyj老师对象下studentlist里的第二个元素。

同样的情况,如果用的是,那么第二条语句会创建一个新的teacher对象,sid=2的这名同学会成为新teacher对象里studentlist里的第一个元素。

这里的id字段相当于sql语句里的groupby。

2.再看这一段


       
       
       

这里实际上就是在规定当我们的sql读取到和学生相关的字段时,如何映射为java中studentlist里的对象。

通过使用collection来表示将得到的所有和学生相关的结果合并为一个集合 。property="studentList"指定了往哪个集合里丢。

ofType="Student"表明集合中的元素是student。

了解了一对多,那么多对一(sql返回了多个字段,都属于java中的某一个字段)又该如何查询呢,比如每个学生都有一个对应的老师,现在Student新增了一个Teacher对象,那么现在又该如何去处理呢?

@Data
@Accessors(chain = true)
public class Student {
    private int sid;
    private String name;
    private String sex;
    private Teacher teacher;
}

@Data
public class Teacher {
    int tid;
    String name;
}

现在我们希望的是,每次查询到一个Student对象时都带上它的老师:


    
    
    
    
        
        
    


通过使用association进行关联,将sql返回的和老师有关的字段全都映射到teacher类上。

4.动态sql

动态 SQL 是 MyBatis 中的一项强大功能,它允许在 SQL 映射文件中根据条件来动态生成 SQL 语句。这样可以根据不同的情况灵活地构建不同的 SQL 查询。

假设有一个数据库表 blog 包含以下字段:

  • id (INT)
  • title (VARCHAR)
  • content (VARCHAR)
  • state (VARCHAR)

我们可以创建一个对应的 Java 类 Blog 来表示这个表的结构:

public class Blog {
    private int id;
    private String title;
    private String content;
    private String state;

    // 构造方法、getter 和 setter 略...

    @Override
    public String toString() {
        return "Blog{" +
                "id=" + id +
                ", title='" + title + '\'' +
                ", content='" + content + '\'' +
                ", state='" + state + '\'' +
                '}';
    }
}

xml:





  
    
    
    
    
  

  


标签用于在生成动态 SQL 时添加 WHERE 子句。它的主要作用是根据条件动态拼接 WHERE 子句,并且在生成的 SQL 语句中会自动去除不必要的 AND 或 OR。

标签包含了两个 子标签,每个 子标签表示一个查询条件。如果条件满足,就会在 WHERE 子句中添加相应的条件语句。

如果传入的参数中 titlestate 都不为 null 且不为空字符串,那么生成的 SQL 语句为:

SELECT * FROM blog
WHERE title LIKE #{title} AND state = #{state}

只有 title 不为 null 且不为空字符串,那么生成的 SQL 语句可能类似于:

SELECT * FROM blog
WHERE title LIKE #{title}

只有 state 满足条件,生成的 SQL 语句类似于:

SELECT * FROM blog
WHERE state = #{state}

所以上述配置文件背后的逻辑是:

  1. 如果传递了 title 参数,并且该参数不为空,则添加 AND title LIKE #{title} 条件,即根据博客标题进行模糊查询。

  2. 如果传递了 state 参数,并且该参数不为空,则添加 AND state = #{state} 条件,即根据博客状态进行精确查询。

注意


        AND title LIKE #{title}
     

这里if中的title是传进俩的参数,但是参数不是在后面的 #{title}才被传入的吗?

虽然在执行if语句的时候,还没有执行到 #{title},也就是说如果按照顺序执行,在执行if语句的时候title并没有被赋值,甚至根本不知道title是一个参数。所以这里的逻辑和我们一般认识的编程语言不同。

当解析 标签时,MyBatis 会检查条件表达式中的属性(例如 title)是否在传递的参数对象中存在,并获取其值。然后,根据这个值来判断是否满足条件,从而决定是否将包含在 标签内的 SQL 语句片段包含在最终的 SQL 语句中。

mybatis还可以生成各种各样的动态sql语句,详情可见动态 SQL_MyBatis中文网

你可能感兴趣的:(sql,java,数据库)