- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
为了方便操作,我们在sjdwz_test数据库下建立一张表:
CREATE TABLE `t_student` (
`id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) DEFAULT NULL COMMENT '名字',
`age` int(255) DEFAULT NULL COMMENT '年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4;
数据如下:
实体类如下:
package com.sjdwz.db;
import lombok.*;
/**
* @Description 数据库实体
* @Created by 随机的未知
*/
@Data
@ToString
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Student {
private Long id;
private String name;
private Integer age;
}
我们先来回顾一下JDBC操作数据库的代码:
package com.sjdwz.jdbc;
import com.sjdwz.db.Student;
import java.sql.*;
import java.util.ArrayList;
import java.util.List;
/**
* @Description JDBC操作数据库代码示例
* @Date 2023/12/14
* @Created by 随机的未知 sjdwz.com
*/
public class JDBCMain {
public static void main(String[] args) throws SQLException, ClassNotFoundException {
//数据库连接地址
String url = "jdbc:mysql://localhost:3306/sjdwz_test";
String user = "root";//用户名
String password = "1234567";//密码
//1.注册数据库驱动
Class.forName("com.mysql.jdbc.Driver");
//2.获取数据库连接对象Connection。
Connection conn = DriverManager.getConnection(url, user, password);
//3.创建Sql语句对象Statement,填写SQL语句
PreparedStatement preparedStatement = conn.prepareStatement("select * from t_student where `name` = ?; ");
//传入查询参数
preparedStatement.setString(1, "张三");
//4.执行SQL查询,返回结果集对象ResultSet
ResultSet resultSet = preparedStatement.executeQuery();
List<Student> studentList = new ArrayList<>();
//5.循环解析结果集,获取查询用户list集合
while (resultSet.next()) {
Student student = Student.builder()
.id(resultSet.getLong("id"))
.name(resultSet.getString("name"))
.age(resultSet.getInt("age"))
.build();
studentList.add(student);
}
//打印查询结果
System.out.println(studentList);
//6.关闭连接,释放资源
resultSet.close();//关闭结果集对象
preparedStatement.close();//关闭Sql语句对象
conn.close();//关闭数据库连接对象
}
}
运行截图如下:
这段代码主要有如下四点问题:
所以我们需要一个ORM框架,来解决这些痛点。我用的最多的ORM框架是MyBatis,我们就来从源码角度来分析它,看看MyBatis是怎么解决这些问题的.
项目结构截图如下:
在resources目录下创建mybatis-config.xml文件,内容如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--数据库连接信息-->
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/sjdwz_test?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="1234567"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- 加载sql映射文件-->
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
在resources目录下创建StudentMapper.xml文件,内容如下:
<?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="test">
<!-- id是指sql的唯一标识,resulttype是指返回值的类型-->
<select id="findListByName" resultType="com.sjdwz.db.Student" parameterType="string">
select * from t_student where `name` = #{name};
</select>
</mapper>
MyBatis操作数据库代码如下:
package com.sjdwz.mybatis;
import com.sjdwz.db.Student;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @Description Mybatis示例
* @Created by 随机的未知
*/
public class MybatisTest {
public static void main(String[] args) throws IOException {
//1.创建SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
//2.SqlSessionFactoryBuilder对象创建工厂对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
//3.工厂对象Factory打开SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//4.SqlSession会话对象执行SQL语句,findListByName(命名空间+查询语句唯一标识)
List<Student> studentList = sqlSession.selectList("test.findListByName","张三");
//5.打印查询结果
System.out.println(studentList);
//6.关闭sqlSession会话
sqlSession.close();
}
}
运行截图如下:
在前文,使用JDBC存在四个问题,而Mybatis就解决了这四个问题.
第一个问题是结果集解析复杂,列名硬编码,sql变化导致解析代码变化,系统不易维护,
MyBatis编码中我们不需要进行结果集解析,只需要在编码时指定sql即可,MyBatis会给我们结果; 。
List<Student> studentList = sqlSession.selectList("test.findListByName","张三");
第二个问题是sql语句硬编码,数据库配置硬编码,难以维护,
数据库的配置和sql语句,我们写到了xml文件,解决了硬编码的问题 。
第三个问题是频繁连接、释放数据库资源,没有用到池化思想,系统性能不高; 。
MyBatis使用了池化思想,解决了这个问题; 。
第三个问题是prepareadStatement向占位符传参数存在硬编码,不易维护; 。
我们在配置文件标签上写明了参数,并在代码中传入,避免了占位符的硬编码,解决了此问题.
我们回顾了JDBC和MyBatis的编码方式,了解了JDBC编码存在的问题,并知道了MyBatis编码确实解决了这几个问题.
后面我们就来分析MyBatis源码了.
最后此篇关于MyBatis源码之前言—JDBC编码存在的问题和Mybatis的介绍的文章就讲到这里了,如果你想了解更多关于MyBatis源码之前言—JDBC编码存在的问题和Mybatis的介绍的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
前言 在上一篇随笔中,我们探讨了如何使用 Netty 处理自定义协议中的粘包和拆包问题。Netty 提供了高度封装的 API,帮助开发者轻松应对这一挑战,因此很多人都对其解决方案非常熟悉。 但如果
前言 在上一篇随笔中,我们探讨了如何实现一套自定义通信协议,其中涉及到的粘包和拆包处理最初是完全自定义实现的,后来则改为了继承 ByteToMessageDecoder 来简化处理。 本篇将重点讨
ACO.Visualization项目 本项目演示蚁群算法求解旅行商问题的可视化过程,包括路径上的信息素浓度、蚁群的运动过程等。项目相关的代码:https://github.com/anycad/A
关闭。这个问题不符合Stack Overflow guidelines .它目前不接受答案。 我们不允许提问寻求书籍、工具、软件库等的推荐。您可以编辑问题,以便用事实和引用来回答。 关闭 7 年前。
我需要用Sql数据库制作并包含的PHP票务系统源码用户客户端和管理员。我需要个人 CMS 的这个来源。谢谢你帮助我。 最佳答案 我在不同的情况下使用了 osticket。 这里: http://ost
我的场景:我想在日志文件中写入发生异常的部分代码(例如,发生异常的行前 5 行和行后 5 行 - 或者至少是该方法的所有代码)。 我的想法是用 C# 代码反编译 pdb 文件,并从该反编译文件中找到一
RocketMQ设定了延迟级别可以让消息延迟消费,延迟消息会使用 SCHEDULE_TOPIC_XXXX 这个主题,每个延迟等级对应一个消息队列,并且与普通消息一样,会保存每个消息队列的消费进度
先附上Hystrix源码图 在微服务架构中,根据业务来拆分成一个个的服务,服务与服务之间可以相互调用(RPC),在Spring Cloud可以用RestTemplate+Ribbon和
此篇博客学习的api如标题,分别是: current_url 获取当前页面的url; page_source 获取当前页面的源码; title 获取当前页面的titl
? 1 2
1、前言 作为一个数据库爱好者,自己动手写过简单的sql解析器以及存储引擎,但感觉还是不够过瘾。<<事务处理-概念与技术>>诚然讲的非常透彻,但只能提纲挈领,不能让你
gory"> 目录 运行时信号量机制 semaphore 前言 作用是什么 几个主要的方法 如何实现
自己写的一个评论系统源码分享给大家,包括有表情,还有评论机制。用户名是随机的 针对某一篇文章进行评论 function subcomment() {
一、概述 StringBuilder是一个可变的字符串序列,这个类被设计去兼容StringBuffer类的API,但不保证线程安全性,是StringBuffer单线程情况下的一个替代实现。在可能的情
一、概述 System是用的非常多的一个final类。它不能被实例化。System类提供了标准的输入输出和错误输出流;访问外部定义的属性和环境变量;加载文件和库的方法;以及高效的拷贝数组中一部分元素
在JDK中,String的使用频率和被研究的程度都非常高,所以接下来我只说一些比较重要的内容。 一、String类的概述 String类的声明如下: public final class Str
一、概述 Class的实例代表着正在运行的Java应用程序的类和接口。枚举是一种类,而直接是一种接口。每一个数组也属于一个类,这个类b被反射为具有相同元素类型和维数的所有数组共享的类对象。八大基本树
一、概述 Compiler这个类被用于支持Java到本地代码编译器和相关服务。在设计上,这个类啥也不做,他充当JIT编译器实现的占位符。 放JVM虚拟机首次启动时,他确定系统属性java.comp
一、概述 StringBuffer是一个线程安全的、可变的字符序列,跟String类似,但它能被修改。StringBuffer在多线程环境下可以很安全地被使用,因为它的方法都是通过synchroni
一、概述 Enum是所有Jav中枚举类的基类。详细的介绍在Java语言规范中有说明。 值得注意的是,java.util.EnumSet和java.util.EnumMap是Enum的两个高效实现,
我是一名优秀的程序员,十分优秀!