欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > 【MyBatis】数据库基本操作(9)

【MyBatis】数据库基本操作(9)

2024/11/30 4:31:25 来源:https://blog.csdn.net/m0_74164458/article/details/141263043  浏览:    关键词:【MyBatis】数据库基本操作(9)

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。

博客涉及框架的重要知识点,根据序号学习即可。

目录

本系列共涉及4个框架:Sping,SpringBoot,Spring MVC,Mybatis。

博客涉及框架的重要知识点,根据序号学习即可。

1、回顾JDBC

1.1JDBC步骤

1.2具体实现

2、MyBatis入门

2.1什么是MyBatis

2.2MyBatis操作数据库的步骤

3、MyBatis增删改查

4、MyBatis的两种方式

4.1 注解方式

4.2 XML方式

4.3两者方式哪种更好?


1、回顾JDBC

1.1JDBC步骤

(1)创建数据库连接池DataSource

(2)通过DataSource获取数据库连接Connection

(3)编写要执行带?占位符的SQL语句

(4)通过Connection及SQL创建操作命名对象Statement

(5)替换占位符:指定要替换的数据库字段类型,占位符索引及要替换的值

(6)使用Statement执行SQL语句

(7)查询操作:返回结果集ResultSet,更新操作:返回更新的数量

(8)处理结果集

(9)释放资源

1.2具体实现

package edu.fanhuiling;import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class SimpleJdbcOperation {private final DataSource dataSource;public SimpleJdbcOperation(DataSource dataSource) {this.dataSource = dataSource;}/** 添加一本书* */public void addBook(){Connection connection=null;PreparedStatement stmt=null;try{//获取数据库连接connection =dataSource.getConnection();//创建语句stmt=connection.prepareStatement("insert into books(book_name,book_author,book_id)");//参数绑定stmt.setString(1,"Spring");stmt.setString(2,"Boot");stmt.setString(3,"123456789");//执行语句stmt.execute();} catch (SQLException e) {//处理异常信息throw new RuntimeException(e);}finally {//清理资源try{if(stmt!=null) stmt.close();if(connection!=null) connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}/** 更新一本书* */public void updateBook(){Connection connection=null;PreparedStatement stmt=null;try{//获取数据库连接connection =dataSource.getConnection();//创建语句stmt=connection.prepareStatement("update books set book_author=? where book_id =?;");//参数绑定stmt.setString(1,"张三");stmt.setString(2,"123456789");//执行语句stmt.execute();} catch (SQLException e) {//处理异常信息throw new RuntimeException(e);}finally {//清理资源try{if(stmt!=null) stmt.close();if(connection!=null) connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}/** 查询一本书* */public void queryBook(){Connection connection=null;PreparedStatement stmt=null;ResultSet rs=null;Book book=null;try{//获取数据库连接connection =dataSource.getConnection();//创建语句stmt=connection.prepareStatement("select book_name,book_author,book_id ftom books");//参数绑定stmt.setString(1,"123456789");//执行语句stmt.executeQuery();if(rs.next()){book = new Book();book.setBookName(rs.getString("book_name"));book.setBookAuthor(rs.getString("book_author"));book.setBookId(rs.getString("book_id"));}} catch (SQLException e) {//处理异常信息throw new RuntimeException(e);}finally {//清理资源try{if(rs!=null) rs.close();if(stmt!=null) stmt.close();if(connection!=null) connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
}

能清楚的看出,整个过程是十分繁琐的,某些操作步骤还会重复书写,接下来就让我们来看看更简单、更方便的操作数据库——MyBatis!!!

2、MyBatis入门

2.1什么是MyBatis

(1)MyBatis是一款优秀的持久层框架,主要是用于简化JDBC的开发,来完成程序与数据库交互的框架。也可以理解为是一个更简单的操作和读取数据的工具。【持久层:值得就是持久化操作的层级,通常指数据库访问层(dao),是用来操作数据库的】

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

2.2MyBatis操作数据库的步骤

(1)创建SpringBoot工程、数据库准备等等前置工作

(2)引入MyBatis的相关依赖,配置MyBatis

application.properties配置文件:

①注意数据库链接、账号、密码的更改

②如果使用MySQL是5.x之前的使用的是“com.mysql.jdbc.Driver”,如果是大于5.x使用的是“com.mysql.cj.jdbc.Driver”

#热部署生效
spring.devtools.restart.enabled=true
#设置重启目录
spring.devtools.restart.additional-paths=src/main/java
# 指定时区 避免因时区差异而导致的日期时间解析错误
spring.jackson.time-zone=Asia/Shanghai
#设置 cLasspath 目录下的WEB-INF文件夹内容修改不重启(有静态资源才需要)(需要修改成对应值)
spring.devtools.restart.exclude=static/**# 数据库驱动
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据库链接(需要修改成对应值)
spring.datasource.url=jdbc:mysql://localhost:3306/mybatis
# 数据库账号(需要修改成对应值)
spring.datasource.username=root
# 数据库密码(需要修改成对应值)
spring.datasource.password=1234
# 配置 mybatis 的日志,指定输出到控制台
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
# 开启 mybatis 的驼峰命名自动映射开关
mybatis.configuration.map-underscore-to-camel-case=true
# 配置 mybatis 的映射文件路径(需要修改成对应值)
mybatis.mapper-locations=classpath*:mapper/*.xml
# 自动为包下所有Java类注册类型别名(需要修改成对应值)
mybatis.type-aliases-package=edu.xxxx.pojo

(3)编写SQL语句

(4)测试

3、MyBatis增删改查

(1)MyBatis的持久层接口规范一般都叫做XxxMapper

(2)案例:【目前不必掌握标签的具体意思,只需了解Mapper接口与Mapper.xml文件之间的关联,下一篇文章会讲解重点标签的含义】

为什这三个Mapper接口没有加注解@Mapper呢?因为已经在启动类加了@MapperScan扫描的路径了

①Account接口与xml实现

a、AccountMapper.class

import org.fanhuiling.pojo.Account;import java.util.List;public interface AccountMapper {//查询账号Account getAccount(String account);//添加账号void insertAccount(Account account);//查询学生的详细信息List<Account> getAccount();
}

 b、AccountMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.fanhuiling.mapper.AccountMapper"><!--useGeneratedKeys="" :表示使用数据库的自增主键keyProperty="" :将数据库的自增主键与实体类的属性绑定parameterType="":指定传入的类型一般情况下:MyBatis能自动推断--><!--添加账号--><insert id="insertAccount" useGeneratedKeys="true"  keyProperty="id" parameterType="Account">insert into account(account,password,role,create_by,create_time)values(#{account},#{password},#{role},#{createBy},#{createTime})</insert><!--查询学生的详细情况  两个表--><!--resultType 能与数据库对应的Java对象resultMap 能映射到Java对象--><select id="getAccount" resultMap="AccountWithDetails">select a.id,a.account,s.name,s.gender,s.birthday from account as a,student as s where a.account=s.id</select><!--id:用于映射的唯一标识符  主键column: 查询结果集中的数据库中的列名property java对象的属性名result:用于映射其他字段association建立一对一的关系--><resultMap id="AccountWithDetails" type="Account"><id column="id" property="id" /><result column="account" property="account"/><association property="studentDetails" javaType="Student"><id column="account" property="id"/><result column="name" property="name"/><result column="gender" property="gender"/><result column="birthday" property="birthday"/></association></resultMap></mapper>

②Student接口与xml实现

a、StudentMapper.class

import org.apache.ibatis.annotations.Mapper;
import org.fanhuiling.pojo.Student;import java.util.List;@Mapper
public interface StudentMapper {//查询所有对象List<Student> getAll();//根据id查询Student getById(String id);//根据姓名长度和性别查询List<Student> getByCondition(Integer len,Integer gender);//新增学生void insertStudent(Student student);//更新信息void updateStudent(Student student);//查询学生信息(带有性别名称)List<Student> getAllWithGender();//查询学生的所有成绩Student getStudentScoreById(String id);
}

b、studentMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.fanhuiling.mapper.StudentMapper"><!--<sql>标签:定义可重用的sql片段<include>标签:通过属性refid,指定包含的sql片段<if>标签:用于判断条件是否成立,使用test属性来判读,如果为true,则拼接<where>标签:只在有子元素的情况下才会插入where子句,如果where不成立,则去掉where<set>标签:动态的在首行插入set关键字,并删除多余的逗号<foreach>--><sql id="commonSelect">select id,name,gender,birthday from student</sql><!--查询所有学生--><select id="getAll" resultType="org.fanhuiling.pojo.Student"><include refid="commonSelect"></include><!--select id,name,gender,birthday from student--></select><!--根据id查询学生--><select id="getById" resultType="org.fanhuiling.pojo.Student"><include refid="commonSelect"></include>where id=#{id}</select><!--根据条件查询学生--><select id="getByCondition" resultType="org.fanhuiling.pojo.Student"><include refid="commonSelect"></include><where><if test="len!=null">CHAR_LENGTH(student.name)=#{len}</if><if test="gender!=null">and gender=#{gender}</if></where></select><!-- 插入学生信息   --><insert id="insertStudent">insert into student(id, name, gender, birthday, create_by, create_time)values(#{id}, #{name}, #{gender}, #{birthday}, #{createBy}, #{createTime})</insert><!-- 更新学生信息    --><update id="updateStudent">update student<set><if test="name != null"> name = #{name},</if><if test="gender != null"> gender = #{gender},</if><if test="birthday != null"> birthday = #{birthday},</if><if test="updateBy != null"> update_by = #{updateBy},</if><if test="updateTime != null"> update_time = #{updateTime}</if></set>where id = #{id}</update><select id="getAllWithGender" resultMap="StudentWithGender">select s.id,s.name,g.id as gid,g.name as gname,s.birthday from student as s JOIN gender as g on g.id =s.gender    </select><resultMap id="StudentWithGender" type="Student"><id column="id" property="id" /><result column="name" property="name"/><result column="birthday" property="birthday"/><association property="genderDetails" javaType="Gender"><id column="gid" property="id"/><result column="gname" property="name"/></association></resultMap><select id="getStudentScoreById" resultMap="StudentWithScore">select s.id as sid,s.name as sname,c.name as cname,sc.score from score as sc,student as s,course as c where  s.id =#{id} sc.student_id=s.id and sc.course_id=c.id</select><resultMap id="StudentWithScore" type="Student"><id column="sid" property="id" /><result column="sname" property="name"/><collection property="scores" ofType="Score"><result column="score" property="score"/><result column="cname" property="course.name"/><!-- <association property="course" javaType="Course"><result column="cname" property="name"/></association><association property="student" javaType="Student"><result column="sname" property="name"/></association>--></collection></resultMap></mapper>

③ Score接口与xml实现

a、ScoreMapper.class

import org.fanhuiling.pojo.Score;
import java.util.List;public interface ScoreMapper {//新增成绩void insertScore(Score score);//根据id删除成绩void deleteById(Integer id);//批量删除void deleteByIds(List<Integer> ids);
}

b、ScoreMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.fanhuiling.mapper.ScoreMapper"><insert id="insertScore" useGeneratedKeys="true" keyProperty="id" parameterType="Score">insert into score(id,student_id,course_id,score,create_by,create_time)values(#{id},#{studentId},#{courseId},#{score},#{createBy},#{createTime})</insert><delete id="deleteById">delete from score where id = #{id}</delete><delete id="deleteByIds">delete from score where id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></delete><select id="getAllWithName" resultMap="ScoreWithName">select sc.id,s.name as sname,c.name as cname,sc.score from score as sc,student as s,course as c where sc.student_id=s.id and sc.course_id=c.id</select><resultMap id="ScoreWithName" type="Score"><id column="id" property="id" /><result column="score" property="score"/><association property="student" javaType="Student"><result column="sname" property="name"/></association><association property="course" javaType="Course"><result column="cname" property="name"/></association></resultMap></mapper>

(3)测试代码

测试类上添加了注解@SpringBootTest,该测试类在运行时,就会自动加载Spring的运行环境。注解@Autowired可以注入我们要测试的类,这样就可以进行测试了

import org.fanhuiling.mapper.AccountMapper;
import org.fanhuiling.mapper.ScoreMapper;
import org.fanhuiling.mapper.StudentMapper;
import org.fanhuiling.pojo.Account;
import org.fanhuiling.pojo.Score;
import org.fanhuiling.pojo.Student;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.List;@SpringBootTest
class ApplicationTests {@AutowiredStudentMapper studentMapper;@AutowiredAccountMapper accountMapper;@AutowiredScoreMapper scoreMapper;@Testvoid testGetAll() {//查询所有学生List<Student> students=studentMapper.getAll();System.out.println(students);}@Testvoid testGetById() {//根据id查询学生Student student=studentMapper.getById("12138");System.out.println(student);}@Testvoid testGetByCondition() {//根据条件查询学生List<Student> student=studentMapper.getByCondition(null,null);System.out.println(student);}@Testvoid testInsertAccount(){//新增账号Account account=new Account();account.setAccount("12143");account.setPassword("123456");account.setRole(1);account.setCreateBy(1);LocalDateTime now=LocalDateTime.now();account.setCreateTime(now);accountMapper.insertAccount(account);}@Testvoid testInsertStudent(){Student student =new Student();student.setId("12145");student.setName("陆展播");student.setGender(1);student.setBirthday(LocalDate.of(2002,10,24));student.setCreateBy(1);LocalDateTime now=LocalDateTime.now();student.setCreateTime(now);studentMapper.insertStudent(student);}@Testvoid testInsertScore(){Score score=new Score();score.setStudentId("12143");score.setCourseId("104");score.setScore(87);score.setCreateBy(1);LocalDateTime now=LocalDateTime.now();score.setCreateTime(now);scoreMapper.insertScore(score);}@Testvoid testUpdateStudent(){Student student=new Student();student.setId("12141");student.setName("张益达");student.setUpdateBy(1);LocalDateTime now=LocalDateTime.now();student.setUpdateTime(now);studentMapper.updateStudent(student);}@Testvoid testDeleteById(){scoreMapper.deleteById(32);}@Testvoid testDeleteByIds(){List<Integer> ids= Arrays.asList(33,34,35);scoreMapper.deleteByIds(ids);}@Testpublic void testGetAccount(){List<Account> accounts=accountMapper.getAccount();System.out.println(accounts);}@Testpublic void testGetAllWithGender(){List<Student> students=studentMapper.getAllWithGender();for(Student student:students)System.out.println(student);}}

(4)这里的重点不是编写代码,也不是编写测试代码,重点是理解XxxMapper接口对应XxxMapper.xml文件之间的关联与各自的作用,XxxMapper接口只提供方法定义,不具体实现与数据库的交互,而XxxMapper.xml才是编写SQL语句的地方!!!当然,除了XML方式还有注解的方式可以与数据库建立连接,数据交互。

4、MyBatis的两种方式

4.1 注解方式

(1)@Select()、@Insert()、@Update()、@Delete()

(2)这四个注解就可以直接写在XxxMapper接口中方法前面,括号里面直接写SQL语句即可

(3)小例子

import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import org.fanhuiling.mybatis.pojo.Student;import java.util.List;@Mapper
public interface StudentMapper {//查询全部学生方法@Select("select * from student")public abstract List<Student> list();/** 根据id查询学生* */@Select("select * from student where id=#{id}")Student getById(String id);/** 根据姓氏查询* */@Select("select * from student where name like concat(#{lastName},'%')")List<Student> getByLastName(String lastName);}

4.2 XML方式

(1)mapper模版:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace=""></mapper>

(2)上述3、MyBatis增删改查的例子就是使用的XML方式 

4.3两者方式哪种更好?

这个取决于你所在的开发团队,没有明确答案。我个人更偏向于XML方式,因为SQL语句与编写的java逻辑分开了!!!更容易理解代码

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com