本文详细介绍了mybatis持久层框架学习的内容,包括Mybatis的基本概念、环境搭建与配置、CRUD操作、关联查询以及事务管理等。通过本文,你将全面掌握Mybatis的使用方法和技巧,提升数据库操作的灵活性和性能。
Mybatis持久层框架学习教程 Mybatis简介与安装配置Mybatis是什么
Mybatis是一个优秀的持久层框架,它支持定制化SQL查询,存储过程和高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJOs(Plain Old Java Objects,普通的Java对象)映射成数据库中的记录。
Mybatis的优势与应用场景
Mybatis具有以下优势:
- 灵活性:Mybatis的灵活性主要体现在SQL语句的灵活性上,它可以完全自定义SQL语句,从而可以根据需要进行优化。
- 性能:Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,从而显著减少了代码量,提升了应用的性能。
- 简洁性:Mybatis将接口和Java的POJOs映射成数据库中的记录,因此代码简洁,易于理解和维护。
- 可扩展性:Mybatis提供了一系列的插件机制,可以通过自定义插件来拦截Mybatis运行时的循环,以此来对Mybatis的功能进行扩展。
- 支持存储过程:Mybatis支持存储过程,提供了存储过程的支持。
Mybatis适用于以下场景:
- 需要自定义SQL语句:当业务逻辑复杂,需要自定义SQL语句时,可以使用Mybatis。
- 需要高性能:Mybatis可以避免编写大量的JDBC代码,减少代码量,提升应用性能。
- 需要简洁的代码:Mybatis提供了简洁的代码,易于理解和维护。
- 支持存储过程:当需要使用存储过程时,可以使用Mybatis。
Mybatis环境搭建与配置
Mybatis环境搭建与配置步骤如下:
-
下载Mybatis:首先,从Mybatis官网下载Mybatis的最新版本的jar包,将其添加到项目的ClassPath路径下。也可以通过Maven或Gradle等构建工具自动管理依赖。
-
创建数据库和表:创建一个数据库,并在其中创建一张表,用于测试。
-
创建实体类:创建一个与表对应的实体类,例如:
public class User { private int id; private String username; private String password; private String email; private String phone; // 省略getter和setter方法 }
-
创建XML映射文件:创建一个XML映射文件,用于定义表与实体类的映射关系,例如:
<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="com.example.entity.User"> SELECT id, username, password, email, phone FROM user WHERE id = #{id} </select> <insert id="insertUser"> INSERT INTO user(username, password, email, phone) VALUES (#{username}, #{password}, #{email}, #{phone}) </insert> <update id="updateUser"> UPDATE user SET username = #{username}, password = #{password}, email = #{email}, phone = #{phone} WHERE id = #{id} </update> <delete id="deleteUser"> DELETE FROM user WHERE id = #{id} </delete> </mapper>
-
创建SqlSessionFactory:创建一个SqlSessionFactory,用于生成SqlSession。SqlSessionFactory是线程不安全的,因此通常使用一个SqlSessionFactory的单例。
String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
-
创建SqlSession:通过SqlSessionFactory生成SqlSession,用于执行各种数据库操作。
SqlSession session = sqlSessionFactory.openSession();
-
编写Mapper接口:创建一个Mapper接口,用于定义SQL语句。Mapper接口中的方法名必须与XML映射文件中的id值对应。
public interface UserMapper { User selectUser(int id); void insertUser(User user); void updateUser(User user); void deleteUser(int id); }
-
配置mybatis-config.xml:配置mybatis的全局配置文件,如数据源、事务管理器等。
<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/test" /> <property name="username" value="root" /> <property name="password" value="password" /> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml" /> </mappers> </configuration>
-
执行SQL语句:通过SqlSession执行SQL语句,例如:
UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUser(1); mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901")); mapper.updateUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901")); mapper.deleteUser(1); session.commit(); session.close();
SqlSessionFactory与SqlSession
SqlSessionFactory是一个工厂类,用于创建SqlSession对象。SqlSession是Mybatis中最重要的接口之一,它代表了和数据库交互的会话,能够执行预定义的SQL语句,并返回映射的数据。
创建SqlSessionFactory的代码如下:
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
通过SqlSessionFactory创建SqlSession的代码如下:
SqlSession session = sqlSessionFactory.openSession();
Mapper接口与XML映射文件
Mapper接口是一个普通的Java接口,用于定义SQL语句。Mapper接口中的方法名必须与XML映射文件中的id值对应。
例如,创建一个Mapper接口:
public interface UserMapper {
User selectUser(int id);
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}
创建一个XML映射文件,用于定义表与实体类的映射关系:
<configuration>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
Pojo与Sql语句绑定
Pojo是普通的Java对象,用于表示数据库中的记录。SQL语句用于定义数据库操作,例如查询、插入、更新和删除。
例如,创建一个Pojo:
public class User {
private int id;
private String username;
private String password;
private String email;
private String phone;
// 省略getter和setter方法
}
创建一个SQL语句,用于查询用户信息:
<select id="selectUser" resultType="com.example.entity.User">
SELECT id, username, password, email, phone
FROM user
WHERE id = #{id}
</select>
参数和结果映射
参数和结果映射用于定义SQL语句中的参数和结果类型。
例如,创建一个SQL语句,用于插入用户信息:
<insert id="insertUser">
INSERT INTO user(username, password, email, phone)
VALUES (#{username}, #{password}, #{email}, #{phone})
</insert>
在上述SQL语句中,#{username}
表示一个参数,它将被替换成实际的值。此外,还可以使用@Param
注解为参数指定别名,例如:
public interface UserMapper {
void insertUser(@Param("username") String username, @Param("password") String password, @Param("email") String email, @Param("phone") String phone);
}
在XML映射文件中,可以使用resultMap
标签定义结果映射,如下所示:
<resultMap id="userResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
</resultMap>
在上述代码中,id
表示主键,result
表示普通字段。
基本的增删改查语句
Mybatis支持基本的增删改查操作,这些操作可以通过Mapper接口和XML映射文件实现。
例如,创建一个Mapper接口,用于定义SQL语句:
public interface UserMapper {
User selectUser(int id);
void insertUser(User user);
void updateUser(User user);
void deleteUser(int id);
}
创建一个XML映射文件,用于定义表与实体类的映射关系:
<configuration>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
例如,定义一个查询用户信息的SQL语句:
<select id="selectUser" resultType="com.example.entity.User">
SELECT id, username, password, email, phone
FROM user
WHERE id = #{id}
</select>
定义一个插入用户信息的SQL语句:
<insert id="insertUser">
INSERT INTO user(username, password, email, phone)
VALUES (#{username}, #{password}, #{email}, #{phone})
</insert>
定义一个更新用户信息的SQL语句:
<update id="updateUser">
UPDATE user
SET username = #{username}, password = #{password}, email = #{email}, phone = #{phone}
WHERE id = #{id}
</update>
定义一个删除用户信息的SQL语句:
<delete id="deleteUser">
DELETE FROM user
WHERE id = #{id}
</delete>
使用Mapper接口执行CRUD操作
使用Mapper接口执行CRUD操作的代码如下:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
mapper.updateUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
mapper.deleteUser(1);
session.commit();
session.close();
动态SQL的使用
动态SQL用于根据不同的条件生成不同的SQL语句。Mybatis提供了动态SQL标签,如if
、choose
、when
、otherwise
、trim
、where
、set
、foreach
等。
例如,创建一个Mapper接口,用于定义SQL语句:
public interface UserMapper {
List<User> selectUsers(Map<String, Object> params);
}
创建一个XML映射文件,用于定义表与实体类的映射关系:
<configuration>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
例如,定义一个查询用户信息的SQL语句,使用动态SQL:
<select id="selectUsers" resultType="com.example.entity.User">
SELECT id, username, password, email, phone
FROM user
<where>
<if test="username != null">
username = #{username}
</if>
<if test="email != null">
AND email = #{email}
</if>
</where>
</select>
使用动态SQL的代码如下:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
Map<String, Object> params = new HashMap<>();
params.put("username", "zhangsan");
params.put("email", "zhangsan@163.com");
List<User> users = mapper.selectUsers(params);
session.commit();
session.close();
Mybatis的关联查询
一对一关联查询
一对一关联查询用于查询两张表中的数据,其中两张表之间存在一对一的关系。
例如,创建两个实体类,分别为User和Address,User和Address之间存在一对一的关系:
public class User {
private int id;
private String username;
private String password;
private String email;
private String phone;
private Address address;
// 省略getter和setter方法
}
public class Address {
private int id;
private String street;
private String city;
private String province;
private User user;
// 省略getter和setter方法
}
创建一个Mapper接口,用于定义SQL语句:
public interface UserMapper {
User selectUser(int id);
}
创建一个XML映射文件,用于定义表与实体类的映射关系:
<configuration>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
例如,定义一个查询用户信息的SQL语句,使用一对一关联查询:
<select id="selectUser" resultType="com.example.entity.User">
SELECT u.id, u.username, u.password, u.email, u.phone, a.id as address_id, a.street, a.city, a.province
FROM user u
LEFT JOIN address a ON u.id = a.user_id
WHERE u.id = #{id}
</select>
在上述代码中,定义了一个resultMap
标签,用于定义User和Address的关系:
<resultMap id="userResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
<association property="address" javaType="com.example.entity.Address">
<id column="address_id" property="id"/>
<result column="street" property="street"/>
<result column="city" property="city"/>
<result column="province" property="province"/>
</association>
</resultMap>
使用一对一关联查询的代码如下:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.commit();
session.close();
一对多关联查询
一对多关联查询用于查询两张表中的数据,其中两张表之间存在一对多的关系。
例如,创建两个实体类,分别为User和Order,User和Order之间存在一对多的关系:
public class User {
private int id;
private String username;
private String password;
private String email;
private String phone;
private List<Order> orders;
// 省略getter和setter方法
}
public class Order {
private int id;
private String product;
private String quantity;
private User user;
// 省略getter和setter方法
}
创建一个Mapper接口,用于定义SQL语句:
public interface UserMapper {
User selectUser(int id);
}
创建一个XML映射文件,用于定义表与实体类的映射关系:
<configuration>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
例如,定义一个查询用户信息的SQL语句,使用一对多关联查询:
<select id="selectUser" resultType="com.example.entity.User">
SELECT u.id, u.username, u.password, u.email, u.phone, o.id as order_id, o.product, o.quantity
FROM user u
LEFT JOIN order o ON u.id = o.user_id
WHERE u.id = #{id}
</select>
在上述代码中,定义了一个resultMap
标签,用于定义User和Order的关系:
<resultMap id="userResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
<collection property="orders" ofType="com.example.entity.Order">
<id column="order_id" property="id"/>
<result column="product" property="product"/>
<result column="quantity" property="quantity"/>
</collection>
</resultMap>
使用一对多关联查询的代码如下:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.commit();
session.close();
多对多关联查询
多对多关联查询用于查询三张表中的数据,其中三张表之间存在多对多的关系。
例如,创建三个实体类,分别为User、Product和Order,User和Product之间存在多对多的关系:
public class User {
private int id;
private String username;
private String password;
private String email;
private String phone;
private List<Order> orders;
// 省略getter和setter方法
}
public class Product {
private int id;
private String name;
private String price;
private List<Order> orders;
// 省略getter和setter方法
}
public class Order {
private int id;
private User user;
private Product product;
// 省略getter和setter方法
}
创建一个Mapper接口,用于定义SQL语句:
public interface UserMapper {
User selectUser(int id);
}
创建一个XML映射文件,用于定义表与实体类的映射关系:
<configuration>
<mappers>
<mapper resource="com/example/mapper/UserMapper.xml" />
</mappers>
</configuration>
例如,定义一个查询用户信息的SQL语句,使用多对多关联查询:
<select id="selectUser" resultType="com.example.entity.User">
SELECT u.id, u.username, u.password, u.email, u.phone, o.id as order_id, p.id as product_id, p.name, p.price
FROM user u
LEFT JOIN order o ON u.id = o.user_id
LEFT JOIN product p ON o.product_id = p.id
WHERE u.id = #{id}
</select>
在上述代码中,定义了一个resultMap
标签,用于定义User、Product和Order的关系:
<resultMap id="userResultMap" type="com.example.entity.User">
<id column="id" property="id"/>
<result column="username" property="username"/>
<result column="password" property="password"/>
<result column="email" property="email"/>
<result column="phone" property="phone"/>
<collection property="orders" ofType="com.example.entity.Order">
<id column="order_id" property="id"/>
<association property="product" javaType="com.example.entity.Product">
<id column="product_id" property="id"/>
<result column="name" property="name"/>
<result column="price" property="price"/>
</association>
</collection>
</resultMap>
使用多对多关联查询的代码如下:
SqlSession session = sqlSessionFactory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
session.commit();
session.close();
Mybatis的事务管理
事务的基本概念
事务是数据库中的一种操作,它包含了一组数据库操作,这些操作要么全部成功,要么全部失败,不存在只完成一部分的操作。
Mybatis中事务的使用
Mybatis中事务的使用包括以下几个步骤:
-
开启事务:通过SqlSession的
openSession()
方法创建SqlSession对象,将参数设置为true,开启事务。SqlSession session = sqlSessionFactory.openSession(true);
-
执行数据库操作:通过SqlSession执行数据库操作。
UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUser(1); mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901"));
-
提交事务:通过SqlSession的
commit()
方法提交事务。session.commit();
-
关闭资源:通过SqlSession的
close()
方法关闭SqlSession对象,释放资源。session.close();
事务的传播特性
事务的传播特性用于定义事务的传播行为,例如,是否需要创建新的事务,是否需要加入到现有事务中等。
Mybatis支持以下几种事务的传播特性:
- PROPAGATION_REQUIRED:如果当前没有事务,就创建一个新的事务;如果当前存在事务,就加入到当前事务中。
- PROPAGATION_SUPPORTS:如果当前存在事务,就加入到当前事务中;如果当前不存在事务,就以非事务的方式继续运行。
- PROPAGATION_MANDATORY:如果当前存在事务,就加入到当前事务中;如果当前不存在事务,就抛出异常。
- PROPAGATION_REQUIRES_NEW:创建一个新的事务,如果当前存在事务,就暂停当前事务。
- PROPAGATION_NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,就暂停当前事务。
- PROPAGATION_NEVER:以非事务的方式运行,如果当前存在事务,就抛出异常。
- PROPAGATION_NESTED:如果当前存在事务,则在嵌套事务内运行;如果当前没有事务,则行为与
PROPAGATION_REQUIRED
相同。
例如,在Mapper接口中使用事务的传播特性:
public interface UserMapper {
@Transactional(propagation = Propagation.REQUIRED)
User selectUser(int id);
}
Mybatis的日志与调试
Mybatis的日志插件
Mybatis提供了多种日志插件,例如SLF4J、Log4j、JdkLogging、CommonsLogging等。
例如,使用Log4j作为日志插件:
<configuration>
<settings>
<setting name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl" />
</settings>
</configuration>
Mybatis的配置与调试技巧
Mybatis的配置与调试技巧包括以下几个方面:
-
配置日志级别:在配置文件中设置日志级别,例如:
<configuration> <settings> <setting name="logImpl" value="org.apache.ibatis.logging.log4j.Log4jImpl" /> </settings> </configuration>
-
开启调试模式:在配置文件中开启调试模式,例如:
<configuration> <settings> <setting name="configurationFactory" value="org.apache.ibatis.session.ConfigurationFactory" /> </settings> </configuration>
-
使用事务管理:使用事务管理,保证数据库操作的完整性,例如:
SqlSession session = sqlSessionFactory.openSession(true); UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUser(1); mapper.insertUser(new User(1, "zhangsan", "123456", "zhangsan@163.com", "12345678901")); session.commit(); session.close();
-
使用动态SQL:使用动态SQL,根据不同的条件生成不同的SQL语句,例如:
<select id="selectUsers" resultType="com.example.entity.User"> SELECT id, username, password, email, phone FROM user <where> <if test="username != null"> username = #{username} </if> <if test="email != null"> AND email = #{email} </if> </where> </select>
-
使用关联查询:使用关联查询,查询多张表中的数据,例如:
<select id="selectUser" resultType="com.example.entity.User"> SELECT u.id, u.username, u.password, u.email, u.phone, a.id as address_id, a.street, a.city, a.province FROM user u LEFT JOIN address a ON u.id = a.user_id WHERE u.id = #{id} </select>
-
使用事务传播特性:使用事务传播特性,定义事务的传播行为,例如:
@Transactional(propagation = Propagation.REQUIRED) User selectUser(int id);
- 使用Mybatis的调试工具:使用Mybatis的调试工具,例如mybatis-spring-integration,它提供了Mybatis与Spring的集成,方便调试Mybatis。
通过上述配置与调试技巧,可以有效地调试Mybatis。
总结Mybatis是一个优秀的持久层框架,它支持定制化SQL查询,存储过程和高级映射。通过本文的介绍,您应已经了解Mybatis的基本概念、事务管理、日志与调试等内容。希望本文能够帮助您更好地理解和使用Mybatis。更多详细的使用方法和技巧,您可以参考Mybatis的官方文档,或在Moo课网上学习更多相关课程。
共同学习,写下你的评论
评论加载中...
作者其他优质文章