Mybatis 是一个关系映射持久层框架
IDEA目录
pom.xml配置
<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.2</version>
</dependency>
MyBatis-config.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>
<typeAliases>
<typeAlias type="com.gyl.pojo.User" alias="user"></typeAlias>
<!--扫描一个包下面的-->
<package name="com.gyl.pojo"/>
</typeAliases>
<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>
<mapper resource="com/gyl/dao/UserMapper.xml"/>
</mappers>
</configuration>
MyBatisConfig.class配置
package com.gyl.utils;
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 MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try {
//获取SqlSessionFactory对象
String resources = "mybatis.xml";
InputStream inputStream = Resources.getResourceAsStream(resources);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
实体类啊啥的免了吧,说重点:
查询
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> allById = mapper.findAllById(1);
for (User user : allById) {
System.out.println(user);
}
sqlSession.close();
增删改
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int count = mapper.updateUserById("999999",3);
if(count>0){
sqlSession.commit();
}
sqlSession.close();
查询不用提交事务,因为用的JDBC连接,所以涉及到事务,对于增删改来说需要提交事务,错误需要回滚。
模糊查询
1:java代码中拼接 %参数%
2:在mapper.xml中配置
<select id="findUserLike" resultType="user">
select * from user where name like "%"#{value}"%"
</select>
3:不推荐用${value},会引起SQL注入等不安全。而#{value}是预编译的是安全的。
启动错误
1:org.apache.ibatis.binding.BindingException: Type interface com.gyl.dao.UserMapper is not known to the MapperRegistry.
没有配置关系映射器
<mappers>
<mapper resource="com/gyl/dao/UserMapper.xml"/>
</mappers>
2:The error may exist in com/gyl/dao/UserMapper.xml
把mapper.xml放到java路径下没有扫描到,需要在pom.xml里配置bulid
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
3:注意连接池的url的编码 utf-8 要和mapper.xml的第一行的编码一致
4:sql报错找不到参数的时候,要注意看传参,如果是对象看对象名是否一致,如果是单个参数,需要在接口的参数前加下面这个就不会有错啦。
生命周期
简单来说就是SqlSessionFactoryBuild,SqlSessionFactory,SqlSession,用完SqlSession.close
1:SqlSessionFactoryBuild在SqlSessionFactory创建就结束了
2:SqlSessionFactory可以理解为连接池
3:SqlSession可以理解为一个个连接,他是线程不安全的,所以用完要及时关掉,不然会造成资源浪费。
别名
三种方式
1:给单个实体类取别名
mybatis-config.xml
<typeAliases>
<typeAlias type="com.gyl.pojo.User" alias="user"></typeAlias>
</typeAliases>
mapper.xml
<select id="findAllById" resultType="user">
select * from user where id = #{id}
</select>
2:给整个包取别名,mapper.xml下的别名是包下面的类的首字母小写
<typeAliases>
<!--扫描一个包下面的-->
<package name="com.gyl.pojo"/>
</typeAliases>
3:给实体类加注解取别名
这个比较牛批了,
4:resultMap,paramterType等的类型的别名
如果是基本类型 : byte 别名在字母前加下划线 _byte
如果是引用类型 :java.util.Map 这种的,直接首字母小写 Map 的别名为:map
LOG4J配置
maven
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.properties
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.org.apache=INFO
log4j.appender.file.File=./log/gyl.log
mybatis-config-xml
<properties resource="log4j.properties"/>
<settings>
<setting name="logImpl" value="LOG4J"/>
</settings>
执行输出会在控制台打出log,方便调试
分页查询
1:原生的SQL查询,代入对应的startIndex和pageSize
//接口
//分页
List<User> getUserByLimit(Map<String,Integer> map);
//Mapper.xml
<select id="getUserByLimit" parameterType="map" resultType="users">
select * from user limit #{startIndex},#{pageSize}
</select>
调用
@Test
public void getUserLimit(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
HashMap<String, Integer> map = new HashMap<>();
//起始下标从0开始
//每页显示多少个
map.put("startIndex",0);
map.put("pageSize",2);
List<User> allBylimit = mapper.getUserByLimit(map);
for (User user : allBylimit) {
System.out.println(user);
}
sqlSession.close();
}
2: 使用RowBounds方法
接口
List<User> getUserByLimitByRowBounds();
mapper.xml
<select id="getUserByLimitByRowBounds" resultType="users">
select * from user
</select>
//通过java代码形式
@Test
public void getUserLimitByRowBounds(){
//不再使用分页实现分页
SqlSession sqlSession = MyBatisUtils.getSqlSession();
RowBounds rowBounds = new RowBounds(1, 2);
List<User> o = sqlSession.selectList("com.gyl.dao.UserMapper.getUserByLimitByRowBounds", null, rowBounds);
for (User user : o) {
System.out.println(user);
}
sqlSession.close();
}
3:第三方插件pagehelper
导包
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.2</version>
</dependency>
mybatis-config.xml下编写配置文件,注意位置
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<!--reasonable:分页合理化参数,默认值为false,直接根据参数进行查询。
当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。-->
<!--<property name="reasonable" value="true"/>-->
</plugin>
</plugins>
然后写接口和mapper
<select id="findAll" resultType="user">
select * from user
</select>
然后写调用的service
PageHelper.startPage(1, 2, true);
//设置分页条件,Parameters:pageNum 页码pageSize 每页显示数量count 是否进行count查询
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
PageHelper.startPage(1, 2, true);
List<User> users = mapper.findAll();
for (User user : users) {
System.out.println(user);
}
运行结果:
注解实现
@Select("select * from user")
public List<User> getAlluser();
@Test
public void getAllUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
annoUser mapper = sqlSession.getMapper(annoUser.class);
List<User> allBylimit = mapper.getAlluser();
for (User user : allBylimit) {
System.out.println(user);
}
sqlSession.close();
}
还有增删改,sql写到接口上面。