一、环境搭建
1.1 数据库脚本
SET NAMES utf8;SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for `T_USER`-- ----------------------------DROP TABLE IF EXISTS `T_USER`;CREATE TABLE `T_USER` ( `uid` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户id', `name` char(32) DEFAULT NULL, `token_id` char(64) NOT NULL, PRIMARY KEY (`uid`,`token_id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;SET FOREIGN_KEY_CHECKS = 1;
1.2 POM依赖
<plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.2</version> <configuration> <configurationFile>${basedir}/src/main/resources/generator/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> <verbose>true</verbose> </configuration></plugin>
1.3 执行脚本生成代码
mysql数据库记得要安装好,如果clone代码下来学习,记得要改成自己的数据库。 当上面的步骤都完成后,并输入自己的mysql地址和用户信息后。就可以执行下面脚本了。
mvn mybatis-generator:generate
执行后就会生成我们本节要说的所有内容代码了。
? tree.├── LICENSE├── README.md├── pom.xml└── src ├── main │ ├── java │ │ └── orm │ │ └── example │ │ └── dal │ │ ├── mapper │ │ │ └── TUserMapper.java │ │ └── model │ │ └── TUser.java │ └── resources │ ├── generator │ │ └── generatorConfig.xml │ └── mapper │ └── TUserMapper.xml └── test └── java13 directories, 7 files
二、原生jdbc知识复习
2.1 JDBC是什么?
JDBC代表Java数据库连接(Java Database Connectivity),它是用于Java编程语言和数据库之间的数据库无关连接的标准Java API,换句话说:JDBC是用于在Java语言编程中与数据库连接的API。
- 连接到数据库
- 创建SQL或MySQL语句
- 在数据库中执行SQL或MySQL查询
- 查看和修改结果记录
2.1.1 代码示例
@Test public void jdbc() throws Exception { String dbUrl = "jdbc:mysql://127.0.0.1:3306/test"; String user = "root"; String pass = "123456"; Connection connection = DriverManager.getConnection(dbUrl, user, pass); Statement statement = connection.createStatement(); ResultSet resultSet = statement.executeQuery("select * from T_User"); while (resultSet.next()) { String name = resultSet.getString("name"); System.out.println(name); } statement.close(); resultSet.close(); connection.close(); }
2.2 jdbc知识点
2.2.1 jdbc驱动
通过前面的例子,我们看到我们都是调用 java.sql的包下面的类创建的与数据库交互的工具。那么我们试想一下吧。 java怎么知道我们用的数据库是什么呢? 如果不知道他怎么知道如何进行交互呢?
其实就是 java.sql定义了一系列的接口定义, 由具体的第三方数据库来实现这些定义。从而进行底层的交互。 这里因为我们使用的是mysql数据库,所以 Connection的具体实现就是mysql的数据驱动类 ConnectionImpl。
DriverManager 怎么知道我们要用mysql的实现呢? 这里面用到的数据就是java原生的spi能力。
private static void loadInitialDrivers() { ServiceLoader<Driver> loadedDrivers = ServiceLoader.load(Driver.class); Iterator<Driver> driversIterator = loadedDrivers.iterator(); }
当获得了与数据库的连接后,就可以与数据库进行交互了。 JDBC Statement,CallableStatement和PreparedStatement接口定义了可用于发送SQL或PL/SQL命令,并从数据库接收数据的方法和属性。 它们还定义了有助于在Java和SQL数据类型的数据类型差异转换的方法。
接口 说明 特点 Statement 用于对数据库进行通用访问,在运行时使用静态SQL语句时很有用。 Statement接口不能接受参数。 Statement每次的执行都需要编译SQL PreparedStatement 当计划要多次使用SQL语句时使用。PreparedStatement接口在运行时接受输入参数。 PreparedStatement会预编译,会被缓冲,在缓存区中可以发现预编译的命令,虽然会被再次解析,但不会被再次编译,能够有效提高系统性能 CallableStatement 当想要访问数据库存储过程时使用。CallableStatement接口也可以接受运行时输入参数。 CallableStatement支持存储过程
2.2.2 Statement
Statement对象后,可以使用它来执行一个SQL语句,它有三个执行方法可以执行
@Test public void statement() throws Exception { String dbUrl = "jdbc:mysql://127.0.0.1:3306/test"; String user = "root"; String pass = "123456"; Connection connection = DriverManager.getConnection(dbUrl, user, pass); connection.setAutoCommit(false); Statement statement = connection.createStatement(); // true System.out.println(statement.execute("insert into t_user (name,token_id) values ('孙武空','007')")); ResultSet resultSet = statement.executeQuery("select * from t_user"); while (resultSet.next()) { String name = resultSet.getString("name"); System.out.println(name); } connection.rollback(); statement.close(); connection.close(); }
2.2.3 PreparedStatement
PreparedStatement接口扩展了Statement接口,它添加了比Statement对象更好一些优点的功能。 此语句可以动态地提供/接受参数。
@Test public void prepareStatement() throws Exception { String dbUrl = "jdbc:mysql://127.0.0.1:3306/test"; String user = "root"; String pass = "123456"; Connection connection = DriverManager.getConnection(dbUrl, user, pass); connection.setAutoCommit(false); PreparedStatement preparedStatement = connection.prepareStatement("insert into t_user (name,token_id) values (?,?)"); preparedStatement.setString(1, "唐三藏"); preparedStatement.setString(2, "tok"); preparedStatement.execute(); ResultSet resultSet = preparedStatement.executeQuery("select * from t_user"); while (resultSet.next()) { String name = resultSet.getString("name"); System.out.println(name); } connection.rollback(); preparedStatement.close(); connection.close(); }
2.2.4 CallableStatement
类似Connection对象创建Statement和PreparedStatement对象一样,它还可以使用同样的方式创建CallableStatement对象,该对象将用于执行对数据库存储过程的调用。
@Test public void callableStatement() throws Exception { String dbUrl = "jdbc:mysql://127.0.0.1:3306/test"; String user = "root"; String pass = "123456"; Connection connection = DriverManager.getConnection(dbUrl, user, pass); // 1. 创建一个存储过程 String call = "CREATE PROCEDURE delete_matches(IN del_name varchar(64))n" + "beginn" + " delete from t_user where name = del_name;n" + "end;"; Statement statement = connection.createStatement(); statement.execute("DROP PROCEDURE IF EXISTS delete_matches;"); statement.execute(call); // 执行存储过程 CallableStatement callableStatement = connection.prepareCall("call delete_matches(?)"); callableStatement.setString(1, "孙武空"); callableStatement.execute(); // 查询结果检查存储过程是否成功 ResultSet resultSet = statement.executeQuery("select * from t_user"); while (resultSet.next()) { String name = resultSet.getString("name"); System.out.println(name); } statement.close(); callableStatement.close(); connection.close(); }
:::tip jdbc主要提供跟数据库的交互,其主要的类就是上面演示的。通过上面的复习。我们要清楚下面几个类的作用。 后面我们在学习mybatis时候,我们看mybatis是如何对下面类的封装,从而实现orm映射的。 :::
关键类 说明 Connection 数据库连接 Statement 静态sql执行 PreparedStatement 预处理sql CallableStatement 存储过程执行 ResultSet 返回结果集
三、抛转引玉
前面我们首先搭建了mybaits的开发环境,然后又对jdbc的知识进行了复习。下面我们就开始学习mybait的源码,看mybatis是如何对 jdbc一步一步进行封装从而实现了orm的映射吧。 首先我们先看下下面的演示代码。
@Test public void mapper() { // 读取配置信息(为什么路径前不用加/,因为是相对路径。maven编译后的资源文件和class文件都是在一个包下,所以不用加/就是当前包目录) InputStream mapperInputStream = Thread.currentThread().getContextClassLoader().getResourceAsStream("mybatisConfig.xml"); // 生成SqlSession工厂,SqlSession从名字上看就是,跟数据库交互的会话信息,负责将sql提交到数据库进行执行 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(mapperInputStream, "development"); // 获取Mybatis配置信息 Configuration configuration = sqlSessionFactory.getConfiguration(); // 参数: autoCommit,从名字上看就是是否自动提交事务 SqlSession sqlSession = sqlSessionFactory.openSession(false); // 获取Mapper TUserMapper mapper = configuration.getMapperRegistry().getMapper(TUserMapper.class, sqlSession); TUser tUser = new TUser(); tUser.setName("testUser1"); tUser.setTokenId("testTokenId1"); mapper.insert(tUser); // 获取插入的数据 System.out.println(mapper.selectAll()); // 数据插入后,执行查询,然后回滚数据 sqlSession.rollback(); }
jdbc的原生操作基本已经看不到了。我们已经使用Mybatis实现了与数据库的交互。可以看到并没有看到sql信息。 因为sql信息都维护在TUserMapper.xml里面,Mybatis帮我们把TUserMapper.xml和TUserMapper建立了关系。 最终将原本要通过jdbc实现的操作通过代理的方式,并最终通过TUserMapper这个接口进行交互了。
请问到这里勾起你的好奇心了没有呢? 想不想知道为什么能这样吗? 想不想知道mybaits究竟做了什么,以及是怎么做的呢? 本系列文章会带你一探究竟。在开始之前我们先指定一下学习目标吧。
3.1 学习目标制定
3.2 学习后我们能得到什么
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!