第一个Mybatis程序
思路:搭建环境-->导入Mybatis-->编写代码-->测试!
数据库和maven
搭建数据库
CREATE DATABASE `mybatis`;
use `mybatis`;
CREATE TABLE `user`(
`id` INT(20) not null PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` (`id`,`name`,`pwd`) VALUES
(1,'小姜','123456'),
(2,'张三','123456'),
(3,'李四','123890')
新建项目
- 新建一个普通的maven项目
- 删除src目录
- 导入maven依赖
<?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.jiang</groupId>
<artifactId>MyBatisStudy</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>mybatis-01-hello</module>
</modules>
<dependencies>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.47</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
</project>
<!--在build中配置resources,来防止我们资源导出失败的问题-->
<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.properties</include>
<include>**/*.xml</include>
</includes>
<filtering>true</filtering>
</resource>
</resources>
</build>
基础环境
实体类User
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 + '\'' +
'}';
}
}
Dao接口
package com.jiang.dao;
import com.jiang.pojo.User;
import java.util.List;
/**
* @Title:
* @author: JiangPeng
*/
public interface UserDao {
//获取所有用户
public List<User> getUserList();
//根据id查找用户
public User getUserById(Integer id);
}
MyBatis操作
全局配置文件
指导MyBatis如何正确的运行,比如连接时候指向那个数据库
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--configuration核心配置文件-->
<configuration>
<!--environments配置环境组-->
<!--default默认环境-->
<environments default="development">
<!--environment单个环境-->
<environment id="development">
<!--transactionManager配置事务管理器-->
<transactionManager type="JDBC"/>
<!--配置连接池-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true"/>
<!-- &characterEncoding=UFT-8
我本机中不需要,如果报Utf-8的错误的话自行添加到后面-->
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
</configuration>
- configuration:核心配置文件
- environments:配置环境组;default 设置默认的环境
- environment:单个环境;id是环境名
- transactionManager :配置事务管理器
- dataSource:配置数据库连接池
- useSSL=true&useUnicode=true&characterEncoding=UFT-8:设置时区设置编码,复制就行
- property:设置对应的 JDBC连接属性
SQL映射文件
编写每一个方法都如何向数据库发送sql语句,如何执行等,相当于接口的实现类
UserDaoMapper.xml
<?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.jiang.dao.UserDao">
<!--select查询语句-->
<select id="getUserList" resultType="com.jiang.pojo.User">
/*定义sql*/
select * from user
</select>
<select id="getUserById" resultType="com.jiang.pojo.User">
select * from user where id = #{id}
</select>
</mapper>
- namespace:名称空间,写接口的全类名,相当于告诉MyBatis这个配置文件是实现那个接口的
- select对应的就是查询操作
- id是接口的方法名 相当于这个配置是对于某个方法的实现
- resultType : 指定方法运行后的返回值类型 ( 如果是查询操作必须指定 )
- #{属性名} : 代表取出传递过来的某个参数的值
全局注册Mapper
我们编写的 mapper也就是dao接口的实现文件 , MyBatis是默认不知道的 , 需要在全局配置文件中注册
在mybatis-config.xml 配置文件中
<mappers>
<mapper resource="UserDaoMapper.xml"></mapper>
</mappers>
测试
public void getUserList() throws IOException {
//根据全局配置文件创建出一个SqlSessionFactory
//SqlSessionFactory:是SqlSession工厂,负责创建SqlSession
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过sqlSessionFactory.openSession()获取和数据库的一次会话
//底层就是getConnection拿到一条连接
SqlSession sqlSession = sqlSessionFactory.openSession();
//使用SqlSession操作数据库,获取到Dao接口的实现
UserDao userDao = sqlSession.getMapper(UserDao.class);
//直接调用写的方法
List<User> userList = userDao.getUserList();
for (User user:userList) {
System.out.println(user);
}
//每一次获取sqlSession相当于一条连接,资源宝贵,用完关闭
sqlSession.close();
}
流程分析
- String resource 就是获取你的全局配置文件
- 通过ibatis下的Resources资源中的getResourceAsStream方法把你的全局配置文件变成输入流inputStream
- SqlSessionFactoryBuilder 是SqlSession工厂建造者,负责创建SqlSessionFactory , 通过该类下的build方法返回值是SqlSessionFactory 也就将我们的输入流变成 SqlSessionFactory
- 拿到SqlSessionFactory 可以调用其openSession方法得到SqlSession
- SqlSession : sql会话 , 相当于每一次与数据库连接时候的connection
- 通过sqlSession的getMapper会获取到Dao接口的实现
- 我们在UserDaoMapper.xml中已经通过namespace绑定了对应的接口
- 所以我们可以通过获取的接口对象 userDao直接调用我们在Mapper中写的方法
- 每一次获取sqlSession相当于一条连接,资源宝贵,用完关闭
CRUD
抽取工具类MyBatisUtils
因为我们获取数据库连接的操作都是重复的,所以我们可以直接抽取操作写为工具类
方便我们快速使用
package com.jiang.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;
/**
* @Title:
* @author: JiangPeng
*/
public class MyBatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static {
try{
//使用mybatis第一步、获取sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}catch(IOException e) {
e.printStackTrace();
}
}
//既然有了 SqlSessionFactory,顾名思义,我们就可以从中获得 SqlSession 的实例了。
// SqlSession 完全包含了面向数据库执行 SQL 命令所需的所有方法。
// 你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
测试使用
@Test
public void getUser() throws IOException {
//首先通过工具类获取一条session连接
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//通过这条连接获取mapper
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userList = mapper.getUserList();
System.out.println(userList);
}
环境
UserDao
package com.jiang.dao;
import com.jiang.pojo.User;
import java.util.List;
/**
* @Title:
* @author: JiangPeng
*/
public interface UserDao {
//获取所有用户
public List<User> getUserList();
//根据id查找用户
public User getUserById(Integer id);
//更改用户
public int updateUser(User user);
//删除用户
public int deleteUser(Integer id);
//添加用户
public int addUser(User user);
}
UserDaoMapper
<?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.jiang.dao.UserDao">
<!--
增删改不用写返回值类型resultType;增删改是返回影响多少行
mybatis自动判断,如果是boolean(影响0行自动封装false,否则true)
-->
<select id="getUserList" resultType="com.jiang.pojo.User">
select * from user
</select>
<select id="getUserById" resultType="com.jiang.pojo.User">
select * from user where id = #{id}
</select>
<update id="updateUser">
update user set name = #{name},pwd = #{pwd} where id = #{id}
</update>
<delete id="deleteUser">
delete from user where id = #{id}
</delete>
<insert id="addUser">
insert into user(name,pwd) value (#{name},#{pwd})
</insert>
</mapper>
查询select
@Test
public void getUser() throws IOException {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
List<User> userList = mapper.getUserList();
System.out.println(userList);
}
更新update
public void updateUser() throws IOException {
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
int i = mapper.updateUser(new User(1, "PWP", "jiang2020"));
System.out.println(i);
sqlSession.commit();
}
注意:更新、删除、添加一定最后要commit,否则没有效果
删除delete
@Test
public void deleteUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
UserDao mapper = sqlSession.getMapper(UserDao.class);
mapper.deleteUser(6);
sqlSession.commit();
}
添加add
@Test
public void addUser(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
try {
UserDao mapper = sqlSession.getMapper(UserDao.class);
int i = mapper.addUser(new User("Nginx", "abc123"));
if(i>0){
System.out.println("添加成功");
}else{
System.out.println("添加失败请检查后重试");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.commit();
sqlSession.close();
}
}
完整的操作,应该try...catch一下
几个注意的地方
commit
增删改一定要commit、因为mybatis没有自动提交
当然你也可以在工具类中设置自动提交
package com.jiang.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;
/**
* @Title:
* @author: JiangPeng
*/
public class MyBatisUtils {
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();
}
}
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
在MyBatisUtils工具类中的getSqlSession方法中,最后是返回 sqlSessionFactory.openSession
我们点进SqlSessionFactory源码中
public interface SqlSessionFactory {
SqlSession openSession();
SqlSession openSession(boolean autoCommit);
SqlSession openSession(Connection connection);
SqlSession openSession(TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType);
SqlSession openSession(ExecutorType execType, boolean autoCommit);
SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
SqlSession openSession(ExecutorType execType, Connection connection);
Configuration getConfiguration();
}
我们可以看到在第二行 有关于autoCommit的设置,所以我们可以将工具类中的openSession值设置为true
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession(true);
}
这样以后就不需要我们自动提交了
写参数值类型
增删改不用写返回值类型resultType;增删改是返回影响多少行
mybatis自动判断,如果是boolean(影响0行自动封装false,否则true)
关于自增id问题
比如你的自增id本来是 1 2 3 4 5
但是你把第5个删了以后,你接下来的参数值增加会是 1 2 3 4 6 7
这时候你需要在数据库命令行中使用该命令
ALTER TABLE table_name AUTO_INCREMENT = 1;
比如我这里就是
ALTER TABLE user AUTO_INCREMENT = 1;