当前位置: 首页 > news >正文

SpringBoot项目整合Mybatis-MySql数据库编程

1.Mybatis-MySql

话不多说-直接上代码!
1. 数据库编程的依赖

<!-- Mybatis整合Spring Boot的依赖项 -->
<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>2.2.2</version>
</dependency>
<!-- MySQL的依赖项 -->
<dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><scope>runtime</scope>
</dependency>

application.properties添加配置如

# 连接数据库的配置参数
spring.datasource.url=jdbc:mysql://localhost:3306/mall_pms?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
spring.datasource.username=root
spring.datasource.password=root

检查配置是否正确在test文件测试 没报错即通过

@Autowired
DataSource dataSource;@Test
void getConnection() throws Throwable {dataSource.getConnection();
}

2. Mybatis实现数据库编程

在项目的根包下创建config.MybatisConfiguration配置类(添加了@Configuration注解的类),在此类上配置@MapperScan注解 指定接口文件所在的根包

package cn.tedu.csmall.product.config;import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Configuration;@MapperScan("cn.tedu.csmall.product.mapper")
@Configuration
public class MybatisConfiguration {
}

application.properties中添加配置:

# Mybatis相关配置
mybatis.mapper-locations=classpath:mapper/*.xml
# 支持驼峰命名法-ymlconfiguration:mapUnderscoreToCamelCase: true

并且,在src/main/resources下创建名为mapper的文件夹。

编写POJO类,先在项目中添加依赖:

<!-- Lombok的依赖项,主要用于简化POJO类的编写 -->
<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.20</version><scope>provided</scope>
</dependency>

在项目的根包下创建`pojo.entity.xxxxx中声明与数据表对应的各属性

package cn.tedu.csmall.product.pojo.entity;
import lombok.Data;
import java.io.Serializable;
import java.time.LocalDateTime;
/*** @author java@tedu.cn* @version 0.0.1*/
@Data
public class Album implements Serializable {/*** 记录id*/private Long id;/*** 相册名称*/private String name;}

在项目的根包下创建mapper.AlbumMapper接口,并在接口中添加“插入1条数据”的抽象方法

在各Mapper接口上添加@Repository注解(防止自动装配报错)

  • 与添加@Mapper注解的本质不同,添加@Mapper注解是为了标识此接口是Mybatis框架应该处理的接口,添加@Repository注解是为了引导IntelliJ IDEA作出正确的判断
package cn.tedu.csmall.product.mapper;
import cn.tedu.csmall.product.pojo.entity.Album;
/*** 处理相册数据的Mapper接口** @author java@tedu.cn* @version 0.0.1*/
@Repository
public interface AlbumMapper {/*** 插入相册数据** @param album 相册数据* @return 受影响的行数*/int insert(Album album);}

src/main/resource/mapper下,并在此文件中配置以上接口

抽象方法的对应代码:

<?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="cn.tedu.csmall.product.mapper.AlbumMapper">←这里需要对应mapper中的文件<!-- int insert(Album album); --><insert id="insert">INSERT INTO pms_album (name, description, sort) VALUES (#{name}, #{description}, #{sort})</insert>
</mapper>

mapper数据库语句编写规范

插入数据时获取自动编号的id

<insert>标签上,可以配置useGeneratedKeys="true"keyProperty="属性名",将可以获取自动编号的id值,并由Mybatis自动赋值到参数对象的属性(keyProperty配置的值)上

<!-- int insert(Album album); -->
<insert id="insert" useGeneratedKeys="true" keyProperty="id">INSERT INTO pms_album (name, description, sort) VALUES (#{name}, #{description}, #{sort})
</insert>

提示:如果表的id不是自动编号的,则插入数据时必须由方法的调用者给出id值,所以,对于方法的调用者而言,id值是已知的,则不需要配置这2个属性。

mapper中增删改查语句示例

批量插入数据

int insertBatch(List<Album> albums);
<!-- int insertBatch(List<Album> albums); -->
<insert id="insertBatch" useGeneratedKeys="true" keyProperty="id">INSERT INTO pms_album (name, description, sort) VALUES<foreach collection="list" item="album" separator=",">(#{album.name}, #{album.description}, #{album.sort})</foreach>
</insert>

根据id删除数据

int deleteById(Long id);
<!-- int deleteById(Long id); -->
<delete id="deleteById">DELETE FROM pms_album WHERE id=#{id}
</delete>

根据若干个id批量删除数据

int deleteByIds(Long[] ids);
<!-- int deleteByIds(Long ids); -->
<delete id="deleteByIds">DELETE FROM pms_album WHERE id IN (<foreach collection="array" item="id" separator=",">#{id}</foreach>)
</delete>

修改数据

int update(Album album);
<!-- int update(Album album); -->
<update id="update">UPDATE pms_album<set><if test="name != null">name=#{name},</if><if test="description != null">description=#{description},</if><if test="sort != null">sort=#{sort},</if></set>WHERE id=#{id}
</update>

统计数据的数量

int count();

在设计“查询”的抽象方法时,关于返回值类型,只需要保证所设计的返回值类型足够“装得下”所需的查询结果即可。

<!-- int count(); -->
<select id="count" resultType="int">SELECT count(*) FROM pms_album
</select>

注意:每个<select>标签必须配置resultTyperesultMap这2个属性中的其中1个

根据id查询数据的详情

创建pojo.vo.AlbumStandardVO类型,在此类型中设计与查询的字段列表匹配的属性

AlbumStandardVO getStandardById(Long id);
<!-- AlbumStandardVO getStandardById(Long id); -->
<select id="getStandardById" resultType="cn.tedu.csmall.product.pojo.vo.AlbumStandardVO">SELECT id, name, description, sort FROM pms_album WHERE id=#{id}
</select>

注意:每个<select>标签必须配置resultTyperesultMap这2个属性中的其中1个。

查询数据列表

创建pojo.vo.AlbumListItemVO类型,在此类型中设计与查询的字段列表匹配的属性

List<AlbumListItemVO> list();
<!-- List<AlbumListItemVO> list(); -->
<select id="list" resultType="cn.tedu.csmall.product.pojo.vo.AlbumListItemVO">SELECT id, name, description, sort FROM pms_album ORDER BY sort DESC, id DESC
</select>

注意:每个<select>标签必须配置resultTyperesultMap这2个属性中的其中1个。

<resultMap><sql>标签

<!-- CategoryStandardVO getStandardById(Long id); -->
<select id="getStandardById" resultMap="StandardResultMap">SELECT<include refid="StandardQueryFields"/>FROMpms_categoryWHEREid=#{id}
</select><sql id="StandardQueryFields"><if test="true">id, name, parent_id, depth, keywords, sort, icon, enable, is_parent, is_display</if>
</sql><resultMap id="StandardResultMap" type="cn.tedu.csmall.product.pojo.vo.CategoryStandardVO"><id column="id" property="id"/><result column="name" property="name"/><result column="parent_id" property="parentId"/><result column="depth" property="depth"/><result column="keywords" property="keywords"/><result column="sort" property="sort"/><result column="icon" property="icon"/><result column="enable" property="enable"/><result column="is_parent" property="isParent"/><result column="is_display" property="isDisplay"/>
</resultMap>

MySQL数据类型与Java类中的数据类型的对应关系

MySQL数据类型Java类中的数据类型
tinyint / smallint / intInteger
bigintLong
char / varchar / text系列String
datetimeLocalDateTime

Mybatis的占位符中使用的名称

在使用Mybatis框架时,配置的SQL语句中的参数可以使用占位符来表示,例如:

<!-- int deleteById(Long id); -->
<delete id="deleteById">DELETE FROM ams_admin WHERE id=#{id}
</delete>

以上SQL语句中#{id}是占位符。

事实上,当抽象方法的参数只有1个时,在占位符中的名称是完全自由编写的,因为Mybatis框架会自动的查找那唯一参数值代入到SQL执行过程中!当抽象方法的参数超过1个时,在占位符中名称不可以是随意的名称,如果使用的名称错误,则可能出现类似以下错误:

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.binding.BindingException: Parameter 'passwordxxx' not found. Available parameters are [password, id, param1, param2]

在错误提示信息中,已经明确指出:Available parameters are [password, id, param1, param2],即“可用的参数名称是[password, id, param1, param2]”,则配置的SQL语句可以是:

<update id="updatePasswordById">update ams_admin set password=#{password} where id=#{id}
</update>

或者:

<update id="updatePasswordById">update ams_admin set password=#{param2} where id=#{param1}
</update>

在较低版本的框架中,为了保证能够使用#{id}#{password}这种名称的占位符,需要在抽象方法的各参数前添加@Param注解,以配置参数的名称,例如:

int updatePasswordById(@Param("id") Long id, @Param("password") String password);

Mybatis的占位符的格式

在Mybatis中,配置SQL语句时,参数可以使用#{}格式的占位符表示,也可以使用${}格式的占位符来表示!

对于以下查询:

<select id="getStandardById" resultMap="StandardResultMap">SELECT<include refid="StandardQueryFields" />FROMams_adminWHEREid=#{id}
</select>

无论是使用#{}还是使用${}格式的占位符,执行效果是相同的!

对于以下查询:

<select id="getLoginInfoByUsername" resultMap="LoginResultMap">SELECT<include refid="LoginQueryFields" />FROMams_adminWHEREusername=#{username}
</select>

使用#{}格式的占位符时,是可以正常使用的,使用${}格式的占位符,会出现如下错误:

Caused by: java.sql.SQLSyntaxErrorException: Unknown column 'root' in 'where clause'

有问题和补充欢迎各位评论区提问!!


http://www.mrgr.cn/news/57344.html

相关文章:

  • JavaWeb——Maven(4/8):Maven坐标,idea集成-导入maven项目(两种方式)
  • web前端-html:简单创建表格表单相结合的网页
  • Vue组件开发详解
  • vue使用jquery的ajax,页面跳转
  • 桌面文件和图片等拖动不了了怎么办?
  • 自动化测试基础知识总结
  • 总集篇:环形链表(是否成环?环长度?入环点?)
  • 鸿蒙启航 | 搭建 HarmonyOS 开发环境来个 Hello World
  • Jenkins配置CI/CD开发环境(理论到实践的完整流程)
  • opencv 将相机图片转为视频 - python 实现
  • 计算机毕业设计Hadoop+大模型在线教育大数据分析可视化 学情分析 课程推荐系统 机器学习 深度学习 人工智能 大数据毕业设计
  • 信发软件之添加组件——未来之窗行业应用跨平台架构
  • 顺序表(一)(数据结构)
  • linux:线程id及线程互斥
  • python基础综合案例(数据可视化—折线图可视化)
  • 全栈面试题】模块5-1】Oracle/MySQL 数据库基础
  • Spring Cloud --- Sentinel 规则持久化
  • 前端-基础CSS总结常用
  • 七、数据库服务器(MySQL、PostgreSQL)的搭建
  • 基于Fourier的两个人形机器人:从改进的3D扩散策略之iDP3到从单个RGB视频中模仿学习的OKAMI
  • 【面试经典150】day 6
  • Flutter鸿蒙next 中如何实现 WebView【跳、显、适、反】等一些基础问题
  • 项目太多,拓展固态硬盘,要安装软件如何固定移动硬盘盘符? - 解决必剪本地作品丢失的问题
  • 如何在复杂的信息物理系统中实施风险管理
  • Educational Codeforces Round 170 C New Game
  • sonarqube-代码扫描-1