传统方式操作DB
- 传统方式有什么弊端?
- 需要自己写代码连接数据库,这段代码程序员怎么编写,没有一定标准
- SQL语句的执行也不是OOP实现,程序员更习惯像insert(object)这种操作。
- 因为SQL语句写在程序中,属于硬编码,不利于代码维护。
- 结果集的封装先获取每行数据,再通过程序员手动封装每个字段的值,很麻烦。
- 如果没有关闭资源,造成资源浪费。
数据源配置回顾
1. JDBC 配置数据源
// JDBC select
@Test
public void testSelect() {
//1. 得到连接
Connection connection = null;
//2. 组织一个 sql
String sql = "select * from actor where id = ?";
PreparedStatement preparedStatement = null;
ResultSet set = null;
//3. 创建 PreparedStatement 对象
try {
connection = JdbcUtils.getConnection();
System.out.println(connection.getClass()); //com.mysql.jdbc.JDBC4Connection
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 5);//给?号赋值
//执行, 得到结果集
set = preparedStatement.executeQuery();
//遍历该结果集
while (set.next()) {
int id = set.getInt("id");
String name = set.getString("name");
String sex = set.getString("sex");
Date borndate = set.getDate("borndate");
String phone = set.getString("phone");
System.out.println(id + "\t" + name + "\t" + sex + "\t" + borndate + "\t" + phone);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭资源
JdbcUtils.close(set, preparedStatement, connection);
}
}
2. C3p0 配置数据源
方式一
//方式1: 相关参数,在程序中指定user, url , password等
@Test
public void testC3P0_01() throws Exception {
//1. 创建一个数据源对象
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource();
//2. 通过配置文件mysql.properties 获取相关连接的信息
Properties properties = new Properties();
properties.load(new FileInputStream("src\\mysql.properties"));
//读取相关的属性值
String user = properties.getProperty("user");
String password = properties.getProperty("password");
String url = properties.getProperty("url");
String driver = properties.getProperty("driver");
//给数据源 comboPooledDataSource 设置相关的参数
//注意:连接管理是由 comboPooledDataSource 来管理
comboPooledDataSource.setDriverClass(driver);
comboPooledDataSource.setJdbcUrl(url);
comboPooledDataSource.setUser(user);
comboPooledDataSource.setPassword(password);
//设置初始化连接数
comboPooledDataSource.setInitialPoolSize(10);
//最大连接数
comboPooledDataSource.setMaxPoolSize(50);
//测试连接池的效率, 测试对mysql 5000次操作
long start = System.currentTimeMillis();
for (int i = 0; i < 5000; i++) {
Connection connection = comboPooledDataSource.getConnection(); //这个方法就是从 DataSource 接口实现的
//System.out.println("连接OK");
connection.close();
}
long end = System.currentTimeMillis();
//c3p0 5000连接mysql 耗时=391
System.out.println("c3p0 5000连接mysql 耗时=" + (end - start));
}
mysql.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bank_db
user=root
password=root1234
方式二 通过C3p0配置模版方式
<c3p0-config>
<!-- 数据源名称代表连接池 -->
<named-config name="hsp_edu">
<!-- 驱动类 -->
<property name="driverClass">com.mysql.jdbc.Driver</property>
<!-- url-->
<property name="jdbcUrl">jdbc:mysql://127.0.0.1:3306/hsp_db02</property>
<!-- 用户名 -->
<property name="user">root</property>
<!-- 密码 -->
<property name="password">hsp</property>
<!-- 每次增长的连接数-->
<property name="acquireIncrement">5</property>
<!-- 初始的连接数 -->
<property name="initialPoolSize">10</property>
<!-- 最小连接数 -->
<property name="minPoolSize">5</property>
<!-- 最大连接数 -->
<property name="maxPoolSize">50</property>
<!-- 可连接的最多的命令对象数 -->
<property name="maxStatements">5</property>
<!-- 每个连接对象可连接的最多的命令对象数 -->
<property name="maxStatementsPerConnection">2</property>
</named-config>
</c3p0-config>
//第二种方式 使用配置文件模板来完成
//1. 将c3p0 提供的 c3p0.config.xml 拷贝到 src目录下
//2. 该文件指定了连接数据库和连接池的相关参数
@Test
public void testC3P0_02() throws SQLException {
ComboPooledDataSource comboPooledDataSource = new ComboPooledDataSource("c3p0");
//测试5000次连接mysql
long start = System.currentTimeMillis();
System.out.println("开始执行....");
for (int i = 0; i < 500000; i++) {
Connection connection = comboPooledDataSource.getConnection();
//System.out.println("连接OK~");
connection.close();
}
long end = System.currentTimeMillis();
//c3p0的第二种方式 耗时=413
System.out.println("c3p0的第二种方式(500000) 耗时=" + (end - start));//1917
}
3. Druid 配置数据源
package com.trishia.jdbc;
import com.alibaba.druid.pool.DruidDataSourceFactory;
import org.junit.Test;
import javax.sql.DataSource;
import java.io.FileInputStream;
import java.sql.Connection;
import java.util.Properties;
/**
* @author 韩顺平
* @version 1.0
* 测试druid的使用
*/
public class Druid_ {
@Test
public void testDruid() throws Exception {
//1. 加入 Druid jar包
//2. 加入 配置文件 druid.properties , 将该文件拷贝项目的src目录
//3. 创建Properties对象, 读取配置文件
Properties properties = new Properties();
properties.load(new FileInputStream("src/druid.properties"));
//4. 创建一个指定参数的数据库连接池, Druid连接池
DataSource dataSource =
DruidDataSourceFactory.createDataSource(properties);
long start = System.currentTimeMillis();
for (int i = 0; i < 500000; i++) {
Connection connection = dataSource.getConnection();
System.out.println(connection.getClass());
//System.out.println("连接成功!");
connection.close();
}
long end = System.currentTimeMillis();
//druid连接池 操作5000 耗时=412
System.out.println("druid连接池 操作500000 耗时=" + (end - start));//539
}
}
druid.properties
#key=value
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/bank_db?rewriteBatchedStatements=true
username=root
password=hsp
#initial connection Size
initialSize=10
#min idle connecton size
minIdle=5
#max active connection size
maxActive=50
#max wait time (5000 mil seconds)
maxWait=5000
Myabtis工作流程
使用Mybatis的好处
- 数据库的连接/连接池只需要连接即可,配置方式都是标准的。
- 对DB的操作是以程序员更容易理解的OOP方式操作。
- SQL语句可以写在xml文件中,实现Java代码与SQL语句的解藕。
- Mybatis可以优化DB的操作,提高效率。如配置缓存
一、 代码入门
需求:通过Mybatis完成对Monster表的CRUD。
1. 创建monster表
CREATE DATABASE `mybatis`;
use `mybatis`;
CREATE TABLE `monster`(
`id` INT NOT NULL AUTO_INCREMENT,
`age` INT NOT NULL,
`birthday` DATE DEFAULT NULL,
`email` VARCHAR(255) NOT NULL ,
`gender` TINYINT NOT NULL, -- 0 女 1 男
`name` VARCHAR(255) NOT NULL,
`salary` DOUBLE NOT NULL,
PRIMARY KEY (`id`)
) CHARSET=utf8;
2. 创建Maven项目,配置pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<!--
将mybatis作为父项目管理多个子模块/子项目
1. 父项目的坐标 groupId + artifactId
2. 父项目会管理多个子项目,父项目中依赖可以直接给子项目用。
-->
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--mysql依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
<!--mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.7</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<!--表示该jar包作用在test目录下-->
<!--项目学习阶段可以先注释-->
<!--<scope>test</scope>-->
</dependency>
</dependencies>
</project>
3. 删除src目录,创建子Module/项目/模块
(1)父项目pom.xml变化
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.example</groupId>
<artifactId>mybatis</artifactId>
<version>1.0-SNAPSHOT</version>
<!--&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-->
<!--
<packaging>pom</packaging> : 表示该项目是父项目
<modules> 指定哪些子模块
<module>mybatis_quickstart</module>
</modules>
-->
<packaging>pom</packaging>
<modules>
<module>mybatis_quickstart</module>
</modules>
<!--&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&-->
<!--
将mybatis作为父项目管理多个子模块/子项目
1. 父项目的坐标 groupId + artifactId
2. 父项目会管理多个子项目,父项目中依赖可以直接给子项目用。
-->
<properties>
...
</properties>
<dependencies>
...
</dependencies>
</project>
(2)子项目pom.xml及结构
4. 编写mybatis-config.xml
(1)去官网找模版
https://mybatis.net.cn/getting-started.html
(2)配置数据库连接和数据源
注意:mybatis-config.xml是资源文件,要放到resources目录下面,包括XxxMapper.xml也是资源文件,也要放到resources目录下面。
<?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"/>
<!--配置数据源-->
<!--
useSSL=true : 使用安全连接
& & 转义符,防止解析出问题
useUnicode=true : 使用Unicode 防止编码错误
characterEncoding=UTF-8 : 指定字符集,防止中文乱码
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="root1234"/>
</dataSource>
</environment>
</environments>
<mappers>
<!--<mapper resource="org/mybatis/example/BlogMapper.xml"/>-->
</mappers>
</configuration>
5. 编写Monster类
package com.trishia.entity;
import java.util.Date;
/**
* Monster属性和monster表字段对应
* 属性名与表字段名称要一致。
*/
public class Monster {
private Integer id;
private Integer age;
private String name;
private String email;
private Date birthday;
private double salary;
private Integer gender;
// getter/setter/toString/NonConstructor/AllConstructor
...
}
6. 编写MonsterMapper接口
定义操作DB的方法
package com.trishia.mapper;
import com.trishia.entity.Monster;
/**
* 接口
* 用于声明操作Monster表的各种方法,方法的实现可以通过【注解】或【xml】
* 怎么实现?底层机制往后看。
*/
public interface MonsterMapper {
/**
* 添加Monster
* @param monster
*/
void addMonster(Monster monster);
}
7. 编写MonsterMapper.xml
(1) 实现MonsterMapper接口中的方法,并将该文件配置在mybatis-config.xml
中。
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--
namespace : 通过namespace指定该文件实现哪个接口中的方法。
MonsterMapper接口与MonsterMapper.xml文件中的方法是怎么映射的呢?
就是通过namespace属性配置的。
-->
<mapper namespace="com.trishia.mapper.MonsterMapper">
<!--
mapper下的子标签
1. insert/delete/update/select对应增删改查语句
2. sql : 用来定义可重用的代码片段
3. resultMap : 结果集映射
4. cache : 缓存,默认仅仅对一个会话中的数据进行缓存,
5. cache-ref : 缓存引用,缓存共享。
-->
<!--
<insert
id="addMonster" : 声明接口中的方法
parameterType="com.trishia.entity.Monster" : 声明参数类型
flushCache="true" :将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
statementType="PREPARED" : 可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用 Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
keyProperty="" :(仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用 getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值
keyColumn="" :((仅适用于 insert 和 update)设置生成键在表中的列名
useGeneratedKeys="" : (仅适用于 insert 和 update)这会令 MyBatis 使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键
timeout="20" 这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
-->
<!-- #{} 用来获取Monster对象中的属性 -->
<insert id="addMonster" parameterType="com.trishia.entity.Monster">
insert into `monster` (`age`,`birthday`,`email`,`gender`,`name`,`salary`) values (#{age},#{birthday},#{email},#{gender},#{name},#{salary});
</insert>
</mapper>
<?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">
...
</environments>
<mappers>
<!--配置关联的mapper.xml-->
<mapper resource="com/trishia/mapper/MonsterMapper.xml"/>
</mappers>
</configuration>
8. 编写工具类
package com.trishia.util;
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;
/**
* 工具类,可以通过SqlSessionFactory 得到 SqlSession
*/
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
// 静态代码块初始化SqlSessionFactory
static {
InputStream inputStream;
// 加载的目录,实际上是生成的target目录
String resource = "mybatis-config.xml";
try {
inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
// 编写方法,通过SqlSessionFactory,返回SqlSession
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
9. 编写java主程序,测试添加任务
package com.trishia.mapper;
import com.trishia.entity.Monster;
import com.trishia.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
public class MonsterMapperTest {
private SqlSession sqlSession;
private MonsterMapper monsterMapper;
// 编写方法完成初始化
@Before
public void init(){
// 获取SqlSession
sqlSession = MyBatisUtils.getSqlSession();
// 获取MonsterMapper,通过反射根据类型获取动态代理对象
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
System.out.println("MonsterMapper.class = " + MonsterMapper.class);
System.out.println("monsterMapper.getClass() = " + monsterMapper.getClass());
}
@Test
public void testInsert(){
// 插入10条数据
for (int i = 0; i < 10; i++) {
Monster monster = new Monster();
monster.setId(null);
monster.setAge(18 + i);
monster.setName("绿巨人"+i);
monster.setEmail("lvjuren" + i + "@123.com");
monster.setSalary(2000);
monster.setGender(1);
monsterMapper.addMonster(monster);
}
}
// 如果是增删改需要提交事务
@After
public void commit(){
if (sqlSession != null){
sqlSession.commit();
sqlSession.close(); // 将连接放回连接池
}
}
}
MyBatis基础
1. 返回自增长id
(1) 编写MonsterMapper接口
void addMonsterReturnId(Monster monster);
(2) 配置MonsterMapper.xml
<mapper namespace="com.trishia.mapper.MonsterMapper">
<!--
想要返回自增长的id,需要两个属性 useGeneratedKeys 和 keyProperty
useGeneratedKeys="true" : 配置为true,就会获取数据库添加记录时生成的自增长id
keyProperty="id" : 指定该对象属性中,自增长id赋值给哪个属性
此时就可以通过添加的Monster对象直接getId(),就可以获取到自增长id的值了。
-->
<insert id="addMonsterReturnId" parameterType="com.trishia.entity.Monster" useGeneratedKeys="true" keyProperty="id">
insert into `monster` (`age`,`birthday`,`email`,`gender`,`name`,`salary`) values (#{age},#{birthday},#{email},#{gender},#{name},#{salary});
</insert>
</mapper>
(3)Junit测试
package com.trishia.mapper;
import com.trishia.entity.Monster;
import com.trishia.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.util.Date;
public class MonsterMapperTest {
private SqlSession sqlSession;
private MonsterMapper monsterMapper;
// 编写方法完成初始化
@Before
public void init(){
// 获取SqlSession
sqlSession = MyBatisUtils.getSqlSession();
// 获取MonsterMapper,通过反射根据类型获取动态代理对象
monsterMapper = sqlSession.getMapper(MonsterMapper.class);
}
@Test
public void testInsertReturnId(){
Monster monster = new Monster();
//monster.setId(null);
monster.setAge(80);
monster.setName("黑山老妖");
monster.setEmail("laoyao@123.com");
monster.setSalary(2000);
monster.setGender(0);
monsterMapper.addMonsterReturnId(monster);
// 不用接收任何返回结果,直接getId() 即可。
System.out.println("monster的自增长id = " + monster.getId());
}
// 如果是增删改需要提交事务
@After
public void commit(){
if (sqlSession != null){
sqlSession.commit();
sqlSession.close(); // 将连接放回连接池
}
}
}
(4)测试结果
2. parameter参数配置
首先以“根据id删除”为例,展开学习
(1)编写MonsterMapper接口
/**
* 根据id删除Monster
* @param id
*/
void deleteById(Integer id);
(2)配置MonsterMapper.xml
<mapper namespace="com.trishia.mapper.MonsterMapper">
<!--
parameterType 的参数配置:
(1)如果参数类型是 java.lang包下的类,可以省略报名。
parameterType="java.lang.Integer"
parameterType="Integer"
-->
<delete id="deleteById" parameterType="java.lang.Integer">
delete from `monster`where `id` = #{id}
</delete>
</mapper>
(3)Junit测试
3. typeAlias 类型别名
配置别名之后,parameterType
resultType
就可以省略全限定类名,直接使用别名指定参数类型。
(1)官网示例
<configuration>
<!-- 配置方式一 : 单独指定别名 -->
<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>
<!--
配置方式二 :
指定包,MyBatis 会在包名下面搜索需要的 Java Bean。
(1)在没有注解的情况下,会使用首字母小写的非限定类名来作为它的别名
(2)若有注解,则别名为其注解值。
-->
<typeAliases>
<package name="domain.blog"/>
</typeAliases>
<environments default="development">...</environments>
<mappers>...</mappers>
</configuration>
@Alias("author")
public class Author {
...
}
(2)配置mybatis-config.xml
(3)配置MonsterMapper.xml
(4)编写MonsterMapper接口
/**
* 修改Monster
* @param monster
*/
void updateMonster(Monster monster);
/**
* 获取单个Monster对象
* @param id
* @return
*/
Monster getMonsterById(Integer id);
/**
* 查询所有
* @return
*/
List<Monster> getMonsterList();
(5)Junit测试
@Test
public void testUpdate(){
Monster monster = new Monster();
monster.setId(1);
monster.setAge(80);
monster.setBirthday(new Date());
monster.setName("黑山老妖");
monster.setEmail("laoyao@123.com");
monster.setSalary(2000);
monster.setGender(0);
monsterMapper.updateMonster(monster);
}
@Test
public void testSelectOne(){
Monster monster = monsterMapper.getMonsterById(1);
//monster=Monster{id=1, age=80, name='黑山老妖', email='laoyao@123.com', birthday=Sun Jul 28 00:00:00 CST 2024, salary=2000.0, gender=0}
System.out.println("testSelectOne 方法被调用。monster=" + monster);
}
@Test
public void testSelectAll(){
List<Monster> monsters = monsterMapper.getMonsterList();
System.out.println("monsters = " + monsters);
//monsters = [Monster{id=1, age=80, name='黑山老妖', email='laoyao@123.com', birthday=Sun Jul 28 00:00:00 CST 2024, salary=2000.0, gender=0},
// Monster{id=12, age=18, name='绿巨人0', email='lvjuren0@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=13, age=19, name='绿巨人1', email='lvjuren1@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=14, age=20, name='绿巨人2', email='lvjuren2@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=15, age=21, name='绿巨人3', email='lvjuren3@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=16, age=22, name='绿巨人4', email='lvjuren4@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=17, age=23, name='绿巨人5', email='lvjuren5@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=18, age=24, name='绿巨人6', email='lvjuren6@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=19, age=25, name='绿巨人7', email='lvjuren7@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=20, age=26, name='绿巨人8', email='lvjuren8@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=21, age=27, name='绿巨人9', email='lvjuren9@123.com', birthday=null, salary=2000.0, gender=1},
// Monster{id=22, age=80, name='黑山老妖', email='laoyao@123.com', birthday=null, salary=2000.0, gender=0},
// Monster{id=23, age=80, name='黑山老妖', email='laoyao@123.com', birthday=null, salary=2000.0, gender=0},
// Monster{id=25, age=80, name='黑山老妖', email='laoyao@123.com', birthday=null, salary=2000.0, gender=0}]
}
4. 配置日志输出
在开发MyBatis程序时,程序员往往需要看程序发给MySQL的SQL语句到底什么样。此时就要用到日志输出
。
- 当sql不正确时
- 想要优化sql时
- sql执行效率低时
实际还要看底层原生的SQL长什么样子。
1. MyBatis官网
注意:如果想使用LOG4J得导入依赖。
2. 个人总结
(1)配置mybatis-config.xml
我这里使用 STDOUT_LOGGING
,配置好了直接用即可。
<configuration>
<settings>
<!--
日志输出配置
logImpl : 指定MyBatis所用日志实现 未指定将自动查找。
SLF4J | LOG4J | LOG4J2 | JDK_LOGGING | COMMONS_LOGGING | STDOUT_LOGGING | NO_LOGGING
-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
</configuration>