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进行引入(依赖注入的体现)@Autowiredprivate UserDao userDao;@Testvoid  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 {@Autowiredprivate UserDao userDao;@Testvoid  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 {@Autowiredprivate UserDao userDao;@Testvoid 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 {@Autowiredprivate UserDao userDao;@Testvoid 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 {@Autowiredprivate UserDao userDao;@Testvoid  getManNum(){System.out.println(userDao.getManNum());}@Testvoid 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 {@Autowiredprivate UserDao userDao;@Testvoid 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 {@Autowiredprivate UserDao userDao;@Testvoid 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 {@Autowiredprivate UserDao userDao;@Testvoid  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 mapperPUBLIC "-//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 mapperPUBLIC "-//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 mapperPUBLIC "-//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 {@Autowiredprivate UserDao userDao;   @Testvoid 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 mapperPUBLIC "-//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;@Testvoid 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 mapperPUBLIC "-//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;@Testvoid 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 mapperPUBLIC "-//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.对方法进行测试

  
@Testvoid  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集合装起来的要删除数据的idpublic int deleteByIds(List<Integer> ids);
    }
    
  2. 在xml文件中编写对应的SQL

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE mapperPUBLIC "-//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 {@Autowiredprivate UserDao userDao;@Testvoid  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 mapperPUBLIC "-//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 {@Autowiredprivate UserDao userDao;@Testvoid getUserBySex(){List list=userDao.getUserBySex("男");System.out.println(list.toString());}}
    
4.6 通过xml映射文件来新增数据

当数据库表里面的字段设置了默认值时,在前端可能没有对该字段添加数据,这时使用注解的方式来新增数据的话,那么数据库表里的字段默认值就不会生效,这时就需要使用注解的方式来解决。

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/56531.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Axure重要元件三——中继器查询和统计

亲爱的小伙伴&#xff0c;在您浏览之前&#xff0c;烦请关注一下&#xff0c;在此深表感谢&#xff01; 本节课&#xff1a;中继器查询页数 课程内容&#xff1a;查询中继器页面、自动统计页数、自动统计数据条数、上一页下一页 应用场景&#xff1a;表单的查询、表单的基本…

10秒钟用Midjourney画出国风味的变形金刚

上魔咒 Optimus Prime comes from the movie Transformers, Chinese style, Wu ShanMing, Ink Painting Halo Dyeing, Conceptual of the Digita Art, MasterComposition, Romantic Ancient Style, Inspired by traditional patterns and symbols, Minimalism, do not con…

【数据分享】全国资源和环境-环境污染治理投资(1998-2021年)

数据介绍 一级标题指标名称单位指标解释资源和环境环境污染治理投资总额亿元环境污染治理投资指在污染源治理和城市环境基础设施建设的资金投入中&#xff0c;用于形成固定资产的资金&#xff0c;其中污染源治理投资包括工业污染源治理投资和“三同时”项目环保投资两部分。环…

ssm基于SSM的社区管理系统+vue

系统包含&#xff1a;源码论文 所用技术&#xff1a;SpringBootVueSSMMybatisMysql 免费提供给大家参考或者学习&#xff0c;获取源码请私聊我 需要定制请私聊 目 录 目 录 I 摘 要 III ABSTRACT IV 1 绪论 1 1.1 课题背景 1 1.2 研究现状 1 1.3 研究内容 2 [2 系统…

1.2024.10.17

2024.10.17 总体规划 总体规划 写这个合集的原因 记录自己入行之前成长过程。本人菜鸟一枚&#xff0c;大佬不喜勿喷。 目前的规划 更新频率 尽量一天一更&#xff0c;会更新之前发布的笔记&#xff0c;争取笔记更加完善。 学习方法 目标 通过面试&#xff0c;成功入行嵌…

Tailwind css系列教程(三)

vue3环境搭建Tailwind CSS 1、创建vue3项目 创建项目&#xff1a;npm create vitelatest vue3app01 --template vue 进入项目文件夹&#xff1a;cd vue3app01 加载默认库&#xff1a;npm install 测试运行&#xff1a;npm run dev 2、搭建tailwind css &#xff08;1&a…

2010年国赛高教杯数学建模C题输油管的布置解题全过程文档及程序

2010年国赛高教杯数学建模 C题 输油管的布置 某油田计划在铁路线一侧建造两家炼油厂&#xff0c;同时在铁路线上增建一个车站&#xff0c;用来运送成品油。由于这种模式具有一定的普遍性&#xff0c;油田设计院希望建立管线建设费用最省的一般数学模型与方法。   1. 针对两炼…

在线考试系统的现代化解决方案:Spring Boot与JavaWeb

3系统分析 3.1可行性分析 通过对本基于JavaWeb技术的在线考试系统设计与实现实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于JavaWeb技术的在线考试系统设…

10 排序算法:冒泡排序与快速排序(算法原理、算法实现、时间和空间复杂度分析)

目录 1 十大常见的排序算法 1.1 算法的稳定性 2 冒泡排序 2.1 算法原理 2.2 算法实现 2.3 时间空间复杂度分析 2.3.1 时间复杂度分析 2.3.2 空间复杂度分析 3 快速排序 3.1 算法原理 3.1.1 排序思想 3.1.2 递归过程 3.2 示例 3.2.1 示例 1 3.2.2 示例 2 3.2.3 …

JAVA 中系统相关的类

System 类 代表的是当前 Java 程序运行的平台&#xff08;操作系统&#xff09;&#xff0c;该类被关键字 final 修饰&#xff0c;即该类不能够派生子类&#xff0c;同时该类的构造器被关键字 private 修饰&#xff0c;因此不能够创建 System 类型的实例对象。 System 类中定…

【数据采集工具】Sqoop从入门到面试学习总结

国科大学习生活&#xff08;期末复习资料、课程大作业解析、大厂实习经验心得等&#xff09;: 文章专栏&#xff08;点击跳转&#xff09; 大数据开发学习文档&#xff08;分布式文件系统的实现&#xff0c;大数据生态圈学习文档等&#xff09;: 文章专栏&#xff08;点击跳转&…

SpringBoot整合Freemarker(一)

Freemarker和jsp一样是一个视图的引擎模板&#xff0c;其实所有的模板引擎的工作原理都是类似的&#xff0c;如下图&#xff1a; 接下来就具体讲解一下Freemarker的用法&#xff0c;参考手册&#xff1a;模板 数据模型 输出 - FreeMarker 中文官方参考手册 SpringBoot默认就…

Agentic RAG(基于智能体的检索增强生成)是检索增强生成(Retrieval-Augmented Generation,RAG)技术的一种高级形式

Agentic RAG&#xff08;基于智能体的检索增强生成&#xff09;是检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;RAG&#xff09;技术的一种高级形式&#xff0c;它通过引入人工智能代理&#xff08;Agent&#xff09;的概念&#xff0c;为语言模型赋予了…

中国科学院大学与美团发布首个交互式驾驶世界模型数据集DrivingDojo:推进交互式与知识丰富的驾驶世界模型

中国科学院大学与美团发布首个交互式驾驶世界模型数据集DrivingDojo&#xff1a;推进交互式与知识丰富的驾驶世界模型 Abstract 驾驶世界模型因其对复杂物理动态的建模能力而受到越来越多的关注。然而&#xff0c;由于现有驾驶数据集中的视频多样性有限&#xff0c;其卓越的建…

简述RESTFul风格的API接口

目录 传统的风格API REST风格 谓词规范 URL命令规范 避免多级URL 幂等 CURD的接口设计 REST响应 响应成功返回的状态码 重定向 错误代码 客户端 服务器 RESTful的返回格式 返回格式 从上一篇文章我们已经初步知道了怎么在VS中创建一个webapi项目。这篇文章来探讨一…

外包干了2个月,技术明显退步

回望过去&#xff0c;我是一名普通的本科生&#xff0c;于2019年通过校招有幸加入了南京某知名软件公司。那时的我&#xff0c;满怀着对未来的憧憬和热情&#xff0c;投入到了功能测试的岗位中。日复一日&#xff0c;年复一年&#xff0c;转眼间&#xff0c;我已经在这个岗位上…

牵手App红娘来助力,打造线上交友“好管家”

线上交友以其便捷性、广泛性和互动性等特点&#xff0c;正逐渐成为单身男女寻找恋爱伴侣的重要渠道。相较于传统相亲模式&#xff0c;线上交友不仅打破了时间和空间的限制&#xff0c;更以其丰富的互动功能和个性化的匹配算法&#xff0c;为用户提供了前所未有的交友体验。在这…

Python数据分析-航空公司客户满意度分析

一、研究背景 随着航空业的快速发展&#xff0c;航空公司之间的竞争愈发激烈。航空公司不再仅仅依靠价格、航班时间等基本要素来吸引客户&#xff0c;而更多地关注如何提升客户体验与满意度。乘客的飞行体验和满意度不仅影响了他们的忠诚度&#xff0c;也对航空公司在市场中的…

IJKPlayer源码分析-整体结构

根据我们的之前的老方法&#xff0c;采用结构化的方式来对IJKPlayer源码做个分析&#xff0c;首先&#xff0c;我们从整体的角度先把IJKPlayer的整体架构和流程讲下&#xff0c;让大家先有个整体的印象。 本地JNI入口 在Android环境下&#xff0c;JVM层载入一个本地so库流程大致…

【C++11】包装器:深入解析与实现技巧

C 包装器&#xff1a;深入解析与实现技巧 个人主页 C专栏 目录 引言包装器的定义与用途C 包装器的常见应用场景实现包装器的技巧使用 RAII 实现资源管理案例分析&#xff1a;智能指针模板包装器的应用包装器与设计模式性能优化更多应用案例总结 引言 C 是一门灵活且强大的语…