Mybatis

1.Mybatis的使用

1.1给项目导入相关依赖

我这里有几个下载好的依赖包提供给大家

点我下载——junit4.13.2

点我下载——maven3.8.1

点我下载——mybatis3.5.7

<!--导入依赖-->
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency> </dependencies>
1.2构建SqlSessionFactory

mybatis文档是这么说的,"每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例。 "

用xml文件配置SqlSessionFactory ,在resouses工具类下,创建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">
<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/jdbcstudy?useUnicode=true&amp;characterEncoding=utf8&amp;useSSL=false&amp;severTimezone=gmt%2b8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
1.3从SqlSessionFactory中获取SqlSession

SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。可以通过 SqlSession 实例来直接执行已映射的 SQL 语句

编写一个工具类去获取sqlSession对象,以后调用即可

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.IOException;
import java.io.InputStream; public class MyBatisUtil {
private static SqlSessionFactory sessionFactory;
static {
//获取获取SqlSesson工厂对象
String resouse = "mybatis-config.xml";
try {
InputStream inputStream = Resources.getResourceAsStream(resouse);
sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//返回sqlsession对象
public static SqlSession getSqlSession(){
return sessionFactory.openSession();
}
}
1.4编写接口和实现类

一个与数据库表对应的资源类(提供gette、rsetter、构造方法、toString)

package pojo;
public class User {
private int id;
private String name;
public User() {}
public User(int id, String name) {this.id = id;this.name = name;}
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;}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
'}';
}
}

一个有获得结果集的抽象方法的接口

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

一个用来映射Sql语句的Mapper文件(提供Session与数据库的对接)

<?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="dao.UserDao">
<!--对应的语句写对应的标签,id为接口的方法,resultType为结果集-->
<select id="getUserList" resultType="pojo.User">
select * from jdbcstudy.student;
</select>
</mapper>
1.5用junit测试
package dao;
import Utils.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import pojo.User;
import java.util.List; public class UserTest {
@org.junit.Test//之前导入了junit的依赖
public void test(){
//通过工具类获取Sqlsession对象
SqlSession session = MyBatisUtil.getSqlSession();
//用SqlSession的getMappper方法获取实例类
UserDao userDao = session.getMapper(UserDao.class);
//调用实例类方法
List<User> list = userDao.getUserList();
for (User user : list) {
System.out.println(user);
}
session.closed();
}
}
1.6 可能会遇到的问题

1.mapper文件未注册

org.apache.ibatis.binding.BindingException: Type interface dao.UserDao is not known to the MapperRegistry.

解决办法:

在配置SqlSessionFactory的xml文件中加入mapper注册

<mappers>
<mapper resource="dao/UserMapper.xml"/>
</mappers>

2.maven资源输出过滤问题

会报出未初始化和io未找到mapper.xml文件等错误

java.lang.ExceptionInInitializerError

Could not find resource dao/UserMapper.xml

解决办法:在项目配置文件里加入下列代码

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>

输出结果:格式不正确可能是没有重写toString方法。楼主我就栽在了这坑里

2.MyBatis操作数据库

mapper标签属性:

namespace:命名空间和接口保持一致

语句标签属性:

id:namespace对应接口中的方法

resultType:返回值类型

需要新的语句时,只需要在接口里新加入抽象方法、以及向mapper映射文件中加入sql语句标签即可

2.1数据库查询(不用事务提交)

eg:根据id查询用户

接口抽象函数:

User getUserById(int id);//根据id查询用户

mapper映射标签:

<select id="getUserById" resultType="pojo.User">
select * from jdbcstudy.student where id= #{id};
</select>

Test测试:

@org.junit.Test
public void SelectById(){
SqlSession session = MyBatisUtil.getSqlSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
User user= userMapper.getUserById(0);
System.out.println(user);
}
2.2数据库增删改(需要提交事务)
@org.junit.Test
public void addUser(){
SqlSession session = MyBatisUtil.getSqlSession();
UserMapper userMapper = session.getMapper(UserMapper.class);
int add = userMapper.addUser(new User(2,"赵中波"));
if(add>0) System.out.println("修改成功");
//事务提交
session.commit();
session.close();
}
2.3Map传参

使用map传参要比基本类型传参和对象传参更加灵活,可以使用key值自定义属性名,在用value存储值,eg:

<insert id="addUser" parameterType="map">
insert into jdbcstudy.student (id,name) values (#{idkey},#{namekey});
</insert>
2.4模糊查询

一般数据库里模糊查询是使用%,比如查询李姓用户 like '李%'

myBatis里可以用字符串拼接,或是在传参时传入参数为("李%"),但这样就显得很low或是接口设计不良好,一般是在sql语句映射文件里用字符串拼接

<select id="getUserById" parameterType="int" resultType="pojo.User">
select * from jdbcstudy.student where id= #{id}"%";
</select>
或者是
<select id="getUserById" parameterType="int" resultType="pojo.User">
select * from jdbcstudy.student where id= concat(#{id},"%");
</select>

3.MaBatis配置解析

MyBatis 的配置文件包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文档的顶层结构如下(配置的时候也要按这个顺序来):

3.1环境配置

1.事务管理器(transactionManager)

类型:jdbc(默认)、managed

2.数据源(datasourse)

类型:Pooled(默认,连接池)、Unpooled、Jdni(正常连接)

3.属性(properties)

属性可以在外部进行配置.properties文件,并可以进行动态替换。也可以在 properties 元素的子元素中设置。

优先级:类型传参>外部文件>子元素设置

4.别名(typeAliases)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写,这样配置时,别名可以在任何地方替代原类

<typeAliases>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
</typeAliases>

比较实用的是用别名扫描一个包,比如原先我定位到一个累要用com.#.@.%.User,加入包扫描后就可以直接用user(首字母小写)定位该类

<typeAliases>
<package name="com.#.@.%"/>
</typeAliases>

5.映射器(mappers)

每个mapper映射器在使用前都需要注册

<mappers>
<mapper resource="dao/UserMapper.xml"/>使用相对路径
<mapper url="D://UserMapper.xml"/>使用绝对路径
<mapper class="dao.UserMapper"/>使用类导入方式(mapper文件和该接口类同包且同名)
<package name="dao"/>使用包导入方式(接口类和mapper文件同名)
</mappers>

4.结果集映射

使用返回实体类类型的方式,如果类属性和数据库列名匹配不上(不同名)的话,就会出现查询出null的情况,为了解决这个问题,可以使用结果集映射

<resultMap id="name" type="class">
<result column="数据库列名" property="类属性名"/>
<!--如果属性是对象,一般需要通过某个列名再去查询到该对象(多对一查询)-->
<association column="映射对象的列名" property="对象属性名" javaType="对象类型" select="连接查询的id">
<result column="数据库列名" property="类属性名"/><!--对象字段里也可以进行结果映射-->
</association>
<!--如果属性是集合,一般需要通过某个列名再去查询到该集合(一对多查询)-->
<collection property="对象属性名" column="映射集合的列名" javaType="集合类型" ofType="集合泛型类型" select="连接查询的id">
<result column="数据库列名" property="类属性名"/><!--集合字段里也可以进行结果映射-->
</collection>
</resultMap>

使用方法(resultMap="结果集映射的id"):

<select id="getUserList" resultMap="name">
select * from jdbcstudy.student;
</select>

5.日志工厂

logImpl

指定 MyBatis 所用日志的具体实现,未指定时将自动查找。

SLF4J | LOG4J | LOG4J2 | JDK_LOGGING

COMMONS_LOGGING | STDOUT_LOGGING

NO_LOGGING

设置方式(设置标准日志STDOUT_LOGGING)

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

日志打印

5.1 LOG4J日志工厂

导入log4j

<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>

配置log4j:log4j.properties(下面是一个简单的配置)

# set log levels
log4j.rootLogger=DEBUG,console,file
# 输出到控制台
log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.console.Threshold=DEBUG
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=【%c】-%m%n
# 文件输出的相关设置
log4j.appender.file=org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/leye.log
log4j.appender.file.MaxFileSize=10mb
log4j.appender.file.Threshold=DEBUG
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=【%p】【%d{yy-MM-dd}】【%c】%m%n
# 日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG

使用:Logger logger = Logger.getLogger(class);

6.分页

limit分页,使用了map之后可以传多个参数

<select id="getUserList" parameterType="map" resultType="pojo.User">
select * from jdbcstudy.student limit #{startpage},#{num};
</select>

7.使用注解开发

7.1通过注解注入sql语句

将sql语句直接注解到接口抽象方法里,比如一个简单的查询语句

@Select("select * from student")
List<User> getUserList();//无参查询

但是,注解注入的方式只适用于少数sql语句比较简单的情况,值得一提的是,在对于多个基本类型参数sql方法,必须要在参数前再加一个指名注解

User getUserBy(@Param("id") int id ,@Param("name") String name);
7.1注解解决列名和属性名不匹配问题

之前是用map解决的,但对于只有少数参数的sql语句,用map就有点大材小用,这里用注解更加方便,但只针对于用注解注入sql语句的情况

@Select("select * from student")
@Results(id = "userMap",value = {
@Result(column = "id" ,property = "anInt")
})
List<User> getUserList();//无参查询

设置id是为了方便其他的结果映射注解去调用,如

@Select("select * from student where id=#{id}")
@ResultMap(value = "userMap")
User getUserById(int id);//根据id查询用户

8.动态SQL

8.1 IF标签
<select id="" parameterType="" resultType="">
select * from student where 1=1<!--方便拼接字符串-->
<if test="表达式">
and sql语句<!--表达式成立的话,拼接该字符串-->
</if>
</select>
8.2 where标签

一般为了在if等标签里拼接字符串,前面都得模拟一个true的where语句

<select id="" ..>
select * from student where 1=1
<if>...</if>
</select>

这样虽然可行,但却降低了耦合性

jsp标签提供了一个where标签来解决这种问题

注意:在第二条语句之后都要加上and

<select id="" ..>
select * from student
<where>
<if test="">...</if>
<if test="">and...</if>
</where>
</select>
8.3choose——when语句

类似于java的swicth

<choose>
<when test="表达式">
and 拼接sql
</when>
...
<otherwise>
..
</otherwise>
</choose>
8.4 set语句

set语句可以自动联系sql语句中的 ','逗号,发现多余的逗号会帮你去掉,和where标签的and比较像,多用于像修改、插入这种含,的sql语句

<set>
<if test="">...,</if>
<if test="">...,</if>
<if test="">...,</if>
</ set>
8.5 trim标签定制语句覆盖

像where、set标签都可以通过trim标签去定制

<trim prefix="where" prefixOverrides="AND|OR">//自动覆盖and、or前缀
//定制where语句
</trim> <trim prefix="set" suffixOverrides=",">//自动覆盖,后缀
//定制set语句
</trim>
8.6 Sql片段

可以将某些sql的公共部分提取出来,以便复用

//sql片段定义
<sql id="sqlName">
...
</sql>
//sql片段使用
<include refid="sqlName"></include>
8.7 forEach标签

可以遍历取出list里的元素拼接sql语句

<foreach collection="listName" item="elemName" open="" close="" separator="">
...
</foreach>
//其中collection是要从中取出元素的集合,item是每个元素的引用名称,
open、close分别是拼接sql的开始和结束,sepqarator是拼接sql的间隔符
比如要拼接一个(1,2,3,4)的sql
<foreach collection="listName" item="id" open="(" close=")" separator=",">
#{id}
</foreach>

9.MyBatis缓存

MyBatis默认定义了二级缓存:一级缓存和二级缓存

<setting name="cacheEnabled" value="true">//开启缓存

一级缓存:SqlSession级别的缓存,也就是本地缓存,增删改查和不同查询等会自动清除缓存

二级缓存:基于namespace的缓存,需要手动开启配置,它可以将对话框关闭后存在一级缓存中的数据存到mapper对应的二级缓存中

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" >
//创建了一个每60s刷新的FIFO缓存,最多可以存储512个引用,而且返回只读对象

SSM框架——MyBatis的更多相关文章

  1. SSM框架-MyBatis框架数据库的增删查改操作

    话不多说,在User.xml文件中主要写一下操作数据库的sql语句,增,删,查,改是最常见的数据库操作 User.xml文件下:

  2. Java基于ssm框架的restful应用开发

    Java基于ssm框架的restful应用开发 好几年都没写过java的应用了,这里记录下使用java ssm框架.jwt如何进行rest应用开发,文中会涉及到全局异常拦截处理.jwt校验.token ...

  3. 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程

    本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...

  4. SSM框架-----------SpringMVC+Spring+Mybatis框架整合详细教程

    1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One  ...

  5. [JSP]Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World

    来源:http://blog.csdn.net/zhshulin/article/details/37956105?utm_source=tuicool&utm_medium=referral ...

  6. SSM框架Web程序的流程(Spring SpringMVC Mybatis)

    SSM框架的Web程序主要用到了三个技术: Spring:用到了注解和自动装配,就是Spring的两个精髓IOC(反向控制)和 AOP(面向切面编程). SpringMVC:用到了MVC模型,将逻辑代 ...

  7. SSM框架搭建web服务器实现登录功能(Spring+SpringMVC+Mybatis)

    初学java EE,虽然知道使用框架会使开发更加便捷高效,但是对于初学者来说,感到使用框架比较迷惑,尤其是各种jar包的引用.各种框架的配置.注解的使用等等. 最好的学习方法就是实践,于是下载了一个现 ...

  8. 整合最优雅SSM框架:SpringMVC + Spring + MyBatis

    我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...

  9. 最优雅SSM框架:SpringMVC + Spring + MyBatis

    在写代码之前我们先了解一下这三个框架分别是干什么的? 相信大以前也看过不少这些概念,我这就用大白话来讲,如果之前有了解过可以跳过这一大段,直接看代码! SpringMVC:它用于web层,相当于con ...

随机推荐

  1. <jsp:useBean>动作的使用

    jsp:useBean动作的使用 jsp:useBean动作用于在指定的范围内寻找指定名称的JavaBean对象,如果找到,则返回该对象的引用可以操作里边的属性.如果没有找到则重新实例化一个对象.并且 ...

  2. 解决在JS中阻止定时器“重复”开启问题、Vue中定时器的使用

    1.问题描述 在一些需求开发中.需要设定软件提供服务的时间段(营业时间).这时可以选择定时器来实现.可以选择让定时器每隔一段时间检测当前时间是否在服务时间.到达服务时间.进入服务状态.未到服务时间.进 ...

  3. 鼠标悬浮上去显示小手CSS

    鼠标悬浮上去显示小手CSS只需要添加一句css代码即可 cursor:pointer;

  4. golang中的几种并发模式

    0.1.索引 https://blog.waterflow.link/articles/1663551951058 1.for- select模式 这种模式通常用在从多个通道读取数据 package ...

  5. sql语法巧用之not取反

    数据库的重要性和通用性都不用说了,什么sql的通用性,sql优化之类的也不必说了,咱们今天来聊聊另一个有意思的话题:如何取一个筛选的反面案例. 1. 举几个正反案例的例子 为了让大家理解我们的假设场景 ...

  6. C语言/python实现定时关机

    1.python def shutdown(): print('(1)定时关机\n(2)取消定时关机\n(3)立即关机\n(4)关机重启') b = eval(input('请选择:\n')) if( ...

  7. ansible使用临时命令通过模块来执行任务

    使用临时命令通过模块来执行任务 一.查看系统上安装的所有模块 ansible-doc -l 查看ping模块帮助文档 ansible-doc ping 1.ansible模块 文件模块: copy:将 ...

  8. python dir函数解析

    dir() 函数  不带参数,直接执行是返回当前环境中对象的名称列表.指定对象的名称作为参数执行,返回指定对象当中的属性(包括函数名,类名,变量名等)   下面我们具体找几个例子测试一下  dir() ...

  9. C#中进行数值的比较

    Equals的使用 str1.Equals(str2,StringComparison.OrdinalIgnoreCase);     ----比较str1和str2       StringComp ...

  10. python进阶(26)collections标准库

    前言 这个模块实现了特定目标的容器,以提供Python标准内建容器dict ,list ,set , 和tuple 的替代选择. 这个模块提供了以下几个函数 函数 作用 namedtuple() 创建 ...