首先明白 Mybatis 是干什么的, 之前使用 jdbc 操作数据库时候要写很多语句, 获取光标, 连接, 获取具体对象进行相应操作, 代码过于繁琐, 所以现在有了 Mybatis, 它将这个操作整合在了一起, 你不需要关心具体的和数据库的之间交互, 你现在只需要关心你的业务逻辑, 书写好你的 sql 语句, 并进行相应的配置就可以了, 这样大大提高了开发效率, 简化了不必要的代码. ps: 说实话我觉得 jdbc 操作真的繁琐, 要注意的太多了, 这种方式操作数据库方便多了, 毕竟我们重要的是业务逻辑代码.
这篇博客记录了基本的配置, statement 方式, 动态代理方式的增删改查
Mybatis 基本配置
1. 首先我们先从官网将压缩包下载下来, 然后将目录下的 .jar 文件引入项目文件之中, 在 Intellij 之下, 引入 jar 文件, 具体怎么引入问度娘, 注意这里暂时只需要引入一个. jar 文件, lib 目录下的 jar 文件相当于是扩展功能, 你需要的时候再引入. 然后用同样的方式将 jdbc 引入一下, 因为 Mybatis 是依赖于 jdbc 的, 是 jdbc 的一种封装可以理解为.
2. 好的接下来我们创建 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"> <!-- 默认的配置环境, 发行版本, debug 版本 -->
- <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/mybatis?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT"/>
- <property name="username" value="xxx"/>
- <property name="password" value="xxxx"/>
- </dataSource>
- </environment>
- </environments>
- <mappers>
- <!-- 加载映射文件, 有多个, 直接写相对于 src 文件的路径 -->
- <mapper resource="entity/PersonMapping.xml"/>
- </mappers>
- </configuration>
看它这个 xml 文件, 还是比较容易理解的, 注意两点,
1. 我这里使用的是 MySQL 8.0.2 版本, 配置和 MySQL 低版本不太一样, url 后面的参数是以 & 来分隔的. 虽然也不知道为撒这样, 反正人家这么规定的.
2. 最下面 < mappers > 加载映射文件的时候, 一个 < mapper resource-"xxx"/> 加载一个, resource 属性就是具体的映射文件相对于 src 文件的路径.
接下来我们创建 Person 类, 和数据库的一张表形成映射: 如下
- package entity;
- public class Person {
- private int id;
- private String name;
- private String loves;
- public Person(){
- }
- public Person(String name, String loves) {
- this.name = name;
- this.loves = loves;
- }
- public int getId(){return id;}
- public void setId(int id){this.id=id;}
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getLoves() {
- return loves;
- }
- public void setLoves(String loves) {
- this.loves = loves;
- }
- public String toString(){
- return "姓名:"+this.name+"\n 爱好:"+this.loves;
- }
- }
表 person 如下:
- create table person(
- `id` int(11) not null auto_increment primary key,
- `name` varchar(30) not null,
- loves varchar(40) not null
- )engine=innodb;
然后看映射文件 PersonMapping.xml 的配置, 这个映射文件和 Person 类时对应的, 配置的是关于表 person 和类 Person 的相关操作
<?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="entity.PersonMapping"> <!-- 该 mapping 文件的唯一映射 -->
- <select id="selectPersonById" resultType="entity.Person" parameterType="string">
- select * from person where `name` = #{name}
- </select>
- <insert id="insertOnePerson" parameterType="entity.Person">
- insert into person values(#{name},#{loves})
- </insert>
- <delete id="deleteOnePerson" parameterType="int">
- delete from person where id=#{id}
- </delete>
- </mapper>
可以看到首先 namespace 是该文件一个唯一标识, 就是该文件的路径 (相对于 src), 接下来有各种标签,<select> <delete> <insert> .. 这其实就对应了数据库的增删改查, 具体对哪一张表, 什么操作, 看你书写的 sql 语句, 因为我们看到标签体的内容就是 sql 语句, 举个例子:
- <insert id="insertOnePerson" parameterType="entity.Person" resultType="">
- insert into person values(#{name},#{loves})
- </insert>
这个标签是向数据库插入数据, id 代表的是该 sql 语句的唯一标识, parameterType 指的是传入的参数类型, 这里是 entity.Person,Person 使我们构造的一个类, resultType 是返回值的类型,
标签体是我们书写的 sql 语句, 这里是动态传值的方式, 输出格式是:#{变量名}, 对于变量名我们注意: 如果传入的是一个 string,int 等类型的数据, 那这个变量名可以是任何字符, 但是如果传入的是一个对象的话, 那么变量名就必须和该对象的属性一一对应起来, 比如 name 就指 person 对象的 name 属性, loves 指 person 的 loves 属性. 另外注意 Mybatis 传参只能传一个值, 但是有时候要传多个参数, 可以使用数组的方式传值.
同样的, 增删改查操作都是在相应的标签下书写 sql 语句来完成的.
statement 的增删改查
到这里我们的基本配置 demo 就算是完成了, 接下来写一个具体的操作例子, 首先分为三步:
1. 加载配置信息, 2. 获取 SqlSession 对象进行操作 3. 执行指定的 sql 语句
- public static void main(String[] args) throws IOException {
- // 加载配置信息
- Reader reader = Resources.getResourceAsReader("config.xml");
- //connection
- SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
- SqlSession sqlSession = sessionFactory.openSession();
- // 执行指定的 sql 语句
- String statement = "entity.PersonMapping.selectPersonById"; // 查询数据
- List<Person> persons = new ArrayList<Person>(sqlSession.selectList(statement,"温鸿飞"));
- for (Person person:persons) {
- System.out.println(person.toString());
- }
- statement = "entity.PersonMapping.deleteOnePerson"; // 删除数据
- sqlSession.delete(statement,1);
- System.out.println("------");
- statement = "entity.PersonMapping.selectPersonById"; // 查询数据
- persons = new ArrayList<Person>(sqlSession.selectList(statement,"温鸿飞"));
- for (Person person:persons) {
- System.out.println(person.toString());
- }
- sqlSession.commit();
- sqlSession.close();
- }
配置信息加载是通过 Reader reader = Resources.getResourceAsReader("config.xml"); 完成, config 就是我们刚才创建的配置文件, 告诉编译器都有哪些 mapper,
获取 SqlSession 对象, 这个不说了, 官网就是这么写的, 规定
然后到了具体的操作了, 看到我们先书写了一个 statement, 这个 statement 对应了刚才的 PersonMapping.xml 文件当中的一个标签, 格式是: namespace.id, 比如
entity.PersonMapping.deleteOnePerson 指的就是 deleteOnePerson 的标签, 之后用 SqlSession 来操作, 调用增删改查里面的一个方式, 传入 statement 和相应的参数就可以了, 比如删除
SqlSession.delete(statement,param); 之后有返回值的接受一下, 没有就算了. sqlSession.commit() 提交一下事务, 当然这里还有回滚等暂时不说了
上面的代码执行结果如下, 可以看到正确的查询到了数据并删除了 id 为 1 的数据
"C:\Program Files\Java\jdk-11.0.1\bin\java.exe" "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\lib\idea_rt.jar=63824:C:\Program Files\JetBrains\IntelliJ IDEA 2019.1.3\bin" -Dfile.encoding=UTF-8 -classpath C:\learn\java\mybatis\out\production\mybatis;C:\ 迅雷下载 \ mybatis-3.5.2\mybatis-3.5.2\mybatis-3.5.2.jar;C:\ 迅雷下载 \ MySQL-connector-java-8.0.16.jar entity.test
姓名: 温鸿飞
爱好: 哈啊哈哈
姓名: 温鸿飞
爱好: 21212121
姓名: 温鸿飞
爱好: 2121266
------
姓名: 温鸿飞
爱好: 21212121
姓名: 温鸿飞
爱好: 2121266
到这里我们的第一个 statement 小 demo 就算成功完成了, 但使用 statement 的话, 每次都要书写 statement, 很繁琐, 所以我们有了动态的进行增删改查的方式, 其实就是将 statemtn 语句进行约定, 名字什么都是有固定规则的, 简化代码, 省略掉 statement, 简单来讲, 让约定优于配置, 根据约定定位 sql 语句
具体的话, 看下面:
定义一个接口, 通过这个接口来替代 statement, 该接口有如下规则;
1. 接口名和映射. xml 文件的文件名相同
2. 接口之中的抽象方法的方法名, 返回值, 参数和映射. xml 之中配置的均相同,
3. 注意一下如果要返回一个数组的话, 使用 List<className> 作为返回类型
定义好了之后通过 SqlSession.getMapper(接口名字. class); 来获取到操作数据库的对象, 之后调用该接口的方法就可以了, 具体代码如下:
PersonMapping 接口
- package mappers;
- import entity.Person;
- import java.util.List;
- // 操作 person 类的接口
- public interface PersonMapping { // 接口名也一样
- public abstract Person selectPersonById(int id); // 方法名, 返回值, 参数均和配置一样
- void deletePersonById(int id);
- void insertOnePerson(Person person);
- public abstract List<Person> selectPersonByName(String name);
- }
main 函数之中:
- public class test {
- public static void main(String[] args) throws IOException {
- // 加载配置信息
... 获取到 SqlSession 对象, 和前面一样 // 获取到 mapper 对象
- PersonMapping personMapping = sqlSession.getMapper(PersonMapping.class);
- // 调用接口方法操作数据库
- Person person = personMapping.selectPersonById(2);
- System.out.println(person);
- List<Person> persons = personMapping.selectPersonByName("温鸿飞");
- for (Person temp:persons) {
- System.out.println(temp);
- }
- sqlSession.commit();
- sqlSession.close();
- }
- }
感觉这和 symfony 里面的 Respository 一样呀, 不过你这个还要自己配置, Symfonyh 都自己配置好了, 你直接实例化对象就行了, symfony 很强呀
来源: https://www.cnblogs.com/eenio/p/11314611.html