前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis必会(详细精美版,保姆级讲解,带Java示例)

Mybatis必会(详细精美版,保姆级讲解,带Java示例)

作者头像
CaesarChang张旭
发布2021-01-26 15:08:14
8310
发布2021-01-26 15:08:14
举报
文章被收录于专栏:悟道

~关注我 带你看更多精品技术和面试必备

号码 1153132260

1.Mybatis介绍

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射 MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息, 将接口 和 Java 的 POJOs( Java对象)映射成数据库中的记录。

2.搭建Mybatis

2.1.添加驱动包(mysql.jar和mybatis的jar包)

<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.40</version> </dependency>

2.2. 添加配置文件 :src/mybatis-confifig.xml

连接数据库的配置文件的作用 : (1). 指定连接数据库的 url,username,password,driver (2). 由框架自动获取连接 (3). 指定了事务的管理对象 配置文件中 default 要和 id 值相同, default 表示默认访问环境, 但是也可以自己指定使用哪个 id 数据源 , 代码如下 : SqlSession session= new SqlSessionFactoryBuilder().build(r,"a2").openSession();

<?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"> <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/dbName"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <!-- 指定maper文件的路径(maven项目从resources源文件夹下找资源)--> <mappers> <mapper resource="包名/mapper文件名"/> </mappers> </configuration>

3. 创建实体类和接口类

4. 添加 mapper 文件

注 : 在 mapper 文件中保存 sql 语句

<mapper namespace=" 接口的完整路径 "> <insert id=" 方法名 " parameterType=" 参数类型 "> //sql语句 </insert> <select id=" 方法名 " resultType=" 查询后的返回值类型 "> //sql 语句 --- 注: sql 语句没有分号 </select> </mapper>

5. 修改 mybatis 的配置文件 , 让该配置文件知道 mapper 文件的存在

6. 获得 SqlSession, 通过该对象进行数据的操作

//1.加载配置文件 Reader r=Resources.getResourceAsReader("mybatis-config.xml"); //2.创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder builder= new SqlSessionFactoryBuilder(); //3.得到session工厂 SqlSessionFactory factory=builder.build(r); //4.得到session SqlSession session= factory.openSession(); //5.调取sql语句,insert("方法的完整路径"),路径=namespace+id int rs=session.insert("dao.EmpDao.insertEmp",e); session.commit();

3.Mybatis实现CRUD

mapper 文件中参数的读取 :

单个基本类型参数或 String 类型:

mapper 读取参数: #{ 参数名 ( 也可以是自定义名称 )}

参数类型为对象类型时,读取参数的语法 : #{ 对象中的属性名 }

insert,delete,update,select 中的 parameterType 参数可以省略

多个参数值的情况 ?

将参数封装到 map 集合中,再将 map 集合传递给 mapper 文件

取值的时候, #{map 的 key 值 }

处理结果没有和实体类做对应的时候,可以返回 map 类型

<select id="jisuan" resultType="map">

在做查询时,如果需要将查询的结果和实体类属性自动对应的话,要求:属性名 = 列名

添加: session.insert("namespace+id"[, 传递给 sql 的参数值 ]);

修改: session.update("namespace+id"[, 传递给 sql 的参数值 ]);

删除 :session.delete("namespace+id"[, 传递给 sql 的参数值 ]);

单行: session.selectOne("namespace+id"[, 传递给 sql 的参数值 ]);

多行 :session.selectList("namespace+id"[, 传递给 sql 的参数值 ]);

处理多个聚合函数 : 使用 map 作为方法的返回值,默认 key 是列名

注意:增删改的时候需要提交事务

session.commit();

session.rollback();

查询的时候要添加 resultType 属性

4. 省略实现类

Reader r=Resources.getResourceAsReader("mybatis.xml");

SqlSession session= new SqlSessionFactoryBuilder().build(r).openSession();

// 参数是接口的 class 类

StudentDao dao=session.getMapper(StudentDao.class);

5.ThreadLocal 处理 sqlSession

介绍:ThreadLocal 是什么呢?其实 ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是 threadlocalvariable (线程局部变量) 。也许把它命名为 ThreadLocalVar 更加合适。线程局部变量 (ThreadLocal) 其实 的功用非常简单,就是 为每一个使用该变量的线程都提供一个变量值的副本 ,是 Java 中一种较为特殊的线程绑定机 制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。 ThreadLocal类型的变量一般用private static加以修饰

//把SqlSession静态共享 每次用每次get就好

示例 :

SessionUtil 类 :

public class XXX { private static ThreadLocal<SqlSession> threadLcoal = new ThreadLocal<SqlSession>(); private static SqlSessionFactory SqlSessionFactory; /** * * 加载配置文件 */ static{ try{ Reader reader = Resources.getResourceAsReader("mybatis.cfg.xml"); SqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); }catch(IOException e){ e.printStackTrace(); throw new RuntimeException(e); } } /** * * 获取SqlSession * * @return */ public static SqlSession getSqlSession(){ //从当前线程获取 SqlSession sqlSession = threadLcoal.get(); if(sqlSession == null){ sqlSession = SqlSessionFactory.openSession(); //将sqlSession与当前线程绑定 threadLcoal.set(sqlSession); } return sqlSession; } /** * 关闭Session */ public static void closeSqlSession(){ //从当前线程获取 SqlSession sqlSession = threadLcoal.get(); if(sqlSession != null){ sqlSession.close(); threadLcoal.remove(); } } }

6.给类起别名<!—给实体类起别名 -->

1 <typeAliases> <!-- <typeAlias alias="u" type="com.yhp.bean.Users"> </typeAlias>--> 2 <!--给包中的类起别名 , 默认更改后的别名为 : 全部小写小写的类名 --> <package name="bean"></package> </typeAliases>

7.获得新增数据的id

适用于可以自增的主键列上

<insert useGeneratedKeys="true" keyProperty="userid">

然后你使用可以输出他的 类名.getXXId()

8.log4j显示sql语句

log4j 日志记录

步骤 : 添加 jar 包和 log4j.properties 文件

<dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-api</artifactId> <version>1.7.5</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-log4j12</artifactId> <version>1.7.12</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>

同时还要新建一个 log4j.properties 在resource包下,内容为:

如下

log4j.rootLogger=DEBUG, Console log4j.appender.Console=org.apache.log4j.ConsoleAppender log4j.appender.Console.layout=org.apache.log4j.PatternLayout log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n log4j.logger.java.sql.ResultSet=INFO log4j.logger.org.apache=INFO log4j.logger.java.sql.Connection=DEBUG log4j.logger.java.sql.Statement=DEBUG log4j.logger.java.sql.PreparedStatement=DEBUG

9.Mybatis复杂查询

9.1 in 查询

foreach 标签中属性说明 :

item 表示集合中每一个元素进行迭代时的别名,等同于 c 标签中的 var

index 指定一个名字,用于表示在迭代过程中,每次迭代到的位置,可以不写

open 表示该语句以什么开始,

separator 表示在每次进行迭代之间以什么符号作为分隔符,

close 表示以什么结束,

注意 : 在使用 foreach 的时候最关键的也是最容易出错的就是 collection 属性,

collection 该属性是必须指定的

list 时取值 list, 数组时取值 array, map 时取值 map的 key

(1) 参数是 list <select id="findall" resultType="bean.Emp"> select * from emp where empno in <foreach collection="list" index="b" item="a" open="(" separator="," close=")" > #{a} </foreach> </select>

注意 :parameterType 的值可以省略 (2) 参数是数组 <select id="findall" resultType="bean.Emp"> select * from emp where empno in <foreach collection="array" index="b" item="a" open="(" separator="," close=")" > #{a} </foreach> </select> 注意 :parameterType 的值可以省略

(3) 参数 Map

<select id="findall" resultType="bean.Emp"> select * from emp where empno in <foreach collection="keya" index="b" item="a" open="(" separator="," close=")" > #{a} </foreach> </select> 注意 :parameterType 的值可以省略 传的值 : Map map=new HashMap(); map.put("keya", list1);

​​

9.2 模糊查询

(1) 模糊查 + 分页

如果传递的参数是多个时? ------ 使用 Map 集合

String sql;

StringBuffffer sql;// 动态 sql 的保存

(2) 动态 sql

模糊查询 : <if test=" 属性名 != 属性值 "> and ename like '${ 属性名 }' </if>

注意 : test 属性中读取属性值时直接写属性名

模糊查询读取属性时使el 表达式,${属性名} 除以上位置外,都使用#{属性名}

多个条件时使用 and,or 拼接

如果传递过来的是 map 类型,则 test 属性中写的是 key #{}: 相当于占位符

#{id} :其中的 id 可以表示输入参数的名称,如果是简单类型名称可以任意

${}: 表示拼接 sql 语句

示例: <if test="ename!=null and ename!=''"> and ename like '%${属性名}%' </if> 或者: and sname like "%"#{username}"%" 或者: sname like concat('%',#{username},'%')

一定要加上 1=1,因为如果不加会造成 如果第一个为空不执行,直接就 where and studentno like '%${sno}% 从而报错

9.3 区间查询

between 开始值 and 结束值

<if test="stu.endTime!=null and stu.endTime!=''"> and regdate <![CDATA[ <= ]]> #{stu.endTime} </if> 加上<![CDTA[<=]]>会 输出 <=

9.4 resultMap

(1) 处理单表关系

通过给列起别名,让别名 = 属性名,也可以实现数据对应

resultType=" 指定返回值的类型 "// 当列名和属性名一致时使用

resultMap="key 值 " //1. 当列名和属性名不一致

2. 做多表查询时 mybatis 能实现的是单标的自动操作

<resultMap id="aaa" type="bean.Dept"> <!-- 可以手动指定列名和属性名的关系 , 非主键列使用 result 标签,主键列使用id 标签 --> <id property="dept_no" column="deptno"></id> <result property="d_name" column="dname"/> <result property="d_loc" column="loc"/> </resultMap>

(2) 处理多表关系

两表联查 : 一对多 和 多对一

注 : 如果是单表查询 ,select 中使用 resultType 设置返回的类型即可 但是如果是多表联查 , 那么 select 查询的结果需要单独使用自定义的 resultMap 标签来 进行结果的映射

存的是集合的话使用 Collection 子标签

存的是一方的话使用 association 子标签

resultType 和 resultMap 属性只能出现一个

格式:

一对多 :

<resultMap type="" id=" 自定义名称 "> <id property="id" column="dept_id" /><!-- 主键列 --> <result property="java 属性名 " column=" 列名 " /> < collection property=" 属性名 " ofType="java 类型 "> <id property=" 属性名 " column=" 列名 " /> <result property=" 属性名 " column=" 列名 " /> </collection> </resultMap>

多对一:

<resultMap type="" id=""> <id property="" column="" /> <result property="" column="" /> < association property="" javaType=""> <id property="" column="" /> <result property="" column="" /> </association> </resultMap>

JavaType 和 ofType 都是用来指定对象类型的,但是 JavaType 是用来指定单个 pojo 中属性的类型,而 ofType 指定的是映 射到list 集合属性中 pojo 的类型。

10.pageHelper分页

sql 语句只需要查询数据,不实现分页代码

方式 1 :内存分页

Mybatis 使用 RowBounds 对象进行分页,它是针对 ResultSet 结果集执行的内存分页,。可以在 sql 内

直接书写带有物理分页的参数来完成物理分页功能,也可以使用分页插件来完成物理分页。

优缺点

物理分页每次都要访问数据库,逻辑分页只访问一次

物理分页占用内存少,逻辑分页相对较多 物理分页数据每次都是最新的,逻辑分页有可能滞后

rowBounds 实现分页 :

结果:

方式 2: 使用分页插件

分页插件的基本原理是使用 Mybatis 提供的插件接口,实现自定义插件,在插件的拦截方法内拦截待执行的 sql ,然

后重写 sql ,根据 dialect 方言,添加对应的物理分页语句和物理分页参数。

示例 :

(a) 导入 jar 包

分页插件 :pagehelper.jar

sql 解析工具 :jsqlparser.jar

<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.6</version> </dependency>

(b) 在 MyBatis 的总体文件中配置插件

放到之前

<plugins> <!-- PageHelper4.1.6 --> <plugin interceptor="com.github.pagehelper.PageHelper"> <property name="dialect" value="mysql"/> </plugin> </plugins> 注意 : 插件 5.1 以后 interceptor 不同,并且不需要指定数据库名字 <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> </plugin> </plugins>

11.缓存

缓存:

一级缓存SqlSession 的缓存 ------>自动开启

二级缓存:

做到从不同的缓存(两个SqlSession)中共享数据

SqlSessionFactory 的缓存 --->需要手动开启

映射配置文件中配置

<mapper namespace="接口路径"> <cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/> </mapper>

说明:

eviction: 二级缓存中,缓存的对象从缓存中移除的策略,回收策略为先进先出

flflushInterval: 刷新缓存的事件间隔,单位:毫秒

size: 缓存对象的个数

readOnly: 是否是只读的

测试代码:

12 注解开发mybatis

mybatis中可以将sql语句通过注解的方式定义在java中,此时配置文件扫描该注解的位置即可,(不用再指定mapper了) <mapper class="com.dao.StudentDao"></mapper>

12.1

@Insert("insert into student(username,password,birthday) values(#{user_name},#{password},# {birthday})") @Options(useGeneratedKeys = true,keyProperty = "userid") public int insertstu(Student student);

12.2

@Delete("delete from student where userid=#{userid}") public int deleteuser(int userid);

12.3

@Update("update student set username=#{user_name},sex=#{sex} where userid=#{userid}") public int updateuser(Student stu);

12.4

@Select("select * from student") /* @Results({ @Result(id = true, property = "id", column = "test_id") @Result(column = "username",property = "user_name") })*/

注意:多个@Result的时候两侧加大括号{}

12.5

@SelectProvider(type = 自定义sql所在的类.class, method = "sql定义的方法")

实例:@SelectProvider(type = SqlTemp.class,method ="getall44")

@InsertProvider(type = SqlTemp.class,method = "insert")

@DeleteProvider(type = SqlTemp.class,method = "delete")

@UpdateProvider(type = SqlTemp.class,method = "update")

12.6

@ResultType(Student.class) public List<Student> findall44();

12.7

@ResultMap("mapper文件中的id名即可") public List<Student> findall33();

注意:(1)mapper文件中namespace的值要写当前接口的全路径

(2)配置文件中加载接口和mapper.xml二选一

实例代码:

接口:

@Select("select * from student s ,grade g where s.gid=g.cid") @ResultMap("com.yhp.dao.StudentDao2.a1") public List<Student> findstu_grade(); mapper文件: 这里namespace一定是接口的完整路径 <mapper namespace="com.yhp.dao.StudentDao2"> <resultMap id="a1" type="student"> <id property="sid" column="sid"></id> <result property="sname" column="sname"></result> <association property="grade" javaType="grade"> <id property="cid" column="cid"></id> <result property="cname" column="cname"></result> </association> </resultMap> </mapper>

配置文件:只需要扫描mapper文件,不需要扫描接口

<mappers> <mapper resource="resultMapper.xml"></mapper> </mappers>

12.8

绑定参数:

@Insert("insert into student(sname1,sex) values(#{sname},#{sex})") @Options(useGeneratedKeys = true,keyProperty = "sid") public int insertStu(@Param("sname") String name, @Param("sex")String usersex);

注意:在自定义sql的方法方法中只能使用#{}

12.9

@Options(useCache = true, flushCache = Options.FlushCachePolicy.FALSE, //表示查询时不刷新缓 timeout = 10000) //表示查询结果缓存10000秒 注意:需要和@CacheNamespace一起使用,并且对象需要实现序列化接口

12.10

@CacheNamespace(size = 512) : 定义在该命名空间内允许使用内置缓存,最大值为512个对象引用,读写默认 是开启的, 缓存内省刷新时间为默认3600000毫秒,用来修饰接口

12.11

动态sql: @Select(" <script>select * from student where 1=1 " + " <if test=\"name!=null and name!=''\">" + " and username like '%${name}%'" + " </if>" + " <if test=\"'pass!=null'\">" + " and password like '%${pass}%'"+ " </if></script>")

13.lombok插件

在idea工具中添加lombok插件:

安装:

<dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <version>1.18.2</version> <scope>provided</scope> </dependency>

lombok的使用

@Data 注解在类上;提供类所有属性的 getter 和 setter方法,此外还提供了equals、canEqual、hashCode、

toString 方法

@Setter :注解在属性上;为属性提供 setting 方法

@Getter :注解在属性上;为属性提供 getting 方法

@Log4j :注解在类上;为类提供一个 属性名为log 的 log4j 日志对象

@NoArgsConstructor :注解在类上;为类提供一个无参的构造方法

@AllArgsConstructor :注解在类上;为类提供一个全参的构造方法

@Cleanup : 可以关闭流

@Builder : 被注解的类加个构造者模式

@Synchronized : 加个同步锁

@SneakyThrows : 等同于try/catch 捕获异常

@NonNull : 如果给参数加个这个注解 参数为null会抛出空指针异常

@Value : 注解和@Data类似,区别在于它会把所有成员变量默认定义为private fifinal修饰,并且不会生成set方法。

@ToString 重写toString()方法

14.Mybatis自动化

作用:反向生成实体类,接口,mapper.xml

添加依赖包:

<dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.5</version> </dependency>

加载插件:

<build> <plugins> <plugin> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-maven-plugin</artifactId> <version>1.3.5</version> <configuration> <!--配置文件的路径--> <configurationFile>src/main/resources/generatorConfig.xml</configurationFile> <overwrite>true</overwrite> </configuration> <dependencies> <dependency> <groupId>org.mybatis.generator</groupId> <artifactId>mybatis-generator-core</artifactId> <version>1.3.5</version> </dependency> </dependencies> </plugin> </plugins> </build>

修改配置文件:

<?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> <!--数据库驱动jar --> <classPathEntry location="/Volumes/mydata/Maven/apache-maven-3.6.3/my_repository/mysql/mysql-connector-java/5.1.38/mysql-connector-java-5.1.38.jar" /> <context id="MyBatis" targetRuntime="MyBatis3"><!--去除注释 --> <commentGenerator> <property name="suppressAllComments" value="true" /> </commentGenerator> <!--数据库连接 --> <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/test" userId="root" password="root"> </jdbcConnection> <!--生成实体类 指定包名 以及生成的地址 (可以自定义地址,但是路径不存在不会自动创建 使用Maven生成在target目录下,会自动创建) --> <javaModelGenerator targetPackage="com.zx.bean" targetProject="/Volumes/mydata/IDEA/SSM/src/main/java"> <property name="trimStrings" value="true" /> </javaModelGenerator> <!--生成SQLmapper文件 --> <sqlMapGenerator targetPackage="mapper" targetProject="/Volumes/mydata/IDEA/SSM/src/main/resources"> </sqlMapGenerator> <!--生成Dao文件,生成接口 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.zx.dao" targetProject="/Volumes/mydata/IDEA/SSM/src/main/java"> </javaClientGenerator> <table tableName="bills" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="billtype" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> <table tableName="subject" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"> </table> </context> </generatorConfiguration>

运行:maven Project选项卡->plugins->找到mybatis-generator-core,双击运行就会自动生成

注意:运行一次即可,如果运行过程中,未完全成功。则将原来生成的代码删除后,再次运行。

拜了个拜 累 ,点个赞呗么么哒

end

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2020/11/04 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • ~关注我 带你看更多精品技术和面试必备
    • 1.Mybatis介绍
      • 2.搭建Mybatis
        • 3.Mybatis实现CRUD
          • 6.给类起别名<!—给实体类起别名 -->
            • 7.获得新增数据的id
              • 8.log4j显示sql语句
                • 9.Mybatis复杂查询
                  • 10.pageHelper分页
                    • 11.缓存
                      • 12 注解开发mybatis
                        • 13.lombok插件
                        相关产品与服务
                        云数据库 SQL Server
                        腾讯云数据库 SQL Server (TencentDB for SQL Server)是业界最常用的商用数据库之一,对基于 Windows 架构的应用程序具有完美的支持。TencentDB for SQL Server 拥有微软正版授权,可持续为用户提供最新的功能,避免未授权使用软件的风险。具有即开即用、稳定可靠、安全运行、弹性扩缩等特点。
                        领券
                        问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档