本文是对MyBatis配置和使用的介绍,适合新手,本人是在狂神说的视频和阅读文档上自学的,主要内容如下
正文------------------------------------------------------------------------------------------------------------------------------
MyBatis 的本质就是 Java 对数据库的操作;hiberbate是对实体类进行操作
一、准备
mybatis的官方文档:https://mybatis.org/mybatis-3/zh/index.html
通过maven导入MyBatis相关依赖 https://mvnrepository.com/artifact/org.mybatis/mybatis
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
二、建立项目和导包
1.建项目
建立一个空白的maven项目
2.pom.xml配置
用来确定JDK
<properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <!-- 根据自己的 Project SDK 来确定版本 --> <maven.compiler.source>9</maven.compiler.source> <maven.compiler.target>9</maven.compiler.target> <maven.compiler.compilerVersion>9</maven.compiler.compilerVersion> </properties>
三个依赖 mysql驱动 MyBatis junit
<!--导入依赖--> <dependencies> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.46</version> </dependency> <!--mybatis--> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <!--junit--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> </dependencies>
用来是的文件读取可以跨资源包
<build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> <include>**/*.properties</include> </includes> <filtering>true</filtering> </resource> </resources> </build>
完整的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>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<!-- 根据自己的 Project SDK 来确定版本 -->
<maven.compiler.source>9</maven.compiler.source>
<maven.compiler.target>9</maven.compiler.target>
<maven.compiler.compilerVersion>9</maven.compiler.compilerVersion>
</properties>
<!--父工程-->
<groupId>com.zhang</groupId>
<artifactId>MybatisStudy</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>mybatis-01</module>
<module>mybatis-02</module>
<module>mybatis-03</module>
<module>mybatis-04</module>
</modules>
<!--导入依赖-->
<dependencies>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
<!--mybatis-->
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.6</version>
</dependency>
<!--junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
3.建立模块
最好见上面那个跨文件读取的也加入到新建模块的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">
<parent>
<artifactId>MybatisStudy</artifactId>
<groupId>com.zhang</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mybatis-01</artifactId>
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
<include>**/*.properties</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
</project>
三、数据库和连接配置
1.建库建表
建立一个数据库,在数据库中创建一个user(这里不用纠结表名,因为mybaties本质是操作SQL语句)
create database mybaties;
use mybaties;
create table user
(
id int not null primary key,
name varchar(30) not null,
pwd varchar(30) not null
)engine=innodb default charset=utf8;
这里注意:mybaties本质不是将表与实体对象建立映射,hibernate才是将实体对象与相应数据库表建立映射,所以hibernate是操作实体对象,而mybaties是操作SQL语句
2.建mybatis-config.xml文件
在resources下建立mybatis-config.xml文件
将官方文档如下复制到配置文件中(可以直接用下面修改的)
3.修改配置
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>
<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?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/zhang/dao/UserMapper.xml"/>
</mappers>
</configuration>
mysql驱动8以上要设置时区问题
同时
com.mysql.jdbc.Driver
要改为下面
com.mysql.cj.jdbc.Driver
4.编写工具包
新建util包,在包中建立工具类,sqlSessionFactory相当于一个连接池,SqlSession相当于一个连接,每次调用时使用一个连接对象
package com.zhang.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;
//sqlSessionFaction-->sqlSession
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
//获取sqlSessionFaction
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();
}
}
用来获取SqlSession
四、查询和测试
1.建立pojo文件和相应dao
user.java
package com.zhang.pojo;
public class User {
private int id;
private String name;
private String pwd;
public User() {
}
public User(int id, String name, String pwd) {
this.id = id;
this.name = name;
this.pwd = pwd;
}
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;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
编写接口
UserDao.java
package com.zhang.dao;
import com.zhang.pojo.User;
import java.util.List;
public interface UserDao {
List<User> getUserList();
}
2.配置相应的mapper.xml
namespace用来绑定相应的Dao接口
id用来绑定相应的方法
resultType用来返回对应的pojo
<?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">
<!--name用来绑定指定的Dao/Mapper接口-->
<mapper namespace="com.zhang.dao.UserDao">
<!--查询语句-->
<select id="getUserList" resultType="com.zhang.pojo.User">
select * from mybatis.user
</select>
</mapper>
注意 这里要将映射的文件注册到mybatis-config.xml中
其中映射有三种方式
- 方式一 通过xml配置文件
<mappers>
<mapper resource="com/zhang/dao/UserMapper.xml"/>
</mappers>
-
方式二 通过class的方式
<mappers> <mapper class="com.zhang.dao.UserMapper"/> </mappers>
注意:
- 接口类和它的配置文件必须同名
- 接口类和它的配置文件必须在同一包下
-
方式三 通过包扫描的方式
<mappers> <package name="com.zhang.dao"/> </mappers>
注意:接口类和配置文件必须同名
3.测试
package com.zhang.dao;
import com.zhang.pojo.User;
import com.zhang.util.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
//获取SqlSession
SqlSession sqlSession= MybatisUtils.getSqlSession();
UserDao userDao=sqlSession.getMapper(UserDao.class);//获取相应的映射操作 传入的接口类是上文创建
List<User> userList = userDao.getUserList();
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
五、注意问题
1.事务提交问题
插入、更新和删除时要注意,只要涉及到数据库的修改就要提交
sqlSession.commit();
public void updateUser(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int result = userMapper.updateUser(new User(4,"爽歪歪","2323232"));
sqlSession.commit();//对数据库有修改操作的都需要调用commit
if (result > 0) {
System.out.println("修改成功!");
}
sqlSession.close();
}
2.增删改查
<?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">
<!--name用来绑定指定的Dao/Mapper接口-->
<mapper namespace="com.zhang.dao.UserMapper">
<!--查询语句-->
<select id="getUserList" resultType="com.zhang.pojo.User">
select * from mybatis.user
</select>
<!--查询语句-->
<select id="getUserById" resultType="com.zhang.pojo.User" parameterType="int">
select * from mybatis.user where id= #{id}
</select>
<insert id="addUser" parameterType="com.zhang.pojo.User">
insert into mybatis.user(id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="com.zhang.pojo.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id} ;
</update>
<delete id="deleteUser" parameterType="int">
delete from mybatis.user where id=#{id}
</delete>
</mapper>
六、进行优化
1.连接信息读取的优化
从配置文件中读取连接设置
添加配置文件db.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
username=root
password=root
同时修改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>
<properties resource="db.properties">
</properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="com/zhang/dao/UserMapper.xml"/>
</mappers>
</configuration>
2.别名
方式一:在alias中指定别名
类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。
注意这里是绑定到相应类 在mybatis-config.xml文件中加
例如:
<typeAliases>
<typeAlias alias="User" type="com.zhang.pojo.User"/>
</typeAliases>
方式二:使用别名注解
通过扫描的方式 这个可以直接将包下所有的类的扫描 最好是在 resultType下直接使用小写类名,这中方式大小写都能接收
但是 可以通过下面方式进行自定义
@Alias("author")
public class Author {
...
}
同时 要在在mybatis-config.xml文件中加相对应的扫描包
<typeAliases>
<package name="com.zhang.pojo"/>
</typeAliases>
七、属性名和字段名不一致
解决方法
-
方法一:起别名,用SQL语句将数据库表中属性名重新起名与实体对象属性名一致(不推荐)
<select id="getUserById" resultType="com.zhang.pojo.User" parameterType="int"> select id,name,pwd as password from mybatis.user where id= #{id} </select>
-
resultMap 结果集映射 注意方法是使用resultMap
<resultMap id="UserMap" type="User"> <!--column为数据库字段 property为类属性--> <result column="id" property="id"/> <result column="name" property="name"/> <result column="pwd" property="password"/> </resultMap> <!--查询语句--> <select id="getUserById" resultMap="UserMap" parameterType="int"> select * from mybatis.user where id= #{id} </select>
ps:其实只要映射不一样的就行
八、日志
1.日志工厂
主要使用 LOG4J STDOUT_LOGGING
-
STDOUT_LOGGING
在mybatis-config.xml配置如下:
<!--使用日志 value选择日志类型--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings>
可以看到显示
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mR5VjP9D-1650615908921)(C:\Users\张大刀\AppData\Roaming\Typora\typora-user-images\image-20201212195108044.png)]
-
LOG4J
-
先配置 同上
在mybatis-config.xml配置如下
<settings> <setting name="logImpl" value="LOG4J"/> </settings>
在pom.xml中导入依赖
<!-- https://mvnrepository.com/artifact/log4j/log4j --> <!--日志依赖--> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency>
-
建立log4j.properties文件
### 设置 这里的名字对应下面不同级别### log4j.rootLogger = DEBUG,I,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 = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n ### 输出INFO级别以上的日志到=./logs/info.log ### log4j.appender.I = org.apache.log4j.DailyRollingFileAppender log4j.appender.I.File = ./logs/info.log log4j.appender.I.Append = true log4j.appender.I.Threshold = INFO log4j.appender.I.layout = org.apache.log4j.PatternLayout log4j.appender.I.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 输出DEBUG 级别以上的日志到=./logs/debug.log ### log4j.appender.D = org.apache.log4j.DailyRollingFileAppender log4j.appender.D.File = ./logs/debug.log log4j.appender.D.Append = true log4j.appender.D.Threshold = DEBUG log4j.appender.D.layout = org.apache.log4j.PatternLayout log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n ### 输出ERROR 级别以上的日志到=./logs/error.log ### log4j.appender.E = org.apache.log4j.DailyRollingFileAppender log4j.appender.E.File =./logs/error.log log4j.appender.E.Append = true log4j.appender.E.Threshold = ERROR log4j.appender.E.layout = org.apache.log4j.PatternLayout log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %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
-
2.log4j日志的简单使用
static Logger logger=Logger.getLogger(UserMapperTest.class);
//getLogger中输入相应方法名
@Test
public void testLog4j(){
//可以通过这个方式实现找错
logger.info("info进入testLog4j");
logger.error("erro进入testLog4j");
logger.debug("debug进入testLog4j");
}
九、分页
1.limit
limit后面接始末位置 如果一个参数则默认从0开始
select * from user limit 0,2;
十、注解
-
mybatis最初配置信息是基于 XML ,映射语句(SQL)也是定义在 XML 中的。而到MyBatis 3提供了新的基于注解的配置。不幸的是,Java 注解的的表达力和灵活性十分有限。最强大的 MyBatis 映射并不能用注解来构建
-
sql 类型主要分成 :
-
- @select ()
- @update ()
- @Insert ()
- @delete ()
**注意:**利用注解开发就不需要mapper.xml映射文件了 .
配置和使用
1、在接口中添加注解
//查询全部用户
@Select("select id,name,pwd password from user")
public List<User> getAllUser();
2、在mybatis的核心配置文件中注入
<!--使用class绑定接口-->
<mappers>
<mapper class="com.kuang.mapper.UserMapper"/>
</mappers>
3、测试
@Test
public void testSelectById(){
//获取SqlSession
SqlSession sqlSession= MybatisUtils.getSqlSession();
//本质上利用了jvm的动态代理机制
UserMapper userMapper =sqlSession.getMapper(UserMapper.class);
List<User> users= userMapper.getAllUsers();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
注解增删改
改造MybatisUtils工具类的getSession( ) 方法,重载实现。
//获取SqlSession连接
public static SqlSession getSession(){
return getSession(true); //事务自动提交
}
public static SqlSession getSession(boolean flag){
return sqlSessionFactory.openSession(flag);
}
【注意】确保实体类和数据库字段对应
查询:
1、编写接口方法注解
//根据id查询用户
@Select("select * from user where id = #{id}")
User selectUserById(@Param("id") int id);
2、测试
@Test
public void testSelectUserById() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUserById(1);
System.out.println(user);
session.close();
}
新增:
1、编写接口方法注解
//添加一个用户
@Insert("insert into user (id,name,pwd) values (#{id},#{name},#{pwd})")
int addUser(User user);
2、测试
@Test
public void testAddUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(6, "秦疆", "123456");
mapper.addUser(user);
session.close();
}
修改:
1、编写接口方法注解
//修改一个用户
@Update("update user set name=#{name},pwd=#{pwd} where id = #{id}")
int updateUser(User user);
2、测试
@Test
public void testUpdateUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User(6, "秦疆", "zxcvbn");
mapper.updateUser(user);
session.close();
}
删除:
1、编写接口方法注解
//根据id删除用
@Delete("delete from user where id = #{id}")
int deleteUser(@Param("id")int id);
2、测试
@Test
public void testDeleteUser() {
SqlSession session = MybatisUtils.getSession();
UserMapper mapper = session.getMapper(UserMapper.class);
mapper.deleteUser(6);
session.close();
}
【注意点:增删改一定记得对事务的处理】
关于@Param
@Param注解用于给方法参数起一个名字。以下是总结的使用原则:
- 在方法只接受一个参数的情况下,可以不使用@Param。
- 在方法接受多个参数的情况下,建议一定要使用@Param注解给参数命名。
- 如果参数是 JavaBean , 则不能使用@Param。
- 不使用@Param注解时,参数只能有一个,并且是Javabean。
#与$的区别
-
#{} 的作用主要是替换预编译语句(PrepareStatement)中的占位符? 【推荐使用】
INSERT INTO user (name) VALUES (#{name}); INSERT INTO user (name) VALUES (?);
-
${} 的作用是直接进行字符串替换
INSERT INTO user (name) VALUES ('${name}'); INSERT INTO user (name) VALUES ('kuangshen');
使用注解和配置文件协同开发,才是MyBatis的最佳实践!
总结
技术长时间不适用好容易就遗忘,我平常会把写的代码和笔记放在自己的仓库中,遗忘了看看,希望这篇文章对大家有所帮助。
本文有自己写的代码,可见仓库:
https://gitee.com/zhangdadao/person-study-mybatis.git