JavaWeb合集07-MyBatis

七、MyBatis

MyBatis是一款优秀的持久层(dao)框架,用于简化JDBC的开发。

MyBatis本是Apache的一个开源项目iBatis, 2010年这个项目由apache迁移到了google code,并且改名为MyBatis。2013年11月迁移到Github。

官网:https://mybatis.net.cn/

1、MyBatis入门

1.1 入门案例

使用Mybatis查询所有用户数据

实现步骤:

  1. 准备工作(创建springboot工程、数据库表user、 实体类User)

  2. 引入Mybatis的相关依赖,配置Mybatis(1。)

# application.properties文件中配置
#配置mysql驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#配置主机地址和数据库
spring.datasource.url=jdbc:mysql://localhost:3306/tatabaseName
#配置数据库用户名
spring.datasource.username=root
#配置数据库密码
spring.datasource.password=1234
  1. 编写SQL语句(注解/XML),z这就是User实体类的接口
//持久层,接口;通过调用接口UserDao中的list方法来启动查询
@Component   //spring提供,将该接口交给ioc容器管理(控制反转的体现)
@Mapper     //Mybatis提供,主要被用来将SQL语句映射到接口方法上,从而简化数据库操作。
public interface UserDao {
  //@select写查询语句
@Select("select * from user")
  //定义对应的接口方法,将查询的结果放到list对象中返回
public List<User> getAllUser();
  1. 去测试类中测试编写好的接口
@SpringBootTest
class MybatisTestApplicationTests {

    //通过@Autowired注解,将ioc容器中的接口实现对象UserDao进行引入(依赖注入的体现)
    @Autowired
    private UserDao userDao;

    @Test
    void  getAlluser(){
        List list=userDao.getAllUser();
        System.out.println(list);
    }
}
1.2 配置SQL提示

由于在写SQL语句时,它是一个字符串,很容易写错,写错了也没有提示,只有运行后才报错,所以很不方便,这时就可以将SQL提示打开,在写SQL时就要提示。

选中SQL,右击,如下操作:

在这里插入图片描述

设置完毕后,SQL语句就会有高亮颜色,但是表名和对应的字段名,可能会爆红,这是因为Idea和数据库没有建立连接,不识别表信息,但是它不影响SQL的执行,只是会没有对应的提示。解决方法就是将Idea和数据库建立对应的连接,操作如下:

在这里插入图片描述

在这里插入图片描述

1.3 JDBC介绍

JDBC: (Java DataBase Connectivity),就是使用Java语言操作关系型数据库的一套API。

在这里插入图片描述

本质:

  • sun公司官方定义的一套操作所有关系型数据库的规范,即接口。
  • 各个数据库厂商去实现这套接口,提供数据库驱动jar包。
  • 我们可以使用这套接口(JDBC) 编程,真正执行的代码是驱动jar包中的实现类。

在这里插入图片描述

1.4 数据库连接池

数据库连接池是个容器,负责分配、管理数据库连接(Connection)。

它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个连接。

释放空闲时间超过最大空闲时间的连接,来避免因为没有释放连接而引起的数据库连接遗漏。

连接池优势:资源重用、提升系统响应速度、避免数据库连接遗漏。

1.4.1 数据库连接池的分类和切换

数据库连接池接口:DataSuorce;官方(sun)提供的数据库连接池接口,由第三方组织实现此接口。

功能:获取连接 Connection getConnection() throws SQLException;

连接池不需要我们自己创建,以下是常见的连接池:C3P0、DBCP、Druid(德鲁伊,阿里巴巴开源,是java语言最好用的数据库连接池之一)、Hikari(追光者,springboot默认的数据库连接池)

切换Druid数据库连接池

官方地址: https://github. com/ alibaba/ druid/ tree/ master/ druid-spring- boot-starter

只需要引入依赖就行

<!--德鲁伊 连接池对应依赖 -->
<dependency>
<groupld>com.alibaba</ groupld>
<artifactld>druid-spring- boot- starter</ artifactld>
<version>1.2.8</version>
</dependency>
#配置数据库的连接信息
spring.datasource.driver-class-namlg=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://localhost:3306/DatabaseName
spring.datasource.username=root
spring.datasource.password=1234
1.5、Lombok

Lombok是一个实用的Java类库,能通过注解的形式自动生成构造器、getter/setter. equals、 hashcode、 toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。

注解作用
@Getter/@Setter为所有的属性提供get/set方法
@ToString会给类自动生成易阅读的toString方法
@EqualsAndHashCode根据类所拥有的非静态字段自动重写equals方法和hashCode方法
@Data提供 了更综合的生成代码功能( @Getter + @Setter + @ToString + @EqualsAndHashCode)
@NoArgsConstructor为实体类生成无参的构造器方法
@AllArgsConstructor为实体类生成除了static修饰的字段之外带有各参数的构造器方法。

注意:Lombok会在编译时,自动生成对应的java代码。我们使用lombok时,还需要安装一个lombok的插件(idea自带)。

在这里插入图片描述

2、MyBatis的基础操作

通过Mybatis的注解方式实现对数据库的增删改查。

2.1 根据Id删除数据

根据id删除用户表中的数据

  1. 在User实体类的对应接口中写对应方法和SQL语句

    @Component
    @Mapper
    public interface UserDao {
      //如果想要动态的删除对应ID的用户,就要通过方法来将Id传递过来,通过 #{ } 来写传递过来的参数名
        @Delete("delete from tb_user where uid=#{uid}")
        //它会返回被影响数据的条数(0,删除失败,1删除成功)所有返回值设置为int类型
        public  int delUserById(int uid);
        }
    
  2. 在测试类中测试对应的删除方法

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void  delUserById(){
            //调用接口的方法,将用户Id作为参数传递过去,删除用户Id为38的用户
          int delNum= userDao.delUserById(38);
            System.out.printf(delNum==1?"删除成功":"删除失败");
        }
    }
    
2.2 日志输出

由于在操作后不知道,Mybatis到底执行了那写操作,这时就可以开启日志输出。

可以在application.properties文件中,打开mybatis的日志,并指定输出到控制台。

#指定mybatis输出日志的位置,输出控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.Std0utlmpl
2.2.1 预编译SQL

通过日志会发现,执行的SQL语句中,通过动态来传入要删除数据的ID语句,条件等于的是一个"?" ,这就是预编译SQL。

优势:性能提高、防止SQL注入:

①性能提高:因为MySQL有缓存的机制,如果执行相同的SQL语句,就会从缓存区中获取编译好的SQL语句,直接执行。如果没有缓存的SQL语句,就会去重新编译。如果不用预编译SQL,那么只要Id不同,就会判断它是一条新的SQL语句,就会重新去编译;如果条件值用“?”来代替(预编译SQL),尽管条件值不同也会从缓存区中拿取编译好的SQL执行。

②防止SQL注入:SQL注入是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。通过“?”代替的条件会将其看成条件的一个值,不会识别为语句。

通过占位符(#{})写的SQL语句就自动的是预编译SQL,有两种占位符,这是它们的区别。

在这里插入图片描述

2.2 新增用户
  1. 在UserDao接口中写新增用户的SQL及方法

    @Component
    @Mapper
    public interface UserDao {
        @Insert("insert into tb_user(email, password, nick_name, fase, admin, sex, birthday) values (#{email},#{password},#{nickName},#{fase},#{admin},#{sex},#{birthday})")
        public int addUser(User user);
        }
    
  2. 在测试类中对新增方法进行测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void addUser(){
            //准备数据
            User user=new User();
            user.setEmail("123456@qq.com");
            user.setPassword("123456");
            user.setSex("男");
            user.setAdmin(1);
            user.setFase("123.jpg");·
            user.setNickName("永恒之月20");
            user.setBirthday(LocalDateTime.now());
            //调用插入数据的接口方法
            int addNum=userDao.addUser(user);
            System.out.println(addNum==1?"插入成功":"插入失败");
        }
    }
    
2.2.1 主键返回

就是在新增加完数据后,要获取到新增数据的主键(新增完数据并返回主键值)

场景:在多对多的表关系中,需要建立中间表,就需要在新增完数据后,将主键值添加到中间表中这样,这时就需要获取到主键值。

实现方法,在插入SQL注解上加上:@Options(keyProperty="id",useGeneratedKeys = true),keyProperty="id"参数表示返回的值是对象中的id属性,useGeneratedKeys表示我们需要拿到生成的主键值。

@Component
@Mapper
public interface UserDao {
    @Options(keyProperty = "uid",useGeneratedKeys = true)
    @Insert("insert into tb_user(email, password, nick_name, fase, admin, sex, birthday) values (#{email},#{password},#{nickName},#{fase},#{admin},#{sex},#{birthday})")
    public int addUser(User user);
}
@SpringBootTest
class MybatisTestApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void addUser(){
        //准备数据
        User user=new User();
        user.setEmail("12345@qq.com");
        user.setPassword("123456");
        user.setSex("男");
        user.setAdmin(1);
        user.setFase("123.jpg");
        user.setNickName("永恒之月20");
        user.setBirthday(LocalDateTime.now());
        //调用插入数据的接口方法
        int addNum=userDao.addUser(user);
        System.out.println(addNum==1?"插入成功":"插入失败");
        System.out.println(user.getUid());   //在加完@Options后,这里就可以拿到插入数据的主键
    }
        
    }
}
2.3 查询用户信息
2.3.1 根据ID查询用户信息

查询指定ID员工,查询男员工数量

  1. 在UserDao接口中编写查询用户的SQL及方法

    @Component
    @Mapper
    public interface UserDao {
        //查询男用户的数量
        @Select("select count(*) from tb_user where sex='男'")
        public  int  getManNum();
    
        //查询指定邮箱的员工信息
        @Select("select * from tb_user where email=#{email}")
        public User getUserById(String email);
    
    }
    
  2. 在测试类中对查询方法进行测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void  getManNum(){
            System.out.println(userDao.getManNum());
        }
    
    
        @Test
        void getUserById(){
          User user=  userDao.getUserById("123@qq.com");
            System.out.println(user.toString());
    //User(uid=45, email=123@qq.com, password=1bbd886460827015e5d605ed44252251, nickName=null, fase=https://s1.ax1x.com/2023/04/15/p9S5eld.png, userStatus=null, admin=0, sex=男, birthday=2024-06-24T00:00)
    
       
    
2.3.2 数据封装

可以发现,如果数据库里面的字段与实体类里面的属性名不一致时(数据表字段用下划线分隔,实体类里面的是驼峰命名的情况),查询出来的字段值为null,解决方法如下:

方案一:通过给数据表字段取别名,让别名与实体类属性一致

 @Component
@Mapper
public interface UserDao {
@Select("select uid, email, password, nick_name as nickName, fase, admin, user_status as userStatus, sex, birthday from tb_user where email=#{email}")
    public User getUserById(String email);
}
@SpringBootTest
class MybatisTestApplicationTests {

    @Autowired
    private UserDao userDao;

    @Test
    void getUserById(){
      User user=  userDao.getUserById("123@qq.com");
        System.out.println(user.toString());
 //User(uid=45, email=123@qq.com, password=1bbd886460827015e5d605ed44252251, nickName=111, fase=https://s1.ax1x.com/2023/04/15/p9S5eld.png, userStatus=0, admin=0, sex=男, birthday=2024-06-24T00:00)

    }
}

方案二: 通过@Results, @Result注解手动映射封装

@Component
@Mapper
public interface UserDao {
    @Results({
            @Result(column = "nick_name",property = "nickName"),
            @Result(column = "user_status",property = "userStatus")
    })
    @Select("select * from tb_user where email=#{email}")
    public User getUserById(String email);
}

方案三(推荐):开启mybatis的驼峰命名自动映射开关

在配置文件application.properties 中添加配置;开启后,如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射。

mybatis.configuration.map-underscore-to-camel-case=true
2.3.3 列表条件查询

列表条件查询通常带有模糊查询,但是使用like模糊查询后面的条件中引号里面不能使用”%“号来模糊匹配,这时就要使用 concat() 函数来将百分号与模糊查询字符进行拼接。

  1. 在UserDao接口中编写查询用户的SQL及方法

    @Component
    @Mapper
    public interface UserDao {
        //使用MySQL函数concat() 对like条件里面的%号进行拼接
    @Select("select * from tb_user where email like concat('%',#{email},'%') and user_status=#{userStatus} and sex=#{sex}")
        public List<User> getLikeUser(User user);
    }
    
  2. 在测试类中对查询方法进行测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
           @Test
        void getListUser(){
            //创建要模糊查询的对象
            User user=new User();
            user.setEmail("12");
            user.setSex("男");
            user.setUserStatus(1);
            //查询出来的结果放到list集合中,通过forEach遍历出来
           List<User> list= userDao.getLikeUser(user);
           list.forEach(user1->{
               System.out.println(user1.toString());
           });
        }
    
    }
    
2.4 修改用户信息

指定用户的ID对其数据进行修改

  1. 在UserDao接口中编写修改用户的SQL及方法

    @Component
    @Mapper
    public interface UserDao {
    @Update("update  tb_user set password=#{password},nick_name=#{nickName},sex=#{sex} where email=#{email}")
        public int updateUserById(User user);
    }
    
  2. 在测试类中对修改方法进行测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void  updateUserById(){
            User user=new User();
            user.setNickName("小丑");
            user.setSex("女");
            user.setPassword("654321");
            user.setEmail("1234@qq.com");
           int updateIs=userDao.updateUserById(user);
            System.out.println(updateIs==1?"修改成功":"修改失败");
        }
    
    }
    

3、XML映射文件

使用Mybatis的注解,主要是来完成一些简单的增删改查功能。如果需要实现复杂的SQL功能,建议使用XML来配置映射语句。

使用xml文件映射SQL语句后,在接口里就可以直接书写方法,不用写SQL语句。如下:

@Component
@Mapper
public interface UserDao {
  //  @Select("select * from tb_user where email like concat('%',#{email},'%') and user_status=#{userStatus} and sex=#{sex}")
    public List<User> getLikeUser(User user);
}

xml文件书写规范:

XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)。

XML映射文件的namespace属性为Mapper接口全限定名一致。

XML映射文件中sql语句的id与Mapper接口中的方法名一致,并保持返回类型一致。

在这里插入图片描述

  1. 在resource目录下创建对应的目录以及xml文件

    注意:在resource目录下创建Directory可以使用”/“来分隔,这样就像包名用”.“分隔一样,可以一次性创建多级目录。创建xml文件就直接创建文件,在后面加上xml后缀名即可。

  2. 编写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">
    
  3. 书写Mapper标签,并且标签的属性namespace要与对接的接口的全限定名保持一致。

    注:直接去找对应的接口,在接口名上右击->Copy Reference 复制即可。

    <?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">
        <!--namespace:要与对应Mapper接口的全限定名保持一致-->
    <mapper namespace="com.yhzyai.dao.UserDao">
    
    </mapper>
    

    在这里插入图片描述

  4. 可以直接在xml文件中的mapper标签里书写要执行的SQL语句

    <?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.yhzyai.dao.UserDao">
    
    <!-- id:必须与对应的Mapper接口里面的方法名保持一致 -->
    <!--    resultType:单条数据封装的数据类型,由于list集合里面存放发是user对象,这里直接拷贝User的实体类的全类名-->
    <select id="getLikeUser" resultType="com.yhzyai.pojo.User">
     select * from tb_user where email like concat('%',#{email},'%') and user_status=#{userStatus} and sex=#{sex}
    </select>
    
    </mapper>
    
  5. 通过测试方法对其进行测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;   
    
    @Test
        void getListUser(){
            User user=new User();
            user.setEmail("12");
            user.setSex("男");
            user.setUserStatus(1);
           List<User> list= userDao.getLikeUser(user);
           list.forEach(user1->{
               System.out.println(user1.toString());
           });
        }
    }
    

4、Mybatis动态SQL

随着用户的输入或外部条件的变化而变化的SQL语句,我们称为动态SQL。

例如:在根据多个条件查询时,我只需要某几个条件,而有些条件我不需要了,这时它的数据就是null,而SQL语句的条件字段值也为null,这样是查询不不数据的,这时就需要通过动态SQL来控制某些条件不需要判断。

4.1 if-动态SQL标签

:用于判断条件是否成立。使用test属性进行条件判断,如果条件为true,则拼接SQL。

<?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.yhzyai.dao.UserDao">

<select id="getLikeUser" resultType="com.yhzyai.pojo.User">
    <!--使用if前-->
 <!-- select * from tb_user where email like concat('%',#{email},'%') and user_status=#{userStatus} and sex=#{sex}-->
 
  <!--  使用if后-->
select * from tb_user where
    <!--如果email不为空,那么就执行对应条件-->
 <if test="email !=null">
 email like concat('%',#{email},'%')
 </if>
 <if test="userStatus !=null">
 and user_status=#{userStatus}
 </if>
 <if test="sex !=null">
 and sex=#{sex}
 </if>
</select>

</mapper>

//测试
@SpringBootTest
class MybatisTestApplicationTests {

@Autowired
private UserDao userDao;
 @Test
    void getListUser(){
        User user=new User();
        user.setEmail("12");
        //将性别设置为空(不限制性别)
        user.setSex(null);
        user.setUserStatus(1);
       List<User> list= userDao.getLikeUser(user);
       list.forEach(user1->{
           System.out.println(user1.toString());
       });
    }
}
4.2 where-动态SQL标签

:用来替换SQL语句中的where,如果不用where标签时,上一个例子的SQL语句,当条件里的email为空时,if标签里的条件就不会执行,那么组合起来的SQL语句条件前面就会多一个and ,导致SQL语句出错。如: select * from tb_user where and user_status=? and sex=?

  1. 在对应Mapping接口中书写对应方法
@Component
@Mapper
public interface UserDao {
   public List<User> getLikeUser(User user);
}

添加where标签后,执行的SQL:select * from tb_user WHERE user_status=? and sex=?

<?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.yhzyai.dao.UserDao">

<select id="getLikeUser" resultType="com.yhzyai.pojo.User">

 select * from tb_user
<!--添加where标签,包裹if标签-->
 <where>
 <if test="email !=null">
 email like concat('%',#{email},'%')
 </if>
 <if test="userStatus !=null">
 and user_status=#{userStatus}
 </if>
 <if test="sex !=null">
 and sex=#{sex}
 </if>
 </where>
</select>

</mapper>
//测试
@SpringBootTest
class MybatisTestApplicationTests {

@Autowired
private UserDao userDao;
 @Test
    void getListUser(){
        User user=new User();
        //将email设置为空
        user.setEmail(null);
        user.setSex("男");
        user.setUserStatus(1);
       List<User> list= userDao.getLikeUser(user);
       list.forEach(user1->{
           System.out.println(user1.toString());
       });
    }
}

4.3 案例-动态修改数据

如果使用注解的方法来执行SQL修改语句时,不需保证,所有数据都必须修改,要不然没有修改的字段,就会被修改为 null,这时就需要用到xml文件的方式进行动态的修改数据。

set标签:动态地在行首插入SET关键字,并会删掉额外的逗号。( 用在update语句中)

  1. 在Mapper接口中书写对应修改方法
@Component
@Mapper
public interface UserDao {
 public int updateUserById(User user);
}

2.在xml映射文件中书写修改的SQL语句

<?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.yhzyai.dao.UserDao">
 <update id="updateUserById">
  update tb_user
  <set>
   <if test="nickName!=null">
   nick_name=#{nickName},
   </if>
   <if test="fase!=null">
   fase=#{fase},admin=#{admin},
   </if>

    <if test="password!=null">
     password=#{password},
    </if>

   <if test="userStatus!=null">
  user_status=#{userStatus},sex=#{sex},
   </if>
   <if test="birthday!=null">
  birthday=#{birthday}
   </if>
  </set>
  where email=#{email}
 </update>

</mapper>

3.对方法进行测试

  
@Test
    void  updateUserById(){
        //准备数据
        User user=new User();
        user.setEmail("12345@qq.com");
        user.setPassword("9999999");
//        user.setSex("男");
//        user.setAdmin(1);
//        user.setFase("123.jpg");
//        user.setNickName("永恒之2000");
//        user.setBirthday(LocalDateTime.now());
       int updateIs=userDao.updateUserById(user);
        System.out.println(updateIs==1?"修改成功":"修改失败");

    }
  //执行SQL:update tb_user SET password=? where email=?
4.4 foreach 动态SQL标签

批量执行SQL,如批量删除数据

  1. 在Mapper接口中添加对应的批量删除方法

    @Component
    @Mapper
    public interface UserDao {
     //批量删除数据方法,接收的参数是list集合装起来的要删除数据的id
        public int deleteByIds(List<Integer> ids);
    }
    
  2. 在xml文件中编写对应的SQL

    <?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.yhzyai.dao.UserDao">
    
     <delete id="deleteByIds">
    <!-- 编写SQL语句,删除id为48,51,52的用户:delete from tb_user where uid in(48,51,52)-->
    <!--   foreach 标签有5个参数:-->
    <!--    collection:要遍历的集合,直接写传过来的集合名-->
    <!--   item 遍历后的变量名,随便写个变量-->
    <!--   separator:每个遍历出来后之间的分隔符-->
    <!--  open:遍历执行前要拼接的SQL-->
    <!--   close:结束遍历后要拼接的SQL-->
    
    delete from tb_user where uid in <foreach collection="ids" item="uid" separator="," open="(" close=")" >
              #{uid}
     </foreach>
    
     </delete>
     </mapper>
    
  3. 编写测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
        @Test
        void  deleteByIds(){
            List list=new ArrayList();
            list.add(48);
            list.add(51);
            list.add(52);
          int delNum= userDao.deleteByIds(list);
            System.out.println(delNum==3?"删除成功":"删除失败");
        }
     }
    
4.5 sql和 include 标签

由于mapper配置文件中的SQL有很多重复的sql语句,导致代码比较臃肿,不易复用,这时就可以使用sql标签来将重复的sql语句进行封装起来,再使用include来进行复用。

:定义可重用的SQL片段,id属性作为标识。
:通过属性refid,指定包含的sql片段。

  1. 书写一个mapper接口的方法

    @Component
    @Mapper
    public interface UserDao {
    
      public List<User> getUserBySex(String sex);
      
      }
    
  2. 编写mapper映射,通过sql标签和include标签来按用户性别条件进行查询

    <?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.yhzyai.dao.UserDao">
    
        <!--将这种比较通用的SQL语句进行提取出来,通过sql标签-->
     <sql id="getuser">
       select uid, email, password, nick_name, fase, admin, user_status, sex, birthday from tb_user
     </sql>
    
        
     <select id="getUserBySex" resultType="com.yhzyai.pojo.User">
     <!--   select uid, email, password, nick_name, fase, admin, user_status, sex, birthday from tb_user where sex=#{sex} -->
      <!--使用include标签中的refid属性来引用对应id的sql标签中的sql语句-->
       <include refid="getuser"/>  where sex=#{sex}
     </select>
    
    </mapper>
    
  3. 测试

    @SpringBootTest
    class MybatisTestApplicationTests {
    
        @Autowired
        private UserDao userDao;
    
            @Test
            void getUserBySex(){
               List list=userDao.getUserBySex("男");
                System.out.println(list.toString());
            }
     }
    
4.6 通过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.yhzyai.dao.UserDao">

<!--    trim能够自动删掉最后的,-->
<!--     prefix="("	最前面的符号为(-->
<!--     suffix=")"	结尾符号为)-->
<!--    suffixOverrides=","	不保留最后的逗号-->
    <insert id="addUser">
        insert into tb_user
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="email != null ">
                email,
            </if>
            <if test="password != null ">
                password,
            </if>
            <if test="nickName != null ">
                `nick_name`,
            </if>
            <if test="fase != null ">
                fase,
            </if>
            <if test="admin != null ">
                admin,
            </if>
            <if test="userStatus != null ">
                `user_status`,
            </if>
            <if test="sex != null ">
                sex,
            </if>
            <if test="birthday != null ">
                birthday
            </if>

        </trim>
        <trim prefix="values (" suffix=")" suffixOverrides=",">
            <if test="email != null ">
                #{email},
            </if>
            <if test="password != null ">
                #{password},
            </if>
            <if test="nickName != null ">
                #{nickName},
            </if>
            <if test="fase != null ">
                #{fase},
            </if>
            <if test="admin != null ">
                #{admin},
            </if>
            <if test="userStatus != null ">
                #{userStatus},
            </if>
            <if test="sex != null ">
                #{sex},
            </if>
            <if test="birthday != null ">
                #{birthday}
            </if>
        </trim>
    </insert>
</mapper>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值