我是靠谱客的博主 朴实纸飞机,这篇文章主要介绍MyBatis(一)——MyBatis简介、MyBatis入门程序MyBatis简介MyBatis入门程序,现在分享给大家,希望可以做个参考。

文章目录

  • MyBatis简介
    • 什么是MyBatis?
    • JDBC编程存在的问题?MyBatis如何解决?
    • MyBatis的工作原理
  • MyBatis入门程序
    • 准备工作
    • 功能实现
      • 第一个功能:insert-新增商品信息
      • update-根据id更改信息
      • select-通过id来查询商品信息
      • 根据id来删除信息
      • 查询商品列表
      • 新增商品返回主键

MyBatis简介

什么是MyBatis?

MyBatis 是支持普通 SQL 查询,存储过程和高级映射的优秀持久层框架。 MyBatis 消除了几乎所有的 JDBC 代码和参数的手工设置以及结果集的检索。 MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plan Old Java Objects,普通的 Java对象)映射成数据库中的记录

JDBC编程存在的问题?MyBatis如何解决?

1) 数据库连接的创建、释放频繁造成系统资源浪费从而影响了性能,如果使用数据库连接池就可以解决这个问题。当然JDBC同样能够使用数据源。

  • 解决:在SQLMapConfig.xml中配置数据连接池,使用数据库连接池管理数据库连接。

2) SQL语句在写代码中不容易维护,事件需求中SQL变化的可能性很大,SQL变动需要改变JAVA代码。

  • 解决:将SQL语句配置在mapper.xml文件中与java代码分离。

3) 向SQL语句传递参数麻烦,因为SQL语句的where条件不一定,可能多,也可能少,占位符需要和参数一一对应。

  • 解决:Mybatis自动将java对象映射到sql语句。

4) 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。

  • 解决:Mbatis自动将SQL执行结果映射到java对象。

MyBatis的工作原理

配置文件对于MyBatis来说非常重要,MyBatis总共有两类配置文件:

  • 一类用于指定数据源、事务属性以及其他一些参数配置信息(通常是一个独立的文件,可以称之为全局配置文件);

  • 另一类则用于 指定数据库表和程序之间的映射信息(可能不止一个文件,我们称之为映射文件

Mybatis大概的执行过程:
在这里插入图片描述

MyBatis入门程序

我们先来编写一个简单的入门程序,在编写的过程中介绍MyBatis处理问题的思路和方法。

  • 需求:新增商品信息、修改商品信息、删除商品信息、查询商品列表、根据id查询单个商品信息。

准备工作

  • 新建商品表:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
CREATE TABLE `t_product` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(255), `code` VARCHAR(255), `price` DOUBLE(10,0), `count` INT(11), `description` VARCHAR(255), `status` INT(255), `create_time` DATETIME, PRIMARY KEY (`id`) );
  • 搭建MyBatis开发环境:
  1. 将 mybatis-x.x.x.jar 文件置于 classpath 中即可。
  2. 将数据库驱动jar包置于classpath中(这两个jar包通常配合使用)。
    效果图:
    在这里插入图片描述
  3. 添加全局配置文件mybatis-config.xml到项目src目录下。

XML 配置文件中包含了对 MyBatis 系统的核心设置,包含获取数据库连接实例的数据源(DataSource)和决定事务作用域和控制方式的事务管理器(TransactionManager)。要注意 XML 头部的声明,它用来验证 XML 文档正确性。environment 元素体中包含了事务管理和连接池的配置。mappers 元素则是包含一组映射器(mapper),这些映射器的 XML 映射文件包含了 SQL 代码和映射定义信息。下面是全局配置文件最关键的部分:

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
<!-- 头部声明 --> <?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是mybatis配置文件的根标签,用来配置mybatis运行环境等信息 --> <configuration> <!-- environments用来配置mybatis运行环境:数据源,事务管理…… --> <!-- 一个environment代表一种运行环境,默认是development --> <environments default="development"> <environment id="development"> <!-- transationManager的type表示的是mybatis的事务管理采用的是JDBC数据管理 --> <transactionManager type="JDBC"/> <!-- mybatis所应用的数据源,type表示的是数据源采用数据库连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/0417test"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- mappers用来配置mybatis要加载的mapper.xml文件或者mapepr接口 --> <mappers> <!--在这里加载映射器--> <mapper resource="com/xx/mapper/ProductMapper.xml"/> </mappers> </configuration>
  1. 创建映射器comxxmapperProductMapper.xml
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
<?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是mapper.xml文件的根标签,mapper标签内,编写sql语句 namespace:命名空间,区分每个mapper.xml 取值格式:mapper文件所在包的包名.mapper文件名(不带后缀) --> <mapper namespace="com.xx.mapper.ProductMapper"> <!-- 在这里用标签编写sql语句 --> </mapper>
  1. 添加log4j.properties文件到src目录下,更改全局配置文件:
    日志是应用软件中不可缺少的部分,Apache的开源项目Log4j是一个功能强大的日志组件,提供方便的日志记录。MyBatis的jar包中整合了Log4j功能,我们只需要添加配置文件然后更改全局配置文件就可以使用了:
  • 在src目录下创建log4j.properties并添加:
复制代码
1
2
3
4
5
6
7
# Global logging configuration log4j.rootLogger=DEBUG, stdout # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
  • 更改mybatis-config.xml:
复制代码
1
2
3
4
5
6
7
8
9
…… <configuration> <settings> <!-- 配置mybatis日志采用的是log4j --> <setting name="logImpl" value="STDOUT_LOGGING" /> </settings> ……
  1. 创建实体类comxxentityProduct.class,与数据库中表t_product相对应:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
package com.xx.entity; import java.util.Date; public class Product { // CREATE TABLE `t_product` ( // `id` INT(11) NOT NULL AUTO_INCREMENT, // `name` VARCHAR(255), // `code` VARCHAR(255), // `price` DOUBLE(10,0), // `count` INT(11), // `description` VARCHAR(255), // `status` INT(255), // `create_time` DATETIME, // PRIMARY KEY (`id`) // ); private Integer id; private String name; private String code; private Double price; private Integer count; private String description; private Integer status; private Date create_time; public Product() { super(); // TODO Auto-generated constructor stub } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getCode() { return code; } public void setCode(String code) { this.code = code; } public Double getPrice() { return price; } public void setPrice(Double price) { this.price = price; } public Integer getCount() { return count; } public void setCount(Integer count) { this.count = count; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public Integer getStatus() { return status; } public void setStatus(Integer status) { this.status = status; } public Date getCreate_time() { return create_time; } public void setCreate_time(Date create_time) { this.create_time = create_time; } }

至此,我们的基础工作就做好了,接下来就可以实现功能了,来看此时的项目结构:
在这里插入图片描述

功能实现

第一个功能:insert-新增商品信息

  1. 更改ProductMapper.xml文件:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<?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="com.xx.mapper.ProductMapper"> <!-- 新增商品信息 id:表示用来区分sql语句 --> <!-- parameterType表示输入的参数类型,可以是java的基础数据类型和引用数据类型 --> <insert id="insertProductInfo" parameterType="com.xx.entity.Product"> <!-- 在insert标签中写sql语句,#{}表示占位符,里面写传入参数的属性值(即product.xxx) --> insert into t_product values( #{id}, #{name}, #{code}, #{price}, #{count}, #{description}, #{status}, #{create_time} ); </insert> </mapper>
  1. 编写测试类comxxtestMyTest.class:
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.xx.test; import java.io.IOException; import java.util.Date; 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 org.junit.Test; import com.xx.entity.Product; public class MyTest { // 这里我们使用单元测试,单元测试有几个规范: // public 无参 无返回值 方法名以test开头 // 使用单元测试需要将JUnit4添加到classpath中 @Test public void testInsertProductInfo() throws IOException { // 每一个 MyBatis 的应 用程序 都以一 个 SqlSessionFactory 对象的 实例为 核心。 // SqlSessionFactory 对 象 的 实 例 可以 通 过 SqlSessionFactoryBuilder 对 象 来 获得。 // SqlSessionFactoryBuilder 对象可以从 XML 配置文件 // 或从 Configuration 类的实例中构建 SqlSessionFactory 对象 // 1.获取到SqlSessionFactory对象 SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsReader("mybatis-config.xml")); // 2.获取SqlSession对象 SqlSession session = sessionFactory.openSession(); // 3.创建product对象 Product product = new Product(); product.setName("华为手机"); product.setCode("10001"); product.setPrice(4499.00); product.setCount(10); product.setDescription("国产手机品牌"); product.setStatus(1); product.setCreate_time(new Date()); // 4.插入数据insert: // 第一个参数是要执行的sql语句(我们已经写在ProductMapper.xml中),它的取值是 namespece+id // 第二个参数就是执行sql语句传递的参数,类型是parameterType所指定的参数类型 session.insert("com.xx.mapper.ProductMapper.insertProductInfo", product); // 5.手动提交事务 session.commit(); // 6.释放资源 session.close(); } }
  1. 执行结果:
  • 控制台
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. Opening JDBC Connection Created connection 1386767190. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@52a86356] ==> Preparing: insert into t_product values( ?, ?, ?, ?, ?, ?, ?, ? ); ==> Parameters: null, 华为手机(String), 10001(String), 4499.0(Double), 10(Integer), 国产手机品牌(String), 1(Integer), 2019-04-17 22:20:32.562(Timestamp) <== Updates: 1 Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@52a86356] Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@52a86356] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@52a86356] Returned connection 1386767190 to pool.
  • 数据库
idnamecodepricecountdescriptionstatuscreate_time
1华为手机10001449910国产手机品牌12019-04-17 22:20:32

我们的第一个功能:新增商品信息就完成了,接下来我们根据这个流程,依次来实现其余功能:

update-根据id更改信息

  • ProductMapper.xml
复制代码
1
2
3
4
5
6
7
8
…… <mapper namespace="com.xx.mapper.ProductMapper"> …… <update id="alterPriceById" parameterType="com.xx.entity.Product"> update t_product set price = #{price} where id = #{id} </update> </mapper>
  • MyTest.class
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test public void testAlterPriceById() throws IOException { SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsReader("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); Product product = new Product(); // 更改华为手机的价格 product.setId(1); product.setPrice(5000.00); session.update("com.xx.mapper.ProductMapper.alterPriceById", product); session.commit(); session.close(); }

select-通过id来查询商品信息

  • ProductMapper.xml
复制代码
1
2
3
4
5
6
7
8
9
10
11
…… <mapper namespace="com.xx.mapper.ProductMapper"> …… <!-- 有必要说明一下parameterType的值为引用类型和基础数据类型的区别 : 如果是基础数据类型、String那么#{}中可以使任何变量名,包括中文和value 如果是引用数据类型(自定义的entity),那么#{}中必须是entity所包含的属性名--> <select id="selectInfoById" parameterType="int" resultType="com.xx.entity.Product"> select * from t_product where id = #{这里写任意变量名} </select> </mapper>
  • MyTest.class
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@Test public void testSelectInfoById() throws IOException { SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsReader("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); // 查询id为1的商品信息,返回类型是Product Product product = session.selectOne("com.xx.mapper.ProductMapper.selectInfoById", 1); // 这里返回Product重写toString方法以便输出 // 如果我们有log4j,就没有必要输出,可以直接在控制台查看返回的信息 System.out.println(product); session.commit(); session.close(); }
  • 控制台
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. Opening JDBC Connection Created connection 540642172. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@20398b7c] ==> Preparing: select * from t_product where id = ? ==> Parameters: 1(Integer) <== Columns: id, name, code, price, count, description, status, create_time <== Row: 1, 华为手机, 10001, 5000, 10, 国产手机品牌, 1, 2019-04-17 22:20:32.0 <== Total: 1 Product [id=1, name=华为手机, code=10001, price=5000.0, count=10, description=国产手机品牌, status=1, create_time=Wed Apr 17 22:20:32 CST 2019] Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@20398b7c] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@20398b7c] Returned connection 540642172 to pool.

根据id来删除信息

  • ProductMpper.mapper
复制代码
1
2
3
4
5
6
7
8
9
…… <mapper namespace="com.xx.mapper.ProductMapper"> …… <delete id="deleteProductById" parameterType="int"> delete from t_product where id = #{id} </delete> </mapper>
  • MyTest.class
复制代码
1
2
3
4
5
6
7
8
9
10
11
@Test public void testDeleteProductById() throws IOException { SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsReader("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); session.delete("com.xx.mapper.ProductMapper.deleteProductById", 1); session.commit(); session.close(); }
  • 控制台
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
Logging initialized using 'class org.apache.ibatis.logging.stdout.StdOutImpl' adapter. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. PooledDataSource forcefully closed/removed all connections. Opening JDBC Connection Created connection 2025864991. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@78c03f1f] ==> Preparing: delete from t_product where id = ? ==> Parameters: 1(Integer) <== Updates: 1 Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@78c03f1f] Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@78c03f1f] Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@78c03f1f] Returned connection 2025864991 to pool.

查询商品列表

现在我们往表中多加几条信息:

idnamecodepricecountdescriptionstatuscreate_time
2华为手机10001449910国产手机品牌12019-04-18 13:56:19
3小米手机10002349920国产手机品牌12019-04-18 14:04:56
4一加手机10003399915国产手机品牌12019-04-18 14:06:02

现在我们来利用MyBatis实现查询商品列表:

  • ProductMapper.mapper
复制代码
1
2
3
4
5
6
7
8
9
10
11
…… <mapper namespace="com.xx.mapper.ProductMapper"> …… <!-- 查询所有信息不需要传参,返回的肯定是一个列表, 但是我们不需要指定resultType为list,只需要列表的数据类型就可以 --> <select id="selectAllProduct" resultType="com.xx.entity.Product"> select * from t_product </select> </mapper>
  • MyTest.class
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
@Test public void testSelectAllProduct() throws IOException { SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsReader("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); // selecrList // 返回类型是List<>类型 List<Product> list = session.selectList("com.xx.mapper.ProductMapper.selectAllProduct"); // 遍历输出一下 Iterator<Product> iterator = list.iterator(); while (iterator.hasNext()) { Product product = (Product) iterator.next(); System.out.println(product); } session.commit(); session.close(); }
  • 控制台
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
…… ==> Preparing: select * from t_product ==> Parameters: <== Columns: id, name, code, price, count, description, status, create_time <== Row: 2, 华为手机, 10001, 4499, 10, 国产手机品牌, 1, 2019-04-18 13:56:19.0 <== Row: 3, 小米手机, 10002, 3499, 20, 国产手机品牌, 1, 2019-04-18 14:04:56.0 <== Row: 4, 一加手机, 10003, 3999, 15, 国产手机品牌, 1, 2019-04-18 14:06:02.0 <== Total: 3 Product [id=2, name=华为手机, code=10001, price=4499.0, count=10, description=国产手机品牌, status=1, create_time=Thu Apr 18 13:56:19 CST 2019] Product [id=3, name=小米手机, code=10002, price=3499.0, count=20, description=国产手机品牌, status=1, create_time=Thu Apr 18 14:04:56 CST 2019] Product [id=4, name=一加手机, code=10003, price=3999.0, count=15, description=国产手机品牌, status=1, create_time=Thu Apr 18 14:06:02 CST 2019] ……

新增商品返回主键

这里有必要介绍一个selectKey标签:

selectKey在新增后返回主键值时使用,表示查询主键的值,绑定给某个列或者类的某个属性
keyProperty:新增后返回的主键值赋给类的哪个属性
order:取值为BEFORE或者AFTER,BEFORE表示在执行insert语句之前执行select,After表示在执行insert语句之后执行select
LAST_INSERT_ID()将查询到的结果绑定到keyProperty

  • ProductMapper
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
…… <mapper namespace="com.xx.mapper.ProductMapper"> …… <insert id="insertProductReturnPK" parameterType="com.xx.entity.Product" > <selectKey keyProperty="id" resultType="int" order="AFTER"> select LAST_INSERT_ID() </selectKey> insert into t_product values( #{id}, #{name}, #{code}, #{price}, #{count}, #{description}, #{status}, #{create_time} ); </insert> </mapper>
  • MyTest
复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@Test public void testInsertProductReturnPK() throws IOException { SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder() .build(Resources.getResourceAsReader("mybatis-config.xml")); SqlSession session = sessionFactory.openSession(); Product product = new Product(); product.setName("vivo手机"); product.setCode("10006"); product.setPrice(4199.00); product.setCount(10); product.setDescription("国产手机品牌"); product.setStatus(1); product.setCreate_time(new Date()); // 插入数据后返回主键pk int pk = session.insert("com.xx.mapper.ProductMapper.insertProductReturnPK", product); session.commit(); session.close(); }
  • 控制台
复制代码
1
2
3
4
5
6
7
8
9
10
11
…… ==> Preparing: insert into t_product values( ?, ?, ?, ?, ?, ?, ?, ? ); ==> Parameters: null, vivo手机(String), 10006(String), 4199.0(Double), 10(Integer), 国产手机品牌(String), 1(Integer), 2019-04-18 14:51:03.886(Timestamp) <== Updates: 1 ==> Preparing: select LAST_INSERT_ID() ==> Parameters: <== Columns: LAST_INSERT_ID() <== Row: 5 <== Total: 1 ……

可见,新插入的这条数据的主键值是5。

以上,我们介绍了MyBatis的用途和特点,还编写了一个简单的小程序,接下来主要讲讲MyBatis的全局配置文件:
https://blog.csdn.net/qq_44238142/article/details/89380508

最后

以上就是朴实纸飞机最近收集整理的关于MyBatis(一)——MyBatis简介、MyBatis入门程序MyBatis简介MyBatis入门程序的全部内容,更多相关MyBatis(一)——MyBatis简介、MyBatis入门程序MyBatis简介MyBatis入门程序内容请搜索靠谱客的其他文章。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(51)

评论列表共有 0 条评论

立即
投稿
返回
顶部