SSM框架——MyBatis
Mybatis
1.Mybatis的使用
1.1给项目导入相关依赖
我这里有几个下载好的依赖包提供给大家
<!--导入依赖-->
<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&characterEncoding=utf8&useSSL=false&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的更多相关文章
- SSM框架-MyBatis框架数据库的增删查改操作
话不多说,在User.xml文件中主要写一下操作数据库的sql语句,增,删,查,改是最常见的数据库操作 User.xml文件下:
- Java基于ssm框架的restful应用开发
Java基于ssm框架的restful应用开发 好几年都没写过java的应用了,这里记录下使用java ssm框架.jwt如何进行rest应用开发,文中会涉及到全局异常拦截处理.jwt校验.token ...
- 【SSM框架】Spring + Springmvc + Mybatis 基本框架搭建集成教程
本文将讲解SSM框架的基本搭建集成,并有一个简单demo案例 说明:1.本文暂未使用maven集成,jar包需要手动导入. 2.本文为基础教程,大神切勿见笑. 3.如果对您学习有帮助,欢迎各种转载,注 ...
- SSM框架-----------SpringMVC+Spring+Mybatis框架整合详细教程
1.基本概念 1.1.Spring Spring是一个开源框架,Spring是于2003 年兴起的一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One ...
- [JSP]Maven+SSM框架(Spring+SpringMVC+MyBatis) - Hello World
来源:http://blog.csdn.net/zhshulin/article/details/37956105?utm_source=tuicool&utm_medium=referral ...
- SSM框架Web程序的流程(Spring SpringMVC Mybatis)
SSM框架的Web程序主要用到了三个技术: Spring:用到了注解和自动装配,就是Spring的两个精髓IOC(反向控制)和 AOP(面向切面编程). SpringMVC:用到了MVC模型,将逻辑代 ...
- SSM框架搭建web服务器实现登录功能(Spring+SpringMVC+Mybatis)
初学java EE,虽然知道使用框架会使开发更加便捷高效,但是对于初学者来说,感到使用框架比较迷惑,尤其是各种jar包的引用.各种框架的配置.注解的使用等等. 最好的学习方法就是实践,于是下载了一个现 ...
- 整合最优雅SSM框架:SpringMVC + Spring + MyBatis
我们看招聘信息的时候,经常会看到这一点,需要具备SSH框架的技能:而且在大部分教学课堂中,也会把SSH作为最核心的教学内容. 但是,我们在实际应用中发现,SpringMVC可以完全替代Struts,配 ...
- 最优雅SSM框架:SpringMVC + Spring + MyBatis
在写代码之前我们先了解一下这三个框架分别是干什么的? 相信大以前也看过不少这些概念,我这就用大白话来讲,如果之前有了解过可以跳过这一大段,直接看代码! SpringMVC:它用于web层,相当于con ...
随机推荐
- <jsp:useBean>动作的使用
jsp:useBean动作的使用 jsp:useBean动作用于在指定的范围内寻找指定名称的JavaBean对象,如果找到,则返回该对象的引用可以操作里边的属性.如果没有找到则重新实例化一个对象.并且 ...
- 解决在JS中阻止定时器“重复”开启问题、Vue中定时器的使用
1.问题描述 在一些需求开发中.需要设定软件提供服务的时间段(营业时间).这时可以选择定时器来实现.可以选择让定时器每隔一段时间检测当前时间是否在服务时间.到达服务时间.进入服务状态.未到服务时间.进 ...
- 鼠标悬浮上去显示小手CSS
鼠标悬浮上去显示小手CSS只需要添加一句css代码即可 cursor:pointer;
- golang中的几种并发模式
0.1.索引 https://blog.waterflow.link/articles/1663551951058 1.for- select模式 这种模式通常用在从多个通道读取数据 package ...
- sql语法巧用之not取反
数据库的重要性和通用性都不用说了,什么sql的通用性,sql优化之类的也不必说了,咱们今天来聊聊另一个有意思的话题:如何取一个筛选的反面案例. 1. 举几个正反案例的例子 为了让大家理解我们的假设场景 ...
- C语言/python实现定时关机
1.python def shutdown(): print('(1)定时关机\n(2)取消定时关机\n(3)立即关机\n(4)关机重启') b = eval(input('请选择:\n')) if( ...
- ansible使用临时命令通过模块来执行任务
使用临时命令通过模块来执行任务 一.查看系统上安装的所有模块 ansible-doc -l 查看ping模块帮助文档 ansible-doc ping 1.ansible模块 文件模块: copy:将 ...
- python dir函数解析
dir() 函数 不带参数,直接执行是返回当前环境中对象的名称列表.指定对象的名称作为参数执行,返回指定对象当中的属性(包括函数名,类名,变量名等) 下面我们具体找几个例子测试一下 dir() ...
- C#中进行数值的比较
Equals的使用 str1.Equals(str2,StringComparison.OrdinalIgnoreCase); ----比较str1和str2 StringComp ...
- python进阶(26)collections标准库
前言 这个模块实现了特定目标的容器,以提供Python标准内建容器dict ,list ,set , 和tuple 的替代选择. 这个模块提供了以下几个函数 函数 作用 namedtuple() 创建 ...