在 MyBatis 中有两种类型的事务管理器(也就是 type=“[JDBC|MANAGED]”):
dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。
我们可以通过properties属性来实现引用配置文件
这些属性都是可外部配置动态替换的,既可以在典型的Java属性文件中配置,又可以通过properties元素的子元素来传递。【db.properties】
编写数据库配置文件db.properties(这个文件要放到上面):
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSl=true;useUnicode=true;characterEncoding=utf8;serverTimezone=UTC
username=root
password=123456
在配置文件中引入:
<properties resource="db.properties">
<property name="username" value="root"/>
<property name="password" value="123456"/>
properties>
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。例如:
<typeAliases>
<typeAlias type="com.yjr.pojo.User" alias="user"/>
typeAliases>
<select id="getUserLikeValue" resultType="user" >
select * from user where name like "%"#{value}"%"
select>
也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,例如:
<typeAliases>
<package name="com.yjr.pojo"/>
typeAliases>
每一个在包 com.yjr.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名(大写也行)。 比如 com.yjr.pojo.User 的别名为 user(或User);若有注解,则别名为其注解值。见下面的例子:
@Alias("radan")
public class User {
private int id;
private String name;
private String pwd;
}
总结:实体类比较少的时候多采用第一种方式;当实体类比较多的时候,建议采用第二种方式。
MapperRegistry:注册绑定我们的Mapper文件
方式一(使用resource的资源引用–这个用斜杠划分)----推荐使用:
这样即可以将xml文件放到resource目录下,也可以避免下面的这些问题。
<mappers>
<mapper resource="com/yjr/dao/UserMapper.xml"/>
mappers>
方式二(使用Class文件绑定注册):
<mappers>
<mapper class="com.yjr.dao.UserMapper"/>
mappers>
注意点:
方式三(使用扫描包进行注册绑定):
<mappers>
<package name="com.yjr.dao"/>
mappers>
注意点:
作用域、生命周期是至关重要的,因为错误的使用会导致非常严重的并发问题。
SQLSessionFactoryBuilder:
SQLSessionFactory:
SQLSession:
数据库中的字段:
实体类中的字段:
public class User {
private int id;
private String name;
private String password; //显然不一致
}
问题:当实体类的字段名和数据库中字段名不一致时,程序可以执行,但是测试的结果是查询的所有记录的该字段值为null。
解决方法:
<select id="getAllUsers" resultType="User">
select id,name,pwd as password from user
</select>
column:数据库中的字段 property:实体类中的属性
<resultMap id="userMap" type="User">
<result property="id" column="id"/>
<result property="name" column="name"/>
<result property="password" column="pwd"/>
resultMap>
<select id="getAllUsers" resultMap="userMap">
select * from user
select>
在MyBatis中具体事宜哪一个日志,在设置中设定!
STDOUT_LOGGING标准日志输出
在mybatis核心配置文件中,配置日志。
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
什么是log4j?
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-apiartifactId>
<version>1.7.25version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-simpleartifactId>
<version>1.7.25version>
<scope>testscope>
dependency>
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
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/yjr.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
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
static Logger logger= Logger.getLogger(UserDaoTest.class);
logger.info("info:进入了testLog4j方法");
logger.debug("debug:进入了testLog4j方法");
logger.error("error:进入了testLog4j方法");
思考:为什么分页?–减少数据的处理量
select * from user limit startIndex,pageSize #startIndex:其实下标(默认从0开始,pageSize :一页的大小)
select * from user limit 3; #[0,n]
使用MyBatis实现分页,核心SQL
//分页
List<User> getUserByLimit(Map<String,Integer> map);
<select id="getUserByLimit" parameterType="map" resultMap="userMap" >
select * from user limit #{startIndex},#{pageSize}
select>
@Test
public void getUserByLimit() throws IOException {
HashMap hashMap=new HashMap();
hashMap.put("startIndex",0);
hashMap.put("pageSize",2);
//1.获取SQLSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//方式一:getMapper-----目前最好用
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
System.out.println(mapper.getUserByLimit(hashMap));
sqlSession.close();
}
参考资料:PageHelper中文文档
根本原因:解耦,可拓展,提高复用;在分层开发中,上层不管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好。
接口的理解:
//查询所有用户
@Select("select * from user")
List<User> getAllUsers();
<mappers>
<mapper class="com.yjr.dao.UserMapper"/>
mappers>
@Test
public void getAllUsersTest() throws IOException {
//1.获取SQLSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//方式一:getMapper-----目前最好用
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
System.out.println(mapper.getAllUsers());
sqlSession.close();
}
注意点(实体类和数据库中的字段出现不一致):
@Select("select * from user")
@Results({
@Result(property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "password", column = "pwd")
//column :数据库中的名字 property:实体类中的名字
})
List<User> getAllUsers();
用@Results注解来解决上述问题。
MyBatis详细的执行流程
Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不需要再写getter、setter或equals方法,只要有一个注解,就有一个功能齐全的构建器、自动记录变量等等。
常用注解:
@Data:无参构造、get、set、toString、hasCode、equals
@AllArgsConstructor:有参构造
@NoArgsConstructor:无参构造
@toString:生成一个toSring()方法
@Getter:给所有的属性生成get方法
@Setter:给所有的属性生成set方法
Lombok的优点:
Lombok的缺点:
使用步骤:
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.24version>
<scope>providedscope>
dependency>
package com.yjr.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@NoArgsConstructor
@Data
@AllArgsConstructor
public class User {
private int id;
private String name;
private String password;
}