在 Java简明笔记(十三)JDBC 中,使用 JDBC 来操作数据库,并把查询到的数据库信息进行 java 对象的映射(ORM),但是 JDBC 除了需要自己写SQL之外,还必须操作Connection, Statment, ResultSet,显得繁琐和枯燥。于是我们对 JDBC 进行封装,以简化数据库操作。mybatis就是这样的一个框架。
以下简介摘自官方文档 :
MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
IDEA 实战 创建数据库和表 使用 MYSQL :
创建数据库,库名: myball
创建表,表名:category_
表分为 id 列 和 name 列, name 列填充category1 和 category2
新建工程 使用 IDEA 新建一个 maven 工程,在 pom.xml 中写入依赖
pom.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 <dependencies > <dependency > <groupId > org.mybatis</groupId > <artifactId > mybatis</artifactId > <version > 3.4.6</version > </dependency > <dependency > <groupId > mysql</groupId > <artifactId > mysql-connector-java</artifactId > <version > 8.0.9-rc</version > </dependency > </dependencies >
准备实体类 Category 这个类用来映射数据库信息为java对象(数据库 category_ 表 -> java 的 category对象)
注意:java对象要和数据库信息对应上。比如表category_有 id
和 name
,对象category就要有 int id
和 String name
。
src/main/java/com.jerrysheh.pojo/Category.java
1 2 3 4 5 public class Category { private Long id; private String name; }
创建配置文件 mybatis-config.xml 在 src/main/java 目录下 创建 mybatis-config.xml,填入以下内容: (SpringBoot 免此配置)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 <?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 > <typeAliases > <package name ="com.jerrysheh.pojo" /> </typeAliases > <environments default ="development" > <environment id ="development" > <transactionManager type ="JDBC" /> <dataSource type ="POOLED" > <property name ="driver" value ="com.mysql.cj.jdbc.Driver" /> <property name ="url" value ="jdbc:mysql://localhost:3306/myball?characterEncoding=UTF-8& serverTimezone=GMT%2B8& useSSL=false" /> <property name ="username" value ="root" /> <property name ="password" value ="123456" /> </dataSource > </environment > </environments > <mappers > <mapper resource ="com/jerrysheh/pojo/Category.xml" /> </mappers > </configuration >
<dataSource>
主要提供连接数据库用的驱动,数据库名称,编码方式,账号密码以及别名
<typeAliases>
写明包后,就会自动扫描这个包下面的类型
<mappers>
是映射
创建配置文件 Category.xml 在包 com.jerrysheh.pojo 下创建 Category.xml
1 2 3 4 5 6 7 8 9 10 <?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.jerrysheh.pojo" > <select id ="listCategory" resultType ="Category" > select * from category_ </select > </mapper >
namespace
指明哪个包
resultType
指映射出来的java对象类型,因为在上一个配置文件已经在<typeAliases>
写明包名,所以这里不用给出全名(com.jerrysheh.pojo.Category)
测试类 Test Test.java
1 2 3 4 5 6 7 8 9 10 11 12 13 public class Test { public static void main (String[] args) throws IOException { String resource = "mybatis-config.xml" ; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream); SqlSession session = sqlSessionFactory.openSession(); List<Category> cs = session.selectList("listCategory" ); for (Category c : cs) { System.out.println(c.getName()); } } }
事实上,Mybatis 做了以下几件事:
应用程序找 Mybatis 要数据
Mybatis从数据库中找来数据(通过 mybatis-config.xml 定位哪个数据库,通过 Category.xml 执行对应的select语句)
基于 Category.xml 把返回的数据库记录封装在 Category 对象中
把多个 Category 对象装在一个 Category 集合中
返回一个 Category 对象的集合
使用 mybatis 增删查改 修改 Category.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 <?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.jerrysheh.pojo" > <insert id ="addCategory" parameterType ="Category" > insert into category_ ( name ) values (#{name}) </insert > <delete id ="deleteCategory" parameterType ="Category" > delete from category_ where id= #{id} </delete > <select id ="getCategory" parameterType ="_int" resultType ="Category" > select * from category_ where id= #{id} </select > <update id ="updateCategory" parameterType ="Category" > update category_ set name=#{name} where id=#{id} </update > <select id ="listCategory" resultType ="Category" > select * from category_ </select > </mapper >
增 在测试类Test中通过session将对象映射为数据库信息,插入表
1 2 3 4 5 6 7 8 9 10 11 12 13 String resource = "mybatis-config.xml" ;InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder ().build(inputStream);SqlSession session = sqlSessionFactory.openSession();Category c = new Category ();c.setName("category3" ); session.insert("addCategory" ,c);
删 删除 id 号为 2 的category
1 2 3 4 5 6 Category c = new Category ();c.setId(2 ); session.delete("deleteCategory" , c);
改 1 2 3 4 5 6 7 8 9 Category c= session.selectOne("getCategory" ,3 ); c.setName("修改了的Category名稱" ); session.update("updateCategory" ,c);
查 1 2 3 4 5 6 7 8 9 10 11 12 listAll(session); session.commit(); session.close(); private static void listAll (SqlSession session) { List<Category> cs = session.selectList("listCategory" ); for (Category c : cs) { System.out.println(c.getName()); } }
模糊查询 在 Category.xml 中添加模糊查询语句:
1 2 3 <select id ="listCategoryByName" parameterType ="string" resultType ="Category" > select * from category_ where name like concat('%',#{0},'%') </select >
concat是一个 SQL 函数,表示字符串连接。在这个例子中,concat(‘%’,#{0},’%’) 表示 [零个或多个字符] + 参数{0} + [零个或多个字符], 比如参数{0}是 cat,可以匹配 hellocatWTF
在 测试类 Test.java 中
1 2 3 4 5 6 7 8 listbyName(session,"gory" ); private static void listbyName (SqlSession session, String param) { List<Category> cs = session.selectList("listCategoryByName" , param); for (Category c : cs) { System.out.println(c.getName()); } }
session.selectList()
提供第二个参数,这个参数就是Category.xml 中的 param #{0}
多条件查询 在 Category.xml 中添加多条件查询语句:
查询 id 号大于某个参数的
1 2 3 <select id ="listCategoryByIdAndName" parameterType ="map" resultType ="Category" > select * from category_ where id> #{id} and name like concat('%',#{name},'%') </select >
因为是多个参数,而selectList方法又只接受一个参数对象,所以需要把多个参数放在Map里,然后把这个Map对象作为参数传递进去
1 2 3 4 5 6 7 8 9 10 11 12 13 Map<String,Object> params = new HashMap <>(); params.put("id" , 4 ); params.put("name" , "cat" ); listbyIdAndName(session,params); private static void listbyIdAndName (SqlSession session, Map<String,Object> param) { List<Category> cs = session.selectList("listCategoryByIdAndName" , param); for (Category c : cs) { System.out.println(c.getName()); } }
动态SQL if 我们前面提供了 listCategory 全部查询 和 listCategoryByName 模糊查询 两种方式。要写两个 SQL 语句。可以看到 session.selectList()
既能接受一个参数,也能接受两个参数。
那么可不可以,只写一个 SQL 语句, 当session.selectList()
只有一个参数的时候,进行全部查询,提供第二个参数的时候,提供模糊查询呢?答案是肯定的。
假如我们要查询的表是 Product_ 表,对应的java对象类为 Product 类。
Product.xml 修改前:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 <?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.how2java.pojo" > <select id ="listProduct" resultType ="Product" > select * from product_ </select > <select id ="listProductByName" resultType ="Product" > select * from product_ where name like concat('%',#{name},'%') </select > </mapper >
Product.xml 修改后:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <?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.how2java.pojo" > <select id ="listProduct" resultType ="Product" > select * from product_ <if test ="name!=null" > where name like concat('%',#{name},'%') </if > </select > </mapper >
其他动态SQL语句 除了 if 以外,还有 where、choose、foreach、bind等动态SQL语句,具体用法可以到网上查找。