Mybatis
1.Mybatis简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
官网文档 https://mybatis.org/mybatis-3/zh/index.html
2.搭建环境
- Maven导包
<dependencies>
<!--Mybatis导入-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.4</version>
</dependency>
<!--MySQL驱动 JDBC-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<!--Junit测试-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
</dependencies>
- 额外可以添加一个数据库属性文件db.properties
#MySQL配置信息
mysql.driver = com.mysql.cj.jdbc.Driver
mysql.url = jdbc:mysql://localhost:3306/my_jdbc?useSSL=true&useUnicode=true&characterEncoding=UTF-8
mysql.username = root
mysql.password = PQS2017214206
- 创建Mybatis核心配置文件
<?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">
<!-- Mybatis核心配置文件 -->
<configuration>
<!-- 导入数据库配置属性 -->
<properties resource="db.properties"></properties>
<environments default="development">
<!-- 环境 -->
<environment id="development">
<!-- 事务管理器 -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
<!-- 注册mapper -->
<mappers>
<mapper resource="StudentMapper.xml"/>
</mappers>
</configuration>
- 创建Mybatis工具类
public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
String resource = "mybatis-config.xml";//配置文件路径
InputStream inputStream= Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//该工具类就是为了得到SqlSession
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
- 准备工作完成,开始编写代码
3.运行简单例子
1、编写实体类
package com.gu_ppy.pojo;
/**
* 学生实体类
* <br>
* @author gu-ppy
* @Package com.gu_ppy.pojo
* @Description: TODO
* @date 2020/4/815:52
*/
public class Student {
private String id;
private String name;
private String sex;
private int phone ;
private String address;
private String password;
public Student() {
}
public void setId(String id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setSex(String sex) {
this.sex = sex;
}
public void setPhone(int phone) {
this.phone = phone;
}
public void setAddress(String address) {
this.address = address;
}
public void setPassword(String password) {
this.password = password;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getSex() {
return sex;
}
public int getPhone() {
return phone;
}
public String getAddress() {
return address;
}
public String getPassword() {
return password;
}
@Override
public String toString() {
return "Student{" +
"id='" + id + '\'' +
", name='" + name + '\'' +
", sex='" + sex + '\'' +
", phone=" + phone +
", address='" + address + '\'' +
", password='" + password + '\'' +
'}';
}
}
2、编写dao层接口
package com.gu_ppy.mapper;
import com.gu_ppy.pojo.Student;
import java.util.List;
/**
* student的数据库操作接口
* <br>
* @author gu-ppy
* @Package com.gu_ppy.mapper
* @Description: TODO
* @date 2020/4/815:59
*/
public interface StudentMapper {
public List<Student> getStudents();
}
3、创建StudentMapper的配置文件
namespace:Dao/Mapper接口的全限定类名
<?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=绑定一个Mapper接口-->
<mapper namespace="com.gu_ppy.mapper.StudentMapper">
<!--id=执行方法 resultType=返回类型-->
<select id="getStudents" resultType="com.gu_ppy.pojo.Student">
select * from my_jdbc.student_info
</select>
</mapper>
4、资源导出失败解决方案
- idea有时会资源导出失败,因此在pom.xml添加构建(bulid)信息
<!--true改为false-->
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/test/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
5、运行测试
- 通过junit来测试我们的StudentMapper
package com.gu_ppy.mapper;
import com.gu_ppy.pojo.Student;
import com.gu_ppy.util.MybatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
/**
* 测试StudentMapper接口
* <br>
*
* @author gu-ppy
* @Package com.gu_ppy.mapper
* @Description: TODO
* @date 2020/4/816:07
*/
public class StudentMapperTest {
@Test
public void testMapper() {
//官网建议将语句块放入try-catch-finally中,此处未使用
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.getStudents();
for (int i = 0; i < students.size(); i++) {
System.out.println(students.get(i));
}
sqlSession.close();
}
}
6、架构总览图
4.增删改查CRUD
下面内容都属于使用xml配置Mapper,注解配置在后续模块述说。
1、Mapper配置文件中常见属性
-
namespace:其是mapper配置文件绑定到Mapper的接口,Mapper接口实质上是一个接口类
-
id:是用于指定Mapper的方法
-
resultType:指定返回类型
-
parameterType:指定传入参数的类型
-
#{}:在SQL语句中常用其来代入参数,如: select * from student where id = #{id} 其中 id 是与Mapper接口类中的方法传入的参数相同
2、select
要完成一个完整的查询功能需要有三部分,Mapper接口设置方法、Mapper.xml配置SQL语句、编写测试运行代码。
- Mapper接口设置
//查询全部学生
List<Student> getStudents();
//根据id查询学生
Student getStudent(String id);
- Mapper.xml配置
<select id="getStudents" resultType="com.gu_ppy.pojo.Student">
select * from my_jdbc.student_info
</select>
<!--多参数,将参数组成对象传给Mapper.xml-->
<select id="getStudent" resultType="com.gu_ppy.pojo.Student" parameterType="String">
select * from my_jdbc.student_info where id like #{id}
</select>
- 测试运行的代码,需要依赖junit
@Test
public void getStudents() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = studentMapper.getStudents();
for (int i = 0; i < students.size(); i++) {
System.out.println(students.get(i));
}
sqlSession.close();
}
@Test
public void getStudent(){
SqlSession session = MybatisUtil.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = mapper.getStudent("0005");
System.out.println(student);
}
3、insert
- Mapper
//插入学生int addStudent(Student student);
- Mapper.xml
<insert id="addStudent" parameterType="com.gu_ppy.pojo.Student">
insert into my_jdbc.student_info(id,name,sex,phone,address,password)
values (#{id},#{name},#{sex},#{phone},#{address},#{password})
</insert>
- 测试
@Test
public void addStudent(){
SqlSession session = MybatisUtil.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student("0005","小刚","男",121211,"地球中国重庆","123456");
int res = mapper.addStudent(student);
if(res>0)
System.out.println("插入成功");
session.commit();//必须加上commit提交事务,否则数据库不改动
session.close();
}
4、update
- Mapper
//更新学生信息
int updateStudent(Student student);
- Mapper.xml
<update id="updateStudent" parameterType="com.gu_ppy.pojo.Student">
update my_jdbc.student_info
set name = #{name},
sex = #{sex},
phone = #{phone},
address = #{address},
password = #{password} where id = #{id}
</update>
- 测试
@Test
public void updateStudent(){
SqlSession session = MybatisUtil.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
Student student = new Student("0006","小刚","女",12121133,"中国重庆","123456");
int res = mapper.updateStudent(student);
if(res>0)
System.out.println("更新成功");
session.commit();//必须加上commit提交事务,否则数据库不改动
session.close();
}
5、delete
- Mapper
//删除学生
int deleteStudent(String id);
- Mapper.xml
<delete id="deleteStudent" parameterType="String">
delete from my_jdbc.student_info where id = #{id}
</delete>
- 测试
@Test
public void deleteStudent(){
SqlSession session = MybatisUtil.getSqlSession();
StudentMapper mapper = session.getMapper(StudentMapper.class);
int res = mapper.deleteStudent("0005");
if(res>0)
System.out.println("删除成功");
session.commit();//必须加上commit提交事务,否则数据库不改动
session.close();
}
6、常用技巧Map
在对象含有多个属性时,可以考虑使用Map类型来作为传参对象。
// 指定数目的更改User属性
int updateUser2(Map<String,Object>map);
<update id="updateUser2" parameterType="map">
update test_info
set name = #{userName},
age = #{userAge} where id = #{userId}
</update>
@org.junit.Test
public void testUseMap(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> map = new HashMap<String, Object>();
map.put("userName","小刚");
map.put("userId","1");
map.put("userAge",15);
mapper.updateUser2(map);
sqlSession.commit();
sqlSession.close();
}
7、模糊查询
- 传参时加入通配符
mapper.selectName("%李%");
- 在SQL拼接中限制通配符
<select id="selectName" parameterType="String">
select * from test_info where name like %${queryName}%
</select>
#{}:是预编译处理,MyBatis在处理#{}时,它会将sql中的#{}替换为?,然后调用PreparedStatement的set方法来赋值,传入字符串后,会在值两边加上单引号,使用占位符的方式提高效率,可以防止sql注入。
${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中,可能引发sql注入。
5.配置
具体的官网文档请查阅官方文档Mybatis配置.
1、properties
这些属性可以在外部进行配置,并可以进行动态替换。你既可以在典型的 Java 属性文件中配置这些属性,也可以在 properties 元素的子元素中设置。例如:
<!--引入外部环境,优先使用外部文件的属性-->
<properties resource="org/mybatis/example/config.properties">
<property name="username" value="dev_user"/>
<property name="password" value="F2Fa3!33TYyg"/>
</properties>
设置好的属性可以在整个配置文件中用来替换需要动态配置的属性值。比如:
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
2、设置setting
这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。 下表描述了设置中各项设置的含义、默认值等。
设置名 | 描述 | 有效值 | 默认值 |
---|---|---|---|
cacheEnabled | 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。 | true | false | true |
lazyLoadingEnabled | 延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。 | true | false | false |
aggressiveLazyLoading | 开启时,任一方法的调用都会加载该对象的所有延迟加载属性。 否则,每个延迟加载属性会按需加载(参考 lazyLoadTriggerMethods )。 | true | false | false(在 3.4.1 及之前的版本中默认为true) |
multipleResultSetsEnabled | 是否允许单个语句返回多结果集(需要数据库驱动支持)。 | true | false | true |
useColumnLabel | 使用列标签代替列名。实际表现依赖于数据库驱动,具体可参考数据库驱动的相关文档,或通过对比测试来观察。 | true | false | true |
useGeneratedKeys | 允许 JDBC 支持自动生成主键,需要数据库驱动支持。如果设置为 true,将强制使用自动生成主键。尽管一些数据库驱动不支持此特性,但仍可正常工作(如 Derby)。 | true | false | False |
autoMappingBehavior | 指定 MyBatis 应如何自动映射列到字段或属性。NONE 表示关闭自动映射;PARTIAL 只会自动映射没有定义嵌套结果映射的字段。FULL 会自动映射任何复杂的结果集(无论是否嵌套)。 | NONE, PARTIAL, FULL | PARTIAL |
autoMappingUnknownColumnBehavior | 指定发现自动映射目标未知列(或未知属性类型)的行为。 NONE : 不做任何反应 WARNING :输出警告日志('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN )FAILING : 映射失败 (抛出 SqlSessionException ) | NONE, WARNING, FAILING | NONE |
defaultExecutorType | 配置默认的执行器。SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(PreparedStatement); BATCH 执行器不仅重用语句还会执行批量更新。 | SIMPLE REUSE BATCH | SIMPLE |
defaultStatementTimeout | 设置超时时间,它决定数据库驱动等待数据库响应的秒数。 | 任意正整数 | 未设置 (null) |
defaultFetchSize | 为驱动的结果集获取数量(fetchSize)设置一个建议值。此参数只可以在查询设置中被覆盖。 | 任意正整数 | 未设置 (null) |
defaultResultSetType | 指定语句默认的滚动策略。(新增于 3.5.2) | FORWARD_ONLY | SCROLL_SENSITIVE | SCROLL_INSENSITIVE | DEFAULT(等同于未设置) | 未设置 (null) |
safeRowBoundsEnabled | 是否允许在嵌套语句中使用分页(RowBounds)。如果允许使用则设置为 false。 | true | false | False |
safeResultHandlerEnabled | 是否允许在嵌套语句中使用结果处理器(ResultHandler)。如果允许使用则设置为 false。 | true | false | True |
mapUnderscoreToCamelCase | 是否开启驼峰命名自动映射,即从经典数据库列名A_COLUMN 映射到经典 Java 属性名 aColumn。 | true | false | False |
localCacheScope | MyBatis 利用本地缓存机制(Local Cache)防止循环引用和加速重复的嵌套查询。默认值为 SESSION,会缓存一个会话中执行的所有查询。若设置值为 STATEMENT,本地缓存将仅用于执行语句,对相同 SqlSession 的不同查询将不会进行缓存。 | SESSION | STATEMENT | SESSION |
jdbcTypeForNull | 当没有为参数指定特定的 JDBC 类型时,空值的默认 JDBC 类型。 某些数据库驱动需要指定列的 JDBC 类型,多数情况直接用一般类型即可,比如 NULL、VARCHAR 或 OTHER。 | JdbcType 常量,常用值:NULL、VARCHAR 或 OTHER。 | OTHER |
lazyLoadTriggerMethods | 指定对象的哪些方法触发一次延迟加载。 | ||
defaultScriptingLanguage | 指定动态 SQL 生成使用的默认脚本语言。 | ||
defaultEnumTypeHandler | 指定 Enum 使用的默认 TypeHandler 。(新增于 3.4.5) | 一个类型别名或全限定类名。 | org.apache.ibatis.type.EnumTypeHandler |
callSettersOnNulls | 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,这在依赖于 Map.keySet() 或 null 值进行初始化时比较有用。注意基本类型(int、boolean 等)是不能设置成 null 的。 | true | false | false |
returnInstanceForEmptyRow | 当返回行的所有列都是空时,MyBatis默认返回 null 。 当开启这个设置时,MyBatis会返回一个空实例。请注意,它也适用于嵌套的结果集(如集合或关联)。(新增于 3.4.2) | true | false | false |
logPrefix | 指定 MyBatis 增加到日志名称的前缀。 | ||
logImpl | 指定 MyBatis 所用日志的具体实现,未指定时将自动查找。 | SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING | 未设置 |
proxyFactory | 指定 Mybatis 创建可延迟加载对象所用到的代理工具。 | CGLIB | JAVASSIST | JAVASSIST(MyBatis 3.3 以上) |
vfsImpl | 指定 VFS 的实现 | 自定义 VFS 的实现的类全限定名,以逗号分隔。 | 未设置 |
useActualParamName | 允许使用方法签名中的名称作为语句参数名称。为了使用该特性,你的项目必须采用 Java 8 编译,并且加上 -parameters 选项。(新增于 3.4.1) | true | false | true |
configurationFactory | 指定一个提供 Configuration 实例的类。这个被返回的Configuration 实例用来加载被反序列化对象的延迟加载属性值。 这个类必须包含一个签名为static Configuration getConfiguration() 的方法。(新增于 3.2.3) | 一个类型别名或完全限定类名。 | 未设置 |
3、类型别名typeAliases
类型别名可为 Java 类型设置一个缩写名字。它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
<typeAliases>
<typeAlias alias="Author" type="domain.blog.Author"/>
<typeAlias alias="Blog" type="domain.blog.Blog"/>
<typeAlias alias="Comment" type="domain.blog.Comment"/>
<typeAlias alias="Post" type="domain.blog.Post"/>
<typeAlias alias="Section" type="domain.blog.Section"/>
<typeAlias alias="Tag" type="domain.blog.Tag"/>
</typeAliases>
当这样配置时,Blog
可以用在任何使用 domain.blog.Blog
的地方。
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,比如:
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
每一个在包 domain.blog
中的 Java Bean,在没有注解的情况下,会使用Bean 的首字母小写的非限定类名来作为它的别名。比如 domain.blog.Author
的别名为author
;若有注解,则别名为其注解值。见下面的例子:
@Alias("author")
public class Author {
...
}
下面是一些为常见的 Java 类型内建的类型别名。它们都是不区分大小写的,注意,为了应对原始类型的命名重复,采取了特殊的命名风格。
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
具体应用:
<!-- 全局别名:包与实体类都可 -->
<typeAliases>
<typeAlias type="com.gu_ppy.pojo.User" alias="user"/>
<!--Mybatis会搜索包下的所有JavaBean,他们的默认别名就是它们的类名首字母小写-->
<package name="com.gu_ppy.pojo"/>
</typeAliases>
4、typeHandlers(类型处理器)
5、objectFactory(对象工厂)
6、插件plugin
- Mybatis Pluss
7、Mappers(映射器)
可以用四种方式绑定接口与配置文件,resource、url、class、package,url不推荐使用。
class 与 **package **具有限制:接口与配置文件必须同名且在同一包下。
<mappers>
<mapper resource="com/gu_ppy/service/UserMapper.xml"/>
</mappers>
!-- 使用映射器接口实现类的完全限定类名 -->
<mappers>
<mapper class="org.mybatis.builder.AuthorMapper"/>
<mapper class="org.mybatis.builder.BlogMapper"/>
</mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers>
<package name="org.mybatis.builder"/>
</mappers>
6.日志
1、log4j
Maven依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
log4j.properties
- 简易使用版
#日志框架
log4j.rootLogger=INFO,stdout,logfile
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c]:%L - %m%n
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=logs.log
log4j.appender.logfile.MaxFileSize=512KB
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
log4j.logger.cn.itsource.pss=debug
- 详细介绍
#日志框架
#最早是System.out.print
#org.apache.log4j.Logger
#org.apache.commons.logging.Log
#java.util.logging.Logger
#org.slf4j.Logger 面向接口编程,选择实现(选择都使用这个)
#日志等级
#TRACE:详细等级,堆栈信息
#debug:类似于System.out.print
#info:类似于Hibernate的show_sql
#warn:不影响运行, 只是提示
#error:出现异常
#全局日志等级配置,输出位置
log4j.rootLogger=INFO,stdout,logfile
#stdout控制器
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
#输出格式
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c]:%L - %m%n
#文件路径输出
log4j.appender.logfile=org.apache.log4j.RollingFileAppender
#默认输出到tomcat的根路径或者运行测试工程的根路径
log4j.appender.logfile.File=pss.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n
#局部日志等级:就近原则
#log4j.logger.固定,后面添加想那个包使用不一样的日志等级
log4j.logger.cn.itsource.pss=debug
输出到文件(常用)
### set log levels ###
log4j.rootLogger = debug,stdout,D,E
### 输出到控制台 如不打印则删除或注释这部分 ###
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = %d{MM-dd HH:mm:ss} %5p %c{1}:%L - %m%n
### 输出到日志文件 ###
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = logs/log.log
log4j.appender.D.Append = true
### 输出DEBUG级别以上的日志
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = [ %p ] %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - %m%n
### 保存异常信息到单独文件 ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
## 异常日志文件名
log4j.appender.E.File = logs/error.log
log4j.appender.E.Append = true
## 只输出ERROR级别以上的日志!!!
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = [ %p ] %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - %m%n
7.分页
1、limit
使用SQL语句来实现分页。
- limit的用法
select * from test_info limit startIndex,pageSize
select * from test_info limit 3; # [0->n]
- Mapper接口
List<User> getUserByLimit(Map<String,Integer> map);
- Mapper.xml
<select id="getUserByLimit" parameterType="map" resultType="user">
select *from test_info limit #{startIndex},#{pageSize}
</select>
- 测试
@org.junit.Test
public void testGetUserByLimit(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Integer> map = new HashMap<String, Integer>();
map.put("startIndex",5);
map.put("pageSize",5);
List<User> users = mapper.getUserByLimit(map);
for (User user : users) {
System.out.println(user);
}
}
2、RowBounds实现分页
- 不通过SQL实现分页,而是通过Java代码来实现分页
@org.junit.Test
public void testGetUserByRowBounds(){
SqlSession sqlSession = MybatisUtil.getSqlSession();
//此种方法主要是Java代码来实现分页功能
RowBounds bounds = new RowBounds(2, 5);//从下标2开始,一页5个
List<User> userList = sqlSession.selectList("com.gu_ppy.service.UserMapper.selectAll",null,bounds);
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
3、分页插件 PageHelper
可以使用Mybatis的分页插件来实现分页,具体信息请查阅PageHelper.
8.注解
9. 常见问题
9.1 mapper文件与接口绑定失败
-
在使用包扫描来将mapper纳入mybatis容器时,绑定出错
-
一个最大的可能就是,Maven打包时mapper文件与mapper接口没有在同一包下,而maven项目默认src/main/java下只包含Java文件,因此类似User.xml等配置文件不会打包。
方法一:创建相同的包
- 在resource下创建与与接口文件相同的包,使mapper接口与mapper文件打包后在同一包下。
方法二:静态资源过滤
- 在pom.xml中配置以下代码
<build>
<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
<filtering>false</filtering>
</resource>
</resources>
</build>