Mybatis的基本使用

Myabtis

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

Myabtis基本配置方式:

1.新建Maven项目

2.删除src

3.数据库中建立测试表

4.在pom.xml导入maven依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
<!--    父工程-->
<groupId>com.MyZhis</groupId>
<artifactId>Myabtis-Study</artifactId>
<version>1.0-SNAPSHOT</version>

<!--  导入依赖  -->
<dependencies>
    <!--   mysql驱动     -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>5.1.46</version>
    </dependency>
    <!--    mybatis    -->
    <dependency>
        <groupId>org.mybatis</groupId>
        <artifactId>mybatis</artifactId>
        <version>3.5.2</version>
    </dependency>
    <!--    junit    -->
    <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.12</version>
    </dependency>
</dependencies>
    
</project>

4.1加载依赖

5.创建maven Module子模块

在子模板pom.xml写入

<build>
    <!-- 自动查找配置路径 -->
    <resources>
        <resource>
            <directory>src/main/java</directory>
            <includes>
                <include>**/*.xml</include>
            </includes>
        </resource>
    </resources>
</build>
6.配置configuration核心文件(类似于数据库驱动)mybatis-config
<?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 核心配置文件-->
<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/mybatis?useSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF-8"/>
                <property name="username" value="root"/>
                <property name="password" value="root"/>
            </dataSource>
        </environment>
    </environments>
<!--  每一个mappers.xml都需要在mybatis核心配置中心注册!  -->
    <mappers>
        <mapper resource="com/mybatis/dao/UserMapp.xml"></mapper>
    </mappers>
</configuration>
7.创建包框架:dao,pojo,utility

在utility写入SqlSessionFactory工具类

//工具类
public class MybatisUtils {
    
    private static SqlSessionFactory sqlSessionFactory;
    
    //使用mybatis获取sqlSessionFactory对象
    //resource要与configuration配置文件相对应
    static {
        String resource = "mybatis-config.xml";
        InputStream inputStream = null;
        try {
            inputStream = Resources.getResourceAsStream(resource);
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /*
    既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。
    SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。
     */
    public static SqlSession getSqlSession(){
        return sqlSessionFactory.openSession();
    }
}

在pojo写入与数据库对应的实体类

public class User {
    private int id;
    private String name;
    private String password;

    public int getId() {
        return id;
    }

    public User(int id, String name, String password) {
        this.id = id;
        this.name = name;
        this.password = password;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}
在dao中写入接口文件和Mapp配置文件:

接口:

public interface UserDao {
    List<User> getUserList();
}

配置:

namespace要和dao中写入的Mapp接口对应

<?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">
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<!--
namespace要与dao中写入的Mapper对应
select标签中的id要与Mapper定义的接口名对应
select标签中的resultType响应要与实体类路径对应
-->
<mapper namespace="com.mybatis.dao.UserDao">
    <!--  类似与daoImpl  -->
    <select id="getUserList" resultType="com.mybatis.entriy.User">
        select * from mybatis_text;
    </select>
</mapper>
8.编写测试类
package com.mybatis.dao;

import com.mybatis.entriy.User;
import com.mybatis.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;

import java.util.List;

public class UserDaoTest {
    @Test
    public void test(){//查询数据
        //第一步:获得SqlSession对象
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        /*
        方式1:getMapper
        	getMapper中的参数要与dao中的接口对应
        	List中的参数要与实体类对应
        */
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user.getName());
        }
        //关闭sqlSession
        sqlSession.close();
    }

}

Mapp增删改查代码:

mapp增删改查配置文件代码:
<!--namespace=绑定一个对应的Dao/Mapper接口-->
<mapper namespace="com.mybatis.dao.UserDao">
    <!--  类似与daoImpl  -->
    <select id="getUserList" resultType="com.mybatis.entriy.User">
        select * from mybatis_text;
    </select>
    
    <select id="getUserName" resultType="com.mybatis.entriy.User" parameterType="int">
        select * from mybatis_text where id = #{id}
    </select>

    <insert id="insertUser" parameterType="com.mybatis.entriy.User">
        insert into mybatis_text values(null,#{name},#{password})
    </insert>
    
    <update id="updateUser" parameterType="com.mybatis.entriy.User">
        update mybatis_text set name = #{name} where id = 1;
    </update>

    <delete id="deleteUser" parameterType="int">
        delete from mybatis_text where id = #{id};
    </delete>

    <update id="TestUser" parameterType="map" >
        update mybatis_text set name = #{newName}  where name = #{name};
    </update>
</mapper>

添删改查测试类代码:
public class UserDaoTest {
    @Test
    public void test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        List<User> userList = mapper.getUserList();
        for (User user : userList) {
            System.out.println(user.getName());
        }
        sqlSession.close();
    }

    @Test
    public void select(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        User userName = mapper.getUserName(1);
        System.out.println(userName.getPassword());
        sqlSession.close();
    }

    //增删改需要提交事务
    @Test
    public void insert(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        mapper.insertUser(new User(0,"李四","135"));
        sqlSession.commit();//提交事务
        sqlSession.close();
    }

    @Test
    public void update(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        mapper.updateUser(new User(0,"啊多跟","4566"));
        sqlSession.commit();
        sqlSession.close();
    }

    @Test
    public void delete(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        mapper.deleteUser(1);
        sqlSession.commit();
        sqlSession.close();
    }

    //使用map标签来传递所需要的参数(用在需要传递的参数和构造方法不匹)
    @Test
    public void Test(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserDao mapper = sqlSession.getMapper(UserDao.class);
        Map<String,Object> map = new HashMap();
        map.put("newName","新的名字");
        map.put("name","李四");
        mapper.TestUser(map);
        sqlSession.commit();
        sqlSession.close();
    }
}
mapp接口代码:
public interface UserDao {
    List<User> getUserList();

    User getUserName(int id);

    boolean insertUser(User user);

    void updateUser(User user);

    void deleteUser(int id);

    void TestUser(Map<String,Object> map);
}

配置映射器

方式1【推荐使用】
<!--每一个Mapper.xml都需要在MyBatis核心配置文件中注册-->
<mappers>
	<mapper resource="com/kuang/dao/UserMapper.xml"/>
</mappers>
方式2

使用class文件绑定注册:

<mappers>
   <mapper class="com.kuang.dao.UserMapper"/>
</mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名
  • 接口和它的Mapper配置必须在同一个包下
方式3

使用扫描包进行注册绑定:

<mappers>
	 <package name="com.kuang.dao"/>
</mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名
  • 接口和它的Mapper配置必须在同一个包下

配置别名:

在mybatis-config.xml配置文件中添加配置别名

<!--    配置別名    -->
<typeAliases>
    <!--    配置別名,指定类,可取指定别名    -->
    <!-- alias为别名名称 type为返回类型 -->
    <typeAlias type="com.mybatis.entriy.User" alias="User"/>
    <!--   包别名,不可指定别名,使用填name包中的参数即可     -->
    <package name="com.mybatis.entriy"/>
</typeAliases>

mapper配置文件代码:

<!-- 配置前 -->
<insert id="insertUser" parameterType="com.mybatis.entriy.User">
    insert into mybatis_text values(null,#{name},#{password})
</insert>

<!-- 配置后 -->
<insert id="insertUser" parameterType="User">
    insert into mybatis_text values(null,#{name},#{password})
</insert>

结果集映射

ResultMap是MyBatis中最强大的元素

ResultMap设计思想是,对于简单的语句根本不需要配置显示的结果映射,而对于复杂一点的语句只描述他们的关系就行了

<!--  结果集映射  -->
<!-- id为mapper中的resultType的命名 type为类型(实体类) -->
<resultMap id="UserMap" type="User">
    <!--    column数据库字段, property实体类中的属性    -->
    <!--    例如数据库字段和实体类属性名不相同,则可以使用结果集映射    -->
    <result column="" property=""/>
</resultMap>
<select id="getUserList" resultType="UserMap">
    select * from mybatis_text where;
</select>

日志工厂

在mybatis-confing.xml配置文件中添加日志工厂,可以通过输出的日志观察运行实现原理

<settings>
    <setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>

注解执行sql语句

可以不通过mapp执行sql语句,只需接口即可,简易sql语句实用,复杂还是建议使用xml

不带参注解

接口代码:

@Select("select * from mybatis_text")
List<User> selectUser();

测试代码:

@Test
public void TestSelect(){//注解查询
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    List<User> user = mapper.selectUser();
    for (User user1 : user) {
        System.out.println(user1.getName());
    }
    sqlSession.close();
}
带参注解

接口代码:

//方法存在多个参数,所有参数都必须在前面加上@Param(),取值依旧是#{}
@Select("select * from mybatis_text where id = #{id}")
User selectUserValue(@Param("id") int id);

测试代码:

public void TestSelectValue(){//注解带参查询
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    UserDao mapper = sqlSession.getMapper(UserDao.class);
    User user = mapper.selectUserValue(8);
    System.out.println(user.getName());
    sqlSession.close();
}

面试题:${}和#{}的区别

#{}能够更好的防止sql注入,${}的where条件永远为true


Lombok插件

可以起到使用注解既对实体快速封装等

使用步骤:

1.在IDEA中安装Lombok插件

2.在项目中导入lombok的jar包

<dependencies>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>1.18.10</version>
    </dependency>
</dependencies>

3.在实体中加注解

//@Data自动封装,无参构造,equals,hashCode
public class User {
    private int id;
    private String name;
    private String password;
}

使用resultMap“多对一”连表(association)

子查询方式(复杂):

举例使用resultMap执行链表查询:

实体类:

public class Student {
    private int id;
    private String name;
    private Teacher teacher;
}

public class Teacher {
    private int id;
    private String name;
}

接口:

public interface StudentMapper {

    List<Student> getStudent();
    
}

mapper配置文件(使用resultMap链表查询):

<!--  resultMap id:姓名 type为类型  -->
<resultMap id="StudentTeacher" type="Student">
    <!--    property为java中的属性名 column为数据库id   -->
    <result property="id" column="id"/>
    <result property="name" column="name"/>
    <!--    
			复杂的属性我们需要单独处理
            对象使用:association
            集合使用:collection
     -->
    <!--   property为java属性 column为数据库id javaType为类型 select为嵌套查询    -->
    <!--   select填入嵌套查询的id即可 -->
    <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>

<select id="getStudent" resultMap="StudentTeacher">
    select * from student;
</select>

<select id="getTeacher" resultType="Teacher">
    select * from teacher where id = #{tid};
</select>

测试类:

@Test
public void getStudent(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> studentList = mapper.getStudent();
    for (Student student : studentList) {
        System.out.println(student);
    }
}

结果:

Student{id=1, name='张三', teacher=Teacher{id=1, name='黄老师'}}
Student{id=2, name='李四', teacher=Teacher{id=1, name='黄老师'}}
Student{id=3, name='王五', teacher=Teacher{id=1, name='黄老师'}}
Student{id=4, name='赵六', teacher=Teacher{id=1, name='黄老师'}}
子查询方式(简易):

实体类,接口,测试类代码于上述相同

mapper代码:

<resultMap id="StudentTeacher" type="Student">
    <result property="id" column="sid"/>
    <result property="name" column="sname"/>
    <association property="teacher" javaType="Teacher">
        <result property="name" column="tname"/>
    </association>
</resultMap>
	
    <select id="getStudent" resultMap="StudentTeacher">
        SELECT s.id as sid,s.name as sname,t.name as tname
        FROM student s,teacher t
        WHERE s.tid = t.id
    </select>

结果:

Student{id=1, name='张三', teacher=Teacher{id=1, name='黄老师'}}
Student{id=2, name='李四', teacher=Teacher{id=2, name='黄老师'}}
Student{id=3, name='王五', teacher=Teacher{id=3, name='黄老师'}}
Student{id=4, name='赵六', teacher=Teacher{id=4, name='黄老师'}}

使用resultMap”一对多“连表(collection)

子查询方式(简易)

实体类:

public class Student {
    private int id;
    private String name;
    private int tid;
}

public class Teacher {
    private int id;
    private String name;
    private List<Student> students;
}

接口:

public interface TeacherMapper {

    Teacher selectTeacher(@Param("tid") int id);

}

mapper配置文件(使用resultMap链表查询):

<select id="selectTeacher" resultMap="TeacherStudent">
        SELECT s.id as sid,s.name as sname,t.id as tid,t.name as tname
        FROM student s,teacher t
        WHERE s.tid = t.id and t.id = #{tid}
    </select>

	<!-- result中的"property"是从实体类中拿的属性名 "column"是由select标签中拿的字段名  -->
    <resultMap id="TeacherStudent" type="Teacher">
        <result property="id" column="tid"/>
        <result property="name" column="tname"/>
        <!-- studens为复杂结果集,由于他是集合,所以我们使用collection标签 -->
        <!-- property是实体类中的属性名 ofType是类型,类型为集合型的Student对象 -->
        <collection property="students" ofType="Student">
        <!-- 可以在collection标签中继续使用result,此时的result参数指向ofType中的属性 column同上  -->
            <result property="id" column="sid"/>
            <result property="name" column="sname"/>
            <result property="tid" column="tid"/>
        </collection>
    </resultMap>

测试类:

@Test
public void selectTeacher(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
        Teacher teachers = mapper.selectTeacher(1);
        System.out.println(teachers);
    }

结果:

Teacher{id=1, name='黄老师', students=[Student{id=1, name='张三', tid=1}, Student{id=2, name='李四', tid=1}, Student{id=3, name='王五', tid=1}, Student{id=4, name='赵六', tid=1}]}

动态SQL

所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面添加条件,去执行逻辑筛选

IF

实体代码:

public class Blog {
    private String id;
    private String title;
    private String author;
    private Date create_time;
    private int views;
}

接口代码:

List<Blog> queryBlogIF(Map map);

mapper代码:

<!--  resultType是返回响应类型 parameterType是参数类型  -->
<select id="queryBlogIF" parameterType="map" resultType="Blog">
    select * from blog where 1=1
    <!--  使用1=1是为了方便后续拼接和避免拼接不合理出现sql错误  -->
    <if test="title != null">
        and title = #{title}
    </if>
    <if test="author !=null">
        and author = #{author}
    </if>
</select>

测试代码:

@Test
public void queryBlogIF(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    map.put("title","Java");
    map.put("author","红猫");
    List<Blog> blogs = mapper.queryBlogIF(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

这里使用了动态SQL IF,我们可以借助于if来筛选出自己想要查询的内容,首先接触map,在mapper的if中,取map中的键值来判断是否为空,如果不为空则拼接上if标签中的字段,这里使用的普通if,所以if条件满足的情况下可以继续往下筛选

where
<select id="queryBlogWhere" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <if test="title != null">
            and title = #{title}
        </if>
        <if test="author !=null">
            and author = #{author}
        </if>
    </where>
</select>

当我们使用where标签的时候,如果条件满足至少一条,它会智能的为语句添加whrer并且智能的将and去除或添加

where choose(满足) otherwise(不成立)
<select id="queryBlogChoose" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <choose>
            <when test="title != null">
                title = #{title}
            </when>
            <when test="author != null">
                and author = #{author}
            </when>
            <otherwise>
                and views = #{views}
            </otherwise>
        </choose>
    </where>
</select>

when同样会条件筛选(与if同理),并且在不需要and的情况下默认将and去除,如果条件都不满足,那么会进入到otherwise标签

set if
<update id="updateBlog" parameterType="map">
    update blog
    <set>
        <if test="title != null">
            title = #{title},
        </if>
        <if test="author != null">
            author = #{author}
        </if>
    </set>
    where id = #{id}
</update>

set用于修改,可以智能省略",“号,例如传递过来的map只有title有值,他将会默认将”,"号去除,为程序正常运行

测试类代码:

public void updateBlog(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    map.put("title","Mybatis");
    map.put("author","紫猫");
    map.put("id","66ea29ed3fb54c7ab1558f68e0eec16f");
    int resultBlog = mapper.updateBlog(map);
    sqlSession.commit();
    sqlSession.close();
}
sql - include片段引入
<!-- sql存储 -->
<sql id="if-title-author">
    <if test="title != null">
        and title = #{title}
    </if>
    <if test="author !=null">
        and author = #{author}
    </if>
</sql>

<select id="queryBlogWhere" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <!-- include引入,通过refid引入对应的sql -->
        <include refid="if-title-author"></include>
    </where>
</select>

使用sql存储条件代码,使用include引入条件,优点在于代码复用等…

注意事项

1.最好基于单表来定义sql

2.抽取的sql片段不可以存在where标签

动态SQL就是在拼接SQL语句,我们只要保证SQL的正确性,按照SQL格式去排列组合就可以了

foreach

实体代码:

@Test
public void queryBlogForEach(){
    SqlSession sqlSession = MybatisUtils.getSqlSession();
    BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
    Map map = new HashMap();
    ArrayList<Integer> ids = new ArrayList<Integer>();
    ids.add(1);
    map.put("ids",ids);
    List<Blog> blogs = mapper.queryBlogForeach(map);
    for (Blog blog : blogs) {
        System.out.println(blog);
    }
    sqlSession.close();
}

接口代码:

List<Blog> queryBlogForeach(Map map);

mapper代码:

<select id="queryBlogForeach" parameterType="map" resultType="Blog">
    select * from blog
    <where>
        <!-- 
			在foreach标签中,collection元素等于传递过来的参数名,item等于数据库字段,
			open等于拼接初始值,close等于结尾,sparator等于拼接符
 		-->
        <foreach collection="ids" item="id"  open="and (" separator="or" close=")" >
            id = #{id}
        </foreach>
        <!-- 
		所以当我们使用上述foreach时,collection在测试代码中是list存储好的map值,map中的建值为ids
 		item对应数据库中的字段,open对应拼接的开头,代码如下:select * from blog where and(
		但foreach标签会智能省去不必要的符号,所以and符号去除:select * from blog where (
		separator代表拼接符号,所以ids的值如果为2那么就是需要拼接两次,和上述close结尾相连为:
		SELECT * FROM blog WHERE (id = 1 OR id = 2),以此来实现用标签来更改sql语句	
		-->
    </where>
</select>

缓存

一级缓存

缓存失效的情况:

1.查询不同数据

2.增删改操作,可能会改变原来的数据,所以必定会刷新缓存

3.查询不同的mapper.xml

4.手动清理缓存

二级缓存

二级缓存也叫全局缓存,一级缓存作用域太低,所以诞生二级缓存

基于namespce级别缓存,一个名称空间,对应一个二级缓存

工作机制:

​ 一个会话查询一条数据,这个数据就会被放在当前会话的一级缓存

​ 如果当前会话关闭,这个会话对应的一级缓存就没了,但我们想要的是,会话关闭了,一级缓存中的数据被保存在二级缓存中

​ 新的会话查询信息,就可以从二级缓存中获取内容

​ 不同的mapper查出的数据会放在对应的缓存(map)中

步骤

1.开启全局缓存(默认开启)

<!--    显示开启全局缓存    -->
<setting name="cacheEnabled" value="true"/>

2.在要使用二级缓存的mapper中开启

<!-- 在当前Mapper.xml中使用二级缓存 -->
<!-- 开启普通缓存 -->
<cache/>
<!-- 自定义参数缓存 -->
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
缓存原理:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-4XjaH10R-1615976524393)(C:\Users\admin\AppData\Roaming\Typora\typora-user-images\image-20210301101128010.png)]

逆向工程

mybatis官方提供了mapper自动生成工具mybatis-generator-core来针对单表,生成PO类,以及Mapper接口和mapper.xml映射文件。针对单表,可以不需要再手动编写xml配置文件和mapper接口文件了,非常方便。美中不足的是它不支持生成关联查询。一般做关联查询,就自己单独写SQL就好了。

基于IDEA的mybatis逆向工程操作步骤如下

1.配置maven插件
<build>
        <plugins>
            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.7</version>
                <configuration>
                    <!-- 输出日志 -->
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>
2.在resources目录下创建名为generatorConfig.xml的配置文件

image-20200527203556766

3.配置文件的模板如下
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
        PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
        "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">

<generatorConfiguration>
    <!--导入属性配置-->
    <properties resource="properties/xx.properties"></properties>

    <!-- 指定数据库驱动的jdbc驱动jar包的位置 -->
    <classPathEntry location="C:\Users\Vergi\.m2\repository\mysql\mysql-connector-java\8.0.11\mysql-connector-java-8.0.11.jar" />
    <!-- context 是逆向工程的主要配置信息 -->
    <!-- id:起个名字 -->
    <!-- targetRuntime:设置生成的文件适用于那个 mybatis 版本 -->
    <context id="default" targetRuntime="MyBatis3">
        <!--optional,旨在创建class时,对注释进行控制-->
        <commentGenerator>
            <property name="suppressDate" value="true" />
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!--jdbc的数据库连接-->
        <jdbcConnection driverClass="${db.driver}"
                        connectionURL="${db.url}"
                        userId="${db.user}"
                        password="${db.password}">
        </jdbcConnection>


        <!--非必须,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <!-- 默认情况下数据库中的 decimal,bigInt 在 Java 对应是 sql 下的 BigDecimal 类 -->
            <!-- 不是 double 和 long 类型 -->
            <!-- 使用常用的基本类型代替 sql 包下的引用类型 -->
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- targetPackage:生成的实体类所在的包 -->
        <!-- targetProject:生成的实体类所在的硬盘位置 -->
        <javaModelGenerator targetPackage="mybatis.generator.model"
                            targetProject=".\src\main\java">
            <!-- 是否允许子包 -->
            <property name="enableSubPackages" value="false" />
            <!-- 是否清理从数据库中查询出的字符串左右两边的空白字符 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!-- targetPackage 和 targetProject:生成的 mapper.xml 文件的包和位置 -->
        <sqlMapGenerator targetPackage="mybatis.generator.mappers"
                         targetProject=".\src\main\resources">
            <!-- 针对数据库的一个配置,是否把 schema 作为字包名 -->
            <property name="enableSubPackages" value="false" />
        </sqlMapGenerator>

        <!-- targetPackage 和 targetProject:生成的 mapper接口文件的包和位置 -->
        <javaClientGenerator type="XMLMAPPER"
                             targetPackage="mybatis.generator.dao" targetProject=".\src\main\java">
            <!-- 针对 oracle 数据库的一个配置,是否把 schema 作为子包名 -->
            <property name="enableSubPackages" value="false" />
        </javaClientGenerator>
        <!-- 这里指定要生成的表 -->
        <table tableName="student"/>
        <table tableName="product"/>
    </context>
</generatorConfiguration>
4.双击执行mybatis-generator的maven插件

image-20200527203902491

生成的文件如下

image-20200527204043910

能看到mybatis-generator除了给我们生成了基本的PO类(上图的Student和Product),还额外生成了Example类。Example类是为了方便执行SQL时传递查询条件的。使用的示例如下
public class GeneratorTest {

   private SqlSessionFactory sqlSessionFactory;

   @Before
   public void init() throws IOException {
      InputStream resourceAsStream = Resources.getResourceAsStream("mysql8-config.xml");
      sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
   }

   @Test
   public void test() {
      SqlSession sqlSession = sqlSessionFactory.openSession();
      StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
      StudentExample example = new StudentExample();
      StudentExample.Criteria criteria = example.createCriteria();
      criteria.andNameLike("%o%");
      List<Student> students = mapper.selectByExample(example);
      students.forEach(System.out::println);
   }
}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值