JavaWeb笔记_09

文章介绍了Lombok如何通过注解简化Java代码,如自动生成getter/setter等,以及MyBatis的基本使用,包括快速入门、注解开发和动态SQL操作。MyBatis作为持久层框架,简化了JDBC的开发,通过XML或注解方式配置SQL。文章还展示了如何进行增删查改操作,并演示了动态SQL的if和foreach用法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. lombok

  • Lombok是一个实用的Java类库,可以通过简单的注解来简化和消除一些必须有但显得很臃肿的Java代码。
  • 坐标
<!-- 在springboot的父工程中,已经集成了lombok并指定了版本号,故当前引入依赖时不需要指定version -->
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
</dependency>

在这里插入图片描述

通过注解的形式自动生成构造器、getter/setter、equals、hashcode、toString等方法,并可以自动化生成日志变量,简化java开发、提高效率。

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

2. MyBatis 入门

  • MyBatis是一款优秀的 持久层 框架,用于简化JDBC的开发。
  • MyBatis本是 Apache的一个开源项目iBatis,2010年这个项目由apache迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
  • 官网:https://mybatis.org/mybatis-3/zh/index.html
    在上面我们提到了两个词:一个是持久层,另一个是框架。
  • 持久层:指的是就是数据访问层(dao),是用来操作数据库的。
    在这里插入图片描述
  • 框架:是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。在框架的基础上进行软件开发更加高效、规范、通用、可拓展。

1.1 快速入门

  • 根据官方文档安装运行环境
  1. 在maven项目的 pom.xml 我文件导入mybatis坐标
<dependency>
  <groupId>org.mybatis</groupId>
  <artifactId>mybatis</artifactId>
  <version>x.x.x</version>
</dependency>
  1. 配置接口和XML
  • XML名必须于接口在同一包下且同名
  • namespace 参数为接口全限定名
  • id 为接口中方法的全称, resultTpye为返回值类型全限定名
import com.itheima.pojo.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface UserMapper {
    //查询所有用户数据
    public List<User> list(); 
}
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.pojo.User">
  <select id="list" resultType="com.itheima.pojo.User">
    select * from Blog where id = #{id}
  </select>
</mapper>
  • 测试代码
@SpringBootTest
public class MybatisQuickstartApplicationTests {
	
    @Autowired
    private UserMapper userMapper;
	
    @Test
    public void testList(){
        List<User> userList = userMapper.list();
        for (User user : userList) {
            System.out.println(user);
        }
    }

}

3. MyBatis 基础操作 (注解开发)

3.1 需求

  1. 查询

    • 根据主键ID查询
    • 条件查询
  2. 新增

  3. 更新

  4. 删除

    • 根据主键ID删除
    • 根据主键ID批量删除

3.2 数据信息

  • 创建表并添加测试数据
-- 部门管理
create table dept
(
    id          int unsigned primary key auto_increment comment '主键ID',
    name        varchar(10) not null unique comment '部门名称',
    create_time datetime    not null comment '创建时间',
    update_time datetime    not null comment '修改时间'
) comment '部门表';
-- 员工管理
create table emp
(
    id          int unsigned primary key auto_increment comment 'ID',
    username    varchar(20)      not null unique comment '用户名',
    password    varchar(32) default '123456' comment '密码',
    name        varchar(10)      not null comment '姓名',
    gender      tinyint unsigned not null comment '性别, 说明: 1 男, 2 女',
    image       varchar(300) comment '图像',
    job         tinyint unsigned comment '职位, 说明: 1 班主任,2 讲师, 3 学工主管, 4 教研主管, 5 咨询师',
    entrydate   date comment '入职时间',
    dept_id     int unsigned comment '部门ID',
    create_time datetime         not null comment '创建时间',
    update_time datetime         not null comment '修改时间'
) comment '员工表';
  • 在 resource 文件夹下创建 application.properties 数据文件,编辑数据库连接信息
#驱动类名称
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#数据库连接的url
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
#连接数据库的用户名
spring.datasource.username=root
#连接数据库的密码
spring.datasource.password=1234
  • 创建对应的实体类Emp
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Emp {
    private Integer id;
    private String username;
    private String password;
    private String name;
    private Short gender;
    private String image;
    private Short job;
    private LocalDate entrydate;     //LocalDate类型对应数据表中的date类型
    private Integer deptId;
    private LocalDateTime createTime;//LocalDateTime类型对应数据表中的datetime类型
    private LocalDateTime updateTime;
}

准备Mapper接口:EmpMapper

/*@Mapper注解:表示当前接口为mybatis中的Mapper接口
  程序运行时会自动创建接口的实现类对象(代理对象),并交给Spring的IOC容器管理
*/
@Mapper
public interface EmpMapper {

}

3.3 删除:根据主键删除数据

  • SQL
-- 删除id=17的数据
delete 
from emp 
where id = 17;
  • 接口编写
@Mapper
public interface EmpMapper {
    @Delete("delete from emp where id = #{id}")//使用#{key}方式获取方法中的参数值
    public void delete(Integer id);
}
  • 在Mybatis中提供的参数占位符有两种:${…} 、#{…}
  • #{XXX}:SQL占位符
    • 执行SQL时,会将#{XXX}替换为?,生成预编译SQL,会自动设置参数值
    • 使用时机:参数传递,都使用#{XXX}
    • 性能更高
    • 更安全(防止SQL注入)
  • ${XXX}:SQL字符串拼接
    • 拼接SQL。直接将参数拼接在SQL语句中,存在SQL注入问题
    • 使用时机:如果对表名、列表进行动态设置时使用

3.4 新增:基本新增

  • SQL
insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) 
values ('songyuanqiao','宋远桥',1,'1.jpg',2,'2012-10-09',2,'2022-10-01 10:00:00','2022-10-01 10:00:00');
  • 接口编写
@Mapper
public interface EmpMapper {
    @Insert("insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time) "+
    				  	 "values (#{username}, #{name}, #{gender}, #{image}, #{job}, #{entrydate}, #{deptId}, #{createTime}, #{updateTime})")
    public void insert(Emp emp);
}

3.5 查询:根据ID查询

  • SQL
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time 
from emp 
where id=1;
  • 接口编写
@Mapper
public interface EmpMapper {
    @Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
    public Emp getById(Integer id);
}
  • 当查询结果为一组数据时,需将结果封装到对象中
  • 有三种方式
    • 起别名
    • 结果映射
    • 开启驼峰命名

1. 起别名:在SQL语句中,对不一样的列名起别名,别名和实体类属性名一样

@Select("select id, username, password, name, gender, image, job, entrydate, " +
        "dept_id AS deptId, create_time AS createTime, update_time AS updateTime " +
        "from emp " +
        "where id=#{id}")
public Emp getById(Integer id);

2. 手动结果映射:通过 @Results及@Result 进行手动结果映射,其中 column 为字段名,property 为属性名

@Results({@Result(column = "dept_id", property = "deptId"),
          @Result(column = "create_time", property = "createTime"),
          @Result(column = "update_time", property = "updateTime")})
@Select("select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp where id=#{id}")
public Emp getById(Integer id);

3. 开启驼峰命名(推荐):如果字段名与属性名符合驼峰命名规则,mybatis会自动通过驼峰命名规则映射

# 在application.properties中添加:
mybatis.configuration.map-underscore-to-camel-case=true

要使用驼峰命名前提是 实体类的属性 与 数据库表中的字段名严格遵守驼峰命名。

3.6 查询:条件查询

  • 需求
    • 姓名:要求支持模糊匹配
    • 性别:要求精确匹配
    • 入职时间:要求进行范围查询
    • 根据最后修改时间进行降序排序
      SQL语句:
select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time 
from emp 
where name like '%张%' 
      and gender = 1 
      and entrydate between '2010-01-01' and '2020-01-01 ' 
order by update_time desc;

接口方法:

  • 方式一
  • 由于展位【?】不能出现在双引号中,所以将 #{XXX}改为${XXX}
    • 但此操作有SQL注入的风险
@Mapper
public interface EmpMapper {
    @Select("select * from emp " +
            "where name like '%${name}%' " +
            "and gender = #{gender} " +
            "and entrydate between #{begin} and #{end} " +
            "order by update_time desc")
    public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}

方式二(解决SQL注入风险)

  • 使用MySQL提供的字符串拼接函数:concat(‘%’ , #{XXX}', ‘%’)
@Mapper
public interface EmpMapper {
   @Select("select * from emp " +
           "where name like concat('%',#{name},'%') " +
           "and gender = #{gender} " +
           "and entrydate between #{begin} and #{end} " +
           "order by update_time desc")
   public List<Emp> list(String name, Short gender, LocalDate begin, LocalDate end);
}

4. 动态SQL (XML配置文件开发)

  • 我们使用注解开发时,字段变多时,编码也会变得臃肿,使用XML配置文件会使得程序更加优雅,且XML配置文件还支持动态SQL
    • 动态SQL:在页面原型中,列表上方的条件是动态的,是可以不传递的,也可以只传递其中的1个或者多个。

4.1 动态SQL-if

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

<if test="条件表达式">
   要拼接的sql语句
</if>
  • 原有的SQL语句
<select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        where name like concat('%',#{name},'%')
              and gender = #{gender}
              and entrydate between #{begin} and #{end}
        order by update_time desc
</select>
  • 动态SQL语句
<select id="list" resultType="com.itheima.pojo.Emp">
        select * from emp
        where
    
             <if test="name != null">
                 name like concat('%',#{name},'%')
             </if>
             <if test="gender != null">
                 and gender = #{gender}
             </if>
             <if test="begin != null and end != null">
                 and entrydate between #{begin} and #{end}
             </if>
    
        order by update_time desc
</select>

4.2 动态SQL-foreach

SQL语句:

delete from emp where id in (1,2,3);

Mapper接口:

@Mapper
public interface EmpMapper {
    //批量删除
    public void deleteByIds(List<Integer> ids);
}

XML映射文件:

  • 使用<foreach>遍历deleteByIds方法中传递的参数ids集合
<foreach collection="集合名称" item="集合遍历出来的元素/项" separator="每一次遍历使用的分隔符" 
         open="遍历开始前拼接的片段" close="遍历结束后拼接的片段">
</foreach>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.itheima.mapper.EmpMapper">
    <!--删除操作-->
    <delete id="deleteByIds">
        delete from emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>
</mapper> 

3.4 动态SQL-sql&include

问题分析:

  • 在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码
    在这里插入图片描述在这里插入图片描述
    我们可以对重复的代码片段进行抽取,将其通过<sql>标签封装到一个SQL片段,然后再通过<include>标签进行引用。

  • <sql>:定义可重用的SQL片段

  • <include>:通过属性refid,指定包含的SQL片段
    在这里插入图片描述

SQL片段: 抽取重复的代码

<sql id="commonSelect">
 	select id, username, password, name, gender, image, job, entrydate, dept_id, create_time, update_time from emp
</sql>

然后通过<include> 标签在原来抽取的地方进行引用。操作如下:

<select id="list" resultType="com.itheima.pojo.Emp">
    <include refid="commonSelect"/>
    <where>
        <if test="name != null">
            name like concat('%',#{name},'%')
        </if>
        <if test="gender != null">
            and gender = #{gender}
        </if>
        <if test="begin != null and end != null">
            and entrydate between #{begin} and #{end}
        </if>
    </where>
    order by update_time desc
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值