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&useUnicode=true&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的配置文件
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插件
生成的文件如下
能看到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);
}
}