首先,阅读官方文档,我们知道了MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。
持久层意味着我们可以把数据持久稳定的进行存储,说白了就是存进数据库里(相对应的如果数据存在内存里就不是持久存储)。mybatis中的映射的实现是依赖xml的配置,以及使用注解的方式。下面就来创建第一个mybatis的小程序,并且实现一些曾删改查功能。
首先打开Idea,创建一个Maven项目
创建好了之后在pom中引入依赖,我使用的是mysql数据库。其中名为lombok的东西是一个简化代码的插件( 通过注释的方法,可以不用在代码里频繁的为属性写set和get方法)
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.19</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
<scope>provided</scope>
</dependency>
</dependencies>
做好这一步,我们需要在resourcces下建立一个核心配置文件,一般来说都叫做mybatis-config
在文件中,我们需要对数据库连接池进行配置,特别注意数据库时区的配置(serverTimezone=GMT),不写很大可能之后会报错
<?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.cj.jdbc.Driver"/>
<!-- 数据库地址-->
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&serverTimezone=GMT&characerEncoding=UFT-8"/>
<!-- 数据库名以及密码-->
<property name="username" value="root"/>
<property name="password" value="123"/>
</dataSource>
</environment>
</environments>
</configuration>
同时我们可以在idea中将数据库连接
测试连接的时候会涉及一个时区问题,填写了就没问题了
连接成功后,就可以在数据库里建立一个user表,包含三个字段,分别是id、name、pwd,并添加一些数据
接着我们需要在项目模块下的src/main/java下建立几个包(com.lzw随便起的,名字缩写,请忽略),首先DAO层,里面提供业务接口和实现方法,POJO层用来存放属性,utils提供了mybatis的实现类。
我们首先在utils下建立一个java类,名叫MybatisUtils,作为一个mybatis的实现类
在MybatisUtils中,涉及到了SqlSessionFactory、SqlSessionFactoryBuilder、sqlSession 三个东西
SqlSessionFactoryBuilder:是用来创建一个session工厂,也就是SqlSessionFactory,官方文档中写到:“每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得,而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例”。
Session:可以理解为数据库连接池中的一个连接,使用时会占用资源,所以使用时打开一个Session,使用完成后必须要关闭。
package com.lzw.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;
//sqlSessionFactory
public class MybatisUtils {
//创建SqlSessionFactory
private static SqlSessionFactory sqlSessionFactory;
//静态代码块
static {
try {
//明确sqlSessionFactory实例对应的xml核心配置文件
String resource = "mybatis-config.xml";
//创建一个IO流,读取xml的file信息
InputStream inputStream = Resources.getResourceAsStream(resource);
//利用SqlSessionFactoryBuilder创建对应xml下的sqlSessionFactory实例
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//创建一个得到session连接的方法
public static SqlSession getSqlSession(){
SqlSession sqlSession = sqlSessionFactory.openSession();
return sqlSession;
}
}
然后我们在POJO层中建立一个属性类,名为user
在这个类中,定义了id、name、以及pwd,名字最好和数据库一致,不一样也没关系,后期可以配置名字之间的映射关系
我们可以看到@Data注解,这是Lombok插件提供的,这样我们就不用为属性写set和get方法了,代码会在编译时自动生成
package com.lzw.POJO;
import lombok.Data;
@Data
public class user {
private int id;
private String name;
private String pwd;
public user(int id, String name, String pwd) {
this.id =id;
this.name =name;
this.pwd =pwd;
}
}
有了user类之后,就可以在DAO下建立一个UserDao接口(用于写业务接口),以及对应的xml映射文件(用于实现接口).
在UserDao中,我们定义接口,并添加一个方法
package com.lzw.DAO;
import com.lzw.POJO.user;
import java.util.List;
public interface UserDao {
//获取用户列表
List<user> getUserList();
}
那么在UserDao.xml中,我们就要实现对应接口中的方法,在xml中,我们需要明确命名空间(UserDao),以及实现的方法名,也就是id(为GetUserList),还有返回类型resultType(POJO下的user类型),最后就是一句SQL,很简单,用于读取表user的所有列
<?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">
<mapper namespace="com.lzw.DAO.UserDao">
<select id="getUserList" resultType="com.lzw.POJO.user">
select * from mybatis.user
</select>
</mapper>
一切完工后呢,我们可以写一个测试类来测试这个功能了,于是我们可以在src/test/java下建立一个测试类
我们可以用以下testToGetUser方法测试
package UserDaoTexst;
import com.lzw.DAO.UserDao;
import com.lzw.POJO.user;
import com.lzw.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class UserDaoTest {
@Test
public void testToGetUser(){
//第一步
//获得SqlSession对象,用到之前写好的getSqlSession方法
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
//第二步
//使用sqlSession中的getMapper方法,去获取我们接口对应的类
UserDao userDao = sqlSession.getMapper(UserDao.class);
//第三步
//得到类对象后,使用对象下的getUserList方法,获得数据库中数据
List<user> userList = userDao.getUserList();
System.out.println(userList);
}
finally {
//最后用完别忘了关!
sqlSession.close();
}
}
}
值得注意的是,在代码的第二步中,我们可以看到这一句:
UserDao userDao = sqlSession.getMapper(UserDao.class)
各位有没有想过,若是之后测试成功了相应的功能,说明在编译时,系统是必定得到了我们的接口以及实现方法的,它是怎么实现的呢?
其实在sqlSession中,有getMapper方法,方法的参数是类名,这里我们传入了UserDao这个类。在编译时,Java利用反射机制,会创建UserDao类,并得到其中的一切接口。
那么我们问题又来了,已经找到了接口,但是mybatis的接口实现依赖的是xml的映射,也就是说我们把接口的功能细节都写在了UserDao.xml中,那么编译的时候,计算机又怎么去找到这个呢?这个问题我们先放下,看看测试会不会成功。
我们运行方法,果然报错,错误是对于我们的UserDao接口没有被MapperRegistry,也就是说没有找到代理它的地址
所以我们需要在核心配置文件中,添加一个maper,从而让系统能够扫描到接口的实现出处(在mybatis-config.xml下添加)
<mappers>
<mapper resource="com/lzw/dao/UserDao.xml"/>
</mappers>
测试之前,我们在pom中加入一个build,加强对于xml文件和properties文件的识别
<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>
再次测试,没有问题了
最后我们添加增删改查方法
//根据id查询用户
user getUserById(int id);
//插入
int insertUser(user User);
//修改
int updateUser(user User);
//删除
int deleteUser(int id);
然后我们在xml中进行映射
<select id="getUserById" parameterType="int" resultType="user">
select * from mybatis.user where id=#{id}
</select>
<insert id="insertUser" parameterType="com.lzw.POJO.user" >
insert into mybatis.user (id,name,pwd) values (#{id},#{name},#{pwd})
</insert>
<update id="updateUser" parameterType="com.lzw.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>
测试功能
@Test
public void textSearchById(){
//第一步,获得SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserDao userDao = sqlSession.getMapper(UserDao.class);
user user = userDao.getUserById(1);
System.out.println(user);
}
finally {
sqlSession.close();
}
}
@Test
public void textInsert(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserDao userDao = sqlSession.getMapper(UserDao.class);
int text = userDao.insertUser(new user(4,"alice","890"));
sqlSession.commit();
if(text !=0)
System.out.print("插入成功!");
}
finally {
sqlSession.close();
}
}
@Test
public void textUpdate(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserDao userDao = sqlSession.getMapper(UserDao.class);
int text = userDao.updateUser(new user(4,"alice","999"));
sqlSession.commit();
if(text !=0)
System.out.print("修改成功!");
}
finally {
sqlSession.close();
}
}
@Test
public void textDelete(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
try {
UserDao userDao = sqlSession.getMapper(UserDao.class);
int text = userDao.deleteUser(4);
sqlSession.commit();
if(text !=0)
System.out.print("删除成功!");
}
finally {
sqlSession.close();
}
}
以上就是mybatis实现数据库增删改查的程序实现
总结
使用mybatis,避免了JDBC许多的重复代码,它通过SqlSessionFactoryBuilder创建了SessionFactory,SessionFactory实例对应了核心xml配置(配置中规定了数据库连接实例,以及运行环境等参数),之后实例SessionFactory工厂中,生产Session用于数据库连接池的连接,每一个连接都会动态的占用资源,所以使用后一定要close掉。