【数据库】Mybatis

Mybatis 是一款优秀的 持久层 框架,用于简化JDBC的开发
在这里插入图片描述

入门

使用Mybatis查询所有用户数据

1.创建工程
(1)引入Mybitis的相关依赖,配置Mybatis(数据库连接信息)
在这里插入图片描述
(2)选择如下图这两项依赖
在这里插入图片描述

2.准备工作(创建springboot工程,数据库表user,实体类User)
(1)先创建数据库mybatis
在这里插入图片描述
(2)在main.resources下配置数据库的连接信息
在这里插入图片描述

只需修改数据库名,用户名和密码

(3)在mian下建立pojo,用于存储实体类。然后再此下面创建java类User.
封装User类下的属性,编写get 、set、toString方法,有参构造与无参构造
在这里插入图片描述

3.编写SQL语句(注解/XML)
(1)在pojo同层级目录下创建mapper,再创建UserMapper接口。在里边编写SQL语句。
在这里插入图片描述

在UserMapper接口中,有一个名为list的方法,这个方法被标记了一个@Select注解,@Select注解的值是"select * from user",这意味着list方法将执行这个SQL语句来获取所有用户的信息。

list方法的返回类型是List<User>,这表示它将返回一个User对象的列表,其中每个User对象都对应于数据库中的一条记录。User类是一个与user表对应的Java实体类,其中包含了与表中的列相对应的属性。

4.test下编写测试代码
在这里插入图片描述

第16,17行:使用Spring的@Autowired注解来自动注入UserMapper的实例。
第20行:调用userMapper的list方法来获取数据库中所有用户的列表。这个方法应该返回一个User对象的List。
第21,22行:使用Java 8的流(Stream)和lambda表达式来遍历userList中的每个User对象,并在控制台上打印它们。

JDBC

使用java语言操作关系型数据库的一套规范,即接口
各个数据库厂商去实现这套接口,提供数据库驱动jar包,即数据库的驱动

数据库连接池

在这里插入图片描述
标准接口:DataSource
获取连接:Connection getConnection() throws SQLException;

lombok

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

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

添加lombok:在pom.xml中的<dependcies>中添加如下代码:
在这里插入图片描述

添加后要按一下右上方的Maven按钮。

使用lombk之前的类定义:
在这里插入图片描述
使用lombok之后的类定义:
在这里插入图片描述

节省许多get、set语句

基础操作

删除

根据主键删除

SQL语句:delete from emp where id=17;
接口方法:

@Delete("delete from emp where id = #{id}")
public void delete(Integer id);

若mapper接口方法形参只有一个普通类型的参数,#{…}里面的属性名可以随便写,如#{id},#{value}。

日志输出

在application.properties中,打开mybatis的日志,并指定输出到控制台。
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutlmpl

不用记,写下提示词mybatis和log就有了

SQL注入

通过输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。
在这里插入图片描述
怎样算登录成功?
执行select count(*) from emp where username = ' ' and password = ' ' ;,若输出不为0,则说明账户密码正确

可是,
但密码为如图所示时,则变为

select count(*) from emp where username = 'wu' and password = '' or '1'='1' ;

此时,语义发生了变化,1=1 永远为真.

参数占用符

一个问号代表一个参数。
在这里插入图片描述
此时,有两个参数,输入的两个参数会分别替换

#{...}
执行SQL时,会将#{...}替换,生成预编译SQL,会自动设置参数值
使用时机:参数传递

${...}
拼接SQL,直接将参数拼接在SQL语句中,存在SQL注入问题
使用时机:对表名、列表进行动态设置时

新增

在这里插入图片描述
SQL语句:

insert into emp(username, name, gender, image, job, entrydate, dept_id, create_time, update_time)
values('songyuanqiao','宋远桥','1','1.jpg','2012-10-09','2022-10-01 10:00:00','2022-10-01 10:00:00');

接口方法:

@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);

把多个参数传递用一个对象emp封装,只需传递一个参数就行了

注意:类对象的属性名都是驼峰命名法;数据库中的字段名是有下划线的

新增(主键返回)

描述:在数据库添加成功后,需要获取插入数据库数据的主键
如:添加套餐数据时,还需要维护套餐菜品关系表数据

实现:

@Options(keyProperty = "id",useGeneratedKeys=true)
@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);

useGeneratedKeys=true表示要拿到主键名,keyProperty = "id"表示拿到的主键会封装到对象的id属性当中

@Data
public class Emp{
	private Integer id;
	private String username;
	private String password;
	private String name;
	private Short gender;
	private LocalDate entrydate;
	private Integer deptId;
	private LocalDateTime createTime;
	private LocalDateTime updateTime;
}

更新

SQL语句(根据ID更新员工信息)

update emp set username='songdaxia', name='宋大侠',gender='1',image='1.jpg',job=2,entrydate='2012-01-01',dept_id=2,update_time='2022-10-01 12:12:12' 
where id =19;

接口方法:

@Update("update emp set username=#{username}, name=#{name},gender=#{gender},image=#{images},job=#{job},entrydate=#{entrydate},dept_id=#{deptId},update_time=#{updateTime} 
where id =#{Id}")
public void update(Emp,emp);

查询(根据ID查询)

SQL语句:

select * from emp where id = 19;

接口方法:

@Select("select * from emp where id =#{id}")
public Emp getById(Integer id);

数据封装

实体类属性名 和 数据库表查询返回的字段名一致,mybatis会自动封装
若实体类属性名 和 数据库表查询返回的字段名不一致,不能自动封装。
在这里插入图片描述
解决方案:开启mybatis的驼峰命名自动映射开关
步骤:在resources下的application,properties中添加:
mybatis.configuration.map-underscore-to-camel-case=true

查询(条件查询)

SQL语句:

select * from emp 
where name like '%张%' and gender = 1 and entrydate between '2010-01-01' and '2020-01-01' 
order by update_time desc;

接口方法:

@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);

XML映射文件

XML映射文件的名称与Mapper接口名称一致,并且将XML映射文件和Mapper接口放置在相同包下(同包同名)
XML映射文件的namespace属性为Mapper接口全限定名一致
XML映射文件中sql语句的id与Mapper接口的方法名一致,并且保持返回类型一致。
在这里插入图片描述

可以在IDEA按照Mybatis的插件

对于简单的增删改查功能,使用注解;若要实现复杂的SQL功能建议用XML

动态SQL

随着用户的输入或外部条件的变化而变化的SQL语句

if ,where

<if>用于判断条件是否成立。使用test属性进行条件判断,若条件为true,则拼接SQL
<where>只会在子元素有内容的情况下才插入where子句,而且会自动去除子句开头的and或or
<set>动态地在行首插入SET关键字,并会删掉额外的逗号(用在update语句中)
在这里插入图片描述

foreach

SQL语句:

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

接口方法:

public void deleteByIds(List<Integer> ids);

XML映射文件

    <!--批量删除员工 (1,2,3)-->
    <!--
        collection: 遍历的集合名称
        item: 遍历出来的元素
        separator: 每一个遍历使用的分隔符
        open: 遍历开始前拼接的SQL片段
        close: 遍历结束后拼接的SQL片段
    -->
    <delete id="deleteByIds">
        delete  from emp where id in
        <foreach collection="ids" item="id" separator="," open="(" close=")">
            #{id}
        </foreach>
    </delete>

sql片段

<sql>定义可重用的SQL片段
<include>通过属性refid,指定包含的sql片段

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

    <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>
  • 23
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值