MyBatis 是一个优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解用于配置和原始映射,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
1.配置MyBatis
- 创建
mybatis-config.xml
文件,这是 MyBatis 的主配置文件,用于配置数据源、事务管理器、SQL 映射等。
<?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>
<settings>
<!--在控制台显示SQL语句-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
<!--开启全局驼峰命名映射-->
<!-- <setting name="mapUnderscoreToCamelCase" value="true"/>-->
</settings>
<!--
typeAliases给类名起别名
typeAlias 给单个类配置别名,太麻烦了,每一个新增的类都得配置,不方便
type:原本的包名+类名
alias:起的别名
-->
<typeAliases>
<!-- <typeAlias type="pojo.User" alias="User"/>-->
<!-- <typeAlias type="pojo.Emp" alias="Emp"/>-->
<package name="pojo"/>
</typeAliases>
<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/db1?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- <mapper resource="UserMapper.xml"/>-->
</mappers>
</configuration>
2.建表,定义实体类和接口
以一个简单实验为例:
2.1.建表
建表代码如下:
CREATE TABLE USER (
id INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(20) NOT NULL,
birthday DATE,
sex CHAR(1) DEFAULT '男',
address VARCHAR(50)
);
INSERT INTO USER VALUES (NULL, '孙悟空','1980-10-24','男','花果山水帘洞');
INSERT INTO USER VALUES (NULL, '白骨精','1992-11-12','女','白虎岭白骨洞');
INSERT INTO USER VALUES (NULL, '沙悟净','1983-05-20','男','流沙河');
INSERT INTO USER VALUES (NULL, '蜘蛛精','1995-03-22','女','盤丝洞');
2.2.创建User类
代码如下:
// 封装User表的数据的实体类
public class User {
private Integer id;
private String username;
private Date birthday; //java.sql.Date;
private String sex;
private String address;
public User() {
}
public User(Integer id, String username, Date birthday, String sex, String address) {
this.id = id;
this.username = username;
this.birthday = birthday;
this.sex = sex;
this.address = address;
}
/**
* 获取
* @return id
*/
public Integer getId() {
return id;
}
/**
* 设置
* @param id
*/
public void setId(Integer id) {
this.id = id;
}
/**
* 获取
* @return username
*/
public String getUsername() {
return username;
}
/**
* 设置
* @param username
*/
public void setUsername(String username) {
this.username = username;
}
/**
* 获取
* @return birthday
*/
public Date getBirthday() {
return birthday;
}
/**
* 设置
* @param birthday
*/
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
/**
* 获取
* @return sex
*/
public String getSex() {
return sex;
}
/**
* 设置
* @param sex
*/
public void setSex(String sex) {
this.sex = sex;
}
/**
* 获取
* @return address
*/
public String getAddress() {
return address;
}
/**
* 设置
* @param address
*/
public void setAddress(String address) {
this.address = address;
}
public String toString() {
return "User{id = " + id + ", username = " + username + ", birthday = " + birthday + ", sex = " + sex + ", address = " + address + "}";
}
}
2.3.创建UserMapper接口
代码如下:
/*
* XxxMapper就是对应Xxx表的数据的增删改查操作
*
* */
public interface UserMapper {
// 1.查询User表的所有数据
List<User> selectAll();
// 2.根据id查询用户信息
User selectById(int id);
// 3.根据Id删除用户
void deleteById(int id);
// 4.修改用户数据
void update(User user);
// 5.添加用户数据
void add(User user);
注意事项:在编写delete语句时不要把delete语句写在select标签之中,这样结果虽然能成功加载出来,但是会导致没有对事务做检查
2.4.编写SQL映射文件UserMapper.xml
mapper根标签,namespace写上对应的是哪一个接口的映射关系
select标签:专门对应查询方法的
id:标记唯一的方法名
resultType:返回结果对象,如果是集合如List,不用写集合,写里面的对象
包名+类名
2.4.1查询User表所有数据:
<select id="selectAll" resultType="User">
select * from user;
</select>
2.4.2根据id查询用户信息:
<select id="selectById" resultType="User">
select * from user where id =#{id};
</select>
注意事项:
在mapper.xml的标签里注释代码,不要用快捷键生成 #{变量} select * from user where id = ?;?表示占位符,是预编译的效果不会有SQL注入问题 ${变量} select * from user where id = 1;直接拼接字符串存在SQL注入问题 resultType 封装的结果对象,如果返回需要集合,可以直接写对象 parameterType 表示参数类型,基本上不写 特殊的字符需要被处理 转义的字符 CD转义符
2.4.3根据id删除指定用户:
<delete id="deleteById">
delete from user where id = #{id};
</delete>
2.4.4修改用户信息:
<update id="update">
update user set username=#{username},birthday=#{birthday},
sex=#{sex},address=#{address} where id =#{id};
</update>
注意事项:
user作为一个对象,mybatis可以解析这个对象,直接用里面的成员变量
2.4.5添加用户信息:
<insert id="add" useGeneratedKeys="true" keyProperty="id">
insert into user values (null,#{username},#{birthday},#{sex},#{address});
</insert>
注意事项:
通常在添加用户信息时都需要考虑数据库中对应数据的主键自增问题,例如此例中的id,因此在编写insert语句时使用 useGeneratedKeys="true" 表示要数据库返回的主键值,keyProperty="id"把获取到的主键值放回到原来的对象的id属性里面。
3.测试代码
public class TestMyBatis {
@Test
public void test01() throws IOException {
// 测试一下MyBatis框架的搭建情况
// 1.标记mybatis的配置环境
String resource = "mybatis-config.xml";
// 2.加载配置环境的信息
InputStream inputStream = Resources.getResourceAsStream(resource);
// 3.根据配置信息,生成sqlSessionFactory对象,相当于连接池
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
// 4.从连接池获取连接
SqlSession sqlSession = sqlSessionFactory.openSession();
// 5.获取执行sql语句的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 6.调用方法,执行SQL语句
List<User> userList = userMapper.selectAll();
// 7.释放资源
sqlSession.close();
userList.forEach(System.out::println);
}
@Test
public void test02()throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.selectById(4);
System.out.println("user= " +user);
sqlSession.close();
}
/*
注意:在mybatis框架中,增删改是不会自动提交事务的
*/
@Test
public void test03()throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
// 4.从连接池获取连接
//4.1自动提交事务
//可以设置自动提交事务 openSession(true);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 5.获取执行sql语句的对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 6.调用方法,执行SQL语句
userMapper.deleteById(3);
//6.1手动提交事务 需要在执行sql之后
// sqlSession.commit();
sqlSession.close();
}
/*
修改
*/
@Test
public void test04()throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建对象
User user = new User(1, "六耳猕猴",
Date.valueOf("1980-10-24"), "男", "不详");
userMapper.update(user);
//提交事务
sqlSession.commit();
sqlSession.close();
}
@Test
public void test05()throws IOException{
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new
SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = new User(1, "唐僧",
Date.valueOf("1999-01-24"), "男", "大唐");
userMapper.add(user);
//获取返回自增的主键值
System.out.println("id ="+ user.getId());
//提交事务
sqlSession.commit();
sqlSession.close();
}
}
总结:
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集,通过XML或注释的方式,可以很容易的编写SQL语句和映射关系。但也存在一些缺点,比如事务管理和缓存等需要自己额外配置和实现。