什么是MyBatis
封装了JDBC,是一个半成品软件,更加灵活。
ORM 框架
一个对象与一行数据一一对应。
把对象持久化到数据库中。
通过配置mybatis-config.xml核心文件
添加文件,配置MySQL的连接信息。
注册 Mapper.xml mapper:mapper.xm文件的位置。
Mapper.xml
namespace需要实现的接口全限定名
xml的映射文件,隐射到持久层的接口。
select的标签中的
- id是接口中的方法名
- resultType 返回的数据类型
- #{arg0} 表示第一个参数
编写文件步骤
- 1.获得读取MyBatis配置文件的流对象
- 2.构建SqlSession 连接对象的工厂
- 3.通过工厂获得连接对象
- 4.通过连接对象获得接口实现对象
- 5.调用接口中的方法
入门案例根据id查询
准备工具
-- 创建数据库
create table hui
(
id int auto_increment primary key,
name varchar(20) null,
sex varchar(20) null
);
-- 插入数据
insert into hui (name, sex) values ('小泽玛利亚','女');
insert into hui (name, sex) values ('波多野结衣','女');
insert into hui (name, sex) values ('苍井空','女');
insert into hui (name, sex) values ('武藤兰','女');
连接数据库配置文件db.properties
#db.properties
driver=com.mysql.cj.jdbc.Driver
# ssm 是你的数据库
url=jdbc:mysql://localhost:3306/ssm?characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai&rewriteBatchedStatements=true
username=root
password=123456
pom文件配置
<!--MyBatis核心依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!--MySql驱动依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<!-- 注解 -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.12</version>
</dependency>
创建 huiMapper接口
/**
* @author 二手Java程序员
* @since 2023/4/17 11:08
*/
public interface huiMapper {
int selechui(int index); // 方法名selecthui
}
创建 huiMapper.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 namespace="com.hui.mapper.huiMapper">
<!-- id 是你的实现方法 parameterType 是查询返回的类型 -->
<select id="selecthui" resultType="Hui">
select * from hui where id = #{id}
</select>
</mapper>
配置 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"/>
<typeAliases>
<!--定义类的别名-->
<typeAlias type="com.hui.userPojo.hui" alias="hui"/>
<!--自动扫描包,将原类名作为别名,扫描实体类-->
<package name="com.hui.userPojo"/>
</typeAliases>
<environments default="MySqlDB">
<environment id="MySqlDB">
<transactionManager type="JDBC"></transactionManager>
<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>
<!-- 扫描接口类 -->
<package name="com.hui.mapper"/>
</mappers>
</configuration>
封装工具类
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.InputStream;
/**
* @author 二手Java程序员
* @since 2023/4/17 16:08
*/
public class MyBatisUtils {
//获得SqlSession工厂
private static SqlSessionFactory factory;
//创建ThreadLocal绑定当前线程中的SqlSession对象
private static final ThreadLocal<SqlSession> tl = new ThreadLocal<SqlSession>();
static {
try {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(is);
} catch (Exception e) {
e.printStackTrace();
}
}
//获得连接(从tl中获得当前线程SqlSession)
public static SqlSession openSession(){
SqlSession session = tl.get();
if(session == null){
session = factory.openSession();
tl.set(session);
}
return session;
}
//释放连接(释放当前线程中的SqlSession)
public static void closeSession(){
SqlSession session = tl.get();
session.close();
tl.remove();
}
//提交事务(提交当前线程中的SqlSession所管理的事务)
public static void commit(){
SqlSession session = openSession();
session.commit();
closeSession();
}
//回滚事务(回滚当前线程中的SqlSession所管理的事务)
public static void rollback(){
SqlSession session = openSession();
session.rollback();
closeSession();
}
//获得接口实现类对象
public static <T extends Object> T getMapper(Class<T> clazz){
SqlSession session = openSession();
return session.getMapper(clazz);
}
}
创建测试类
/**
* @author 二手Java程序员
* @since 2023/4/17 22:08
*/
public class huiMapperTest {
@Test
public void selecthui() {
huiMapper mapper = MyBatisUtils.getMapper(huiMapper.class); // 引用工具类
Hui selecthui = mapper.selecthui(1); // 传入查询的id
System.out.println(selecthui);
}
}
实现CRUD 功能
create table t_users
(
id int auto_increment
primary key,
name varchar(50) null,
password varchar(50) null,
sex varchar(1) null,
birthday datetime null,
registTime datetime null
)
charset = utf8;
-- 插入的数据
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (6, 'admin', '123456', '男', '2021-07-29 10:42:42', null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (7, '貂蝉', '222', '女', '2022-07-07 09:57:51', '2022-07-07 09:57:51');
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (8, 'zs', '1', '男', '2021-07-29 10:45:47', '2023-04-15 20:18:08');
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (9, 'wjl', '123', null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (10, 'wsc', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (16, '张三', '123', null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (18, '鲁班7号', '222', '男', '2022-04-15 09:44:32', '2022-04-15 09:44:32');
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (19, '张三', '123', '男', null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (20, 'aaa', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (21, 'bbb', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (22, 'ccc', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (23, 'dddd', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (24, 'eeee', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (25, '11', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (26, '222', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (27, '333', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (28, '444', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (29, '555', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (30, '6666', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (31, '6666', null, null, null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (34, 'ww', '222', '女', '2022-04-13 09:52:24', '2022-04-13 09:52:24');
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (35, '昭君', '222', '女', '2022-07-07 09:59:13', '2022-07-07 09:59:13');
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (36, '昭君', '222', '女', '2022-07-07 10:21:11', '2022-07-07 10:21:11');
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (39, '苍井空', '123', '女', null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (40, '苍井空', '123', '女', null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (41, '波多野结衣', '123', '女', null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (42, '波多野结衣', '123', '女', null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (43, '波多野结衣', '123', '女', null, null);
INSERT INTO ssm.t_users (id, name, password, sex, birthday, registTime) VALUES (44, '波多野结衣', '123', '女', null, null);
创建实体类
/**
* @author 二手Java程序员
* @since 2023/4/15 15:57
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private Integer id;
private String name;
private String password;
private String sex;
private String birthday;
private String registTime;
}
创建UserMapper 接口
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 二手Java程序员
* @since 2023/4/15 19:25
*/
public interface UserMapper {
// 查 采用注解
User selectUserByIdAndPwd(@Param("id")Integer id,@Param("pwd")String pwd);
// 模糊查询
List<User> selectUsersByKeyword(@Param("keyword") String keyword);
// 删除操作
int deleteUser(int id);
// 修改操作 返回一个影响条数
int updateUser(User user);
// 添加操作
int insertUser(User user);
}
### 创建UserMapper.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">
<mapper namespace="com.hui.mapper.UserMapper">
<insert id="insertUser" parameterType="user"><!--插入-->
insert into t_users (name, password, sex) values (#{name},#{password},#{sex});
</insert>
<select id="selectUserByIdAndPwd" resultType="user">
SELECT * FROM t_users WHERE id = #{id} AND password = #{pwd} <!--arg0 arg1 arg2 ...-->
</select>
<select id="selectUsersByKeyword" resultType="user">
select * from t_users where name LIKE concat('%',#{keyword},'%')
</select>
<!-- parameterType="int" 是查询返回的类型 id="deleteUser"接口中的方法名 -->
<delete id="deleteUser" parameterType="int">
delete from t_users where id = #{id}
</delete>
<update id="updateUser" parameterType="user">
update t_users set name=#{name},password=#{password},sex=#{sex},birthday=#{birthday} where id = #{id}
</update>
</mapper>
import com.hui.utils.DateUtil;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
/**
* @author 二手Java程序员
* @since 2023/4/15 19:50
*/
public class UserMapperTest {
SqlSession sqlSession;
@Before
public void doBefore() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession(true);
}
@After
public void doAfter(){
sqlSession.close();
}
// @Before @After 使用的是未自定义工具的方法
@Test
public void text1(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectUserByIdAndPwd(8,"1");
System.out.println(user);
}
@Test
public void text2(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> list = mapper.selectUsersByKeyword("xxx");
System.out.println(list);
}
@Test
public void text3(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
int n = mapper.deleteUser(15);
System.out.println(n);
sqlSession.commit(); // 事务提交
}
@Test
public void text4(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setId(19);
user.setName("张三");
user.setPassword("123");
user.setSex("男");
int n = mapper.updateUser(user);
sqlSession.commit();
System.out.println(n);
}
@Test
public void text5(){
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setName("波多野结衣");
user.setPassword("123");
user.setSex("女");
String time = DateUtil.dateToStr(new Date(),"yyyy-MM-dd:hh:ss");
user.setBirthday(time);
int n = mapper.insertUser(user);
System.out.println(n);
}
}
日志信息
public class TestLog4J {
Logger logger = Logger.getLogger(this.getClass());
public void test() {
logger.debug("debug print");
logger.info("info print");
logger.warn("warn print");
logger.error("error print");
}
public static void main(String[] args) {
new TestLog4J().test();
}
}
细节注意
针对实体类的映射文件
select | 查询语句,可以自定义参数,返回结果集等 |
---|---|
insert | 插入语句,执行后返回一个整数,代表插入的条数 |
update | 更新语句,执行后返回一个整数,代表更新的条数 |
delete | 删除语句,执行后返回一个整数,代表删除的条数 |
sql | 允许定义一部分的 SQL,然后在各个地方引用它。例如,一张表列名,我们可以一次定义,在多个 SQL 语句中使用 |
resultMap | 用来描述数据库结果集与对象的对应关系,提供映射规则 |
cache | 配置给定命名空间的缓存 |
cache-ref | 其它命名空间缓存配置的引用 |
#{}与${}区别
#{}=?,在预编译时,相当于一个参数占位符“?”,用来补全预编译语句,能够防止注入式攻击。
${}=字符串拼接,表示内容的原样输出,相当于单纯的内容替换,拼接完成后才会对SQL进行编译、执行。