Mybatis持久层框架学习入门介绍了Mybatis的基本概念和环境搭建,包括下载和引入Mybatis,配置数据库连接和核心设置。文章还详细讲解了Mybatis的核心概念、配置文件、SQL语句执行以及高级特性,帮助读者全面掌握Mybatis的使用方法。
MyBatis 是一个优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以通过 XML 配置文件或注解来配置 SQL 映射文件。MyBatis 从接口中知道要找的 SQL 语句,从结果集中取出符合类型的结果集对象,映射它们,返回给调用者。
首先,需要下载 MyBatis 的 jar 包。可以通过 Maven 或手动下载 jar 包进行引入。
通过 Maven 引入 Mybatis
在项目的 pom.xml
文件中添加以下依赖:
<dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.6</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.22</version> </dependency> <dependency> <groupId>org.apache.commons</groupId> <artifactId>commons-dbcp2</artifactId> <version>2.7.0</version> </dependency> </dependencies>
手动下载 jar 包
手动下载 MyBatis 和数据库驱动的 jar 包,并将其添加到项目的类路径中。
在项目中创建一个配置文件 mybatis-config.xml
,用于配置 MyBatis 的核心设置。
<?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/mytest"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
创建一个简单的 Java 工程来演示 Mybatis 的基本用法。
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; public class MyBatisExample { public static void main(String[] args) throws Exception { // 读取配置文件 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); // 创建 SqlSession try (SqlSession session = sqlSessionFactory.openSession()) { // 获取用户映射器 UserMapper mapper = session.getMapper(UserMapper.class); // 查询用户 User user = mapper.selectUserById(1); System.out.println(user.getName()); // 更新用户信息 User userToUpdate = new User(); userToUpdate.setId(1); userToUpdate.setName("UpdatedName"); userToUpdate.setPassword("NewPassword"); session.update("com.example.mapper.UserMapper.updateUser", userToUpdate); session.commit(); } } }
SqlSessionFactory
是 MyBatis 中最核心的接口之一,它是线程不安全的。SqlSessionFactory
的实例通常由 SqlSessionFactoryBuilder
创建,它是一个线程安全的类,用于创建 SqlSessionFactory
的实例。
import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; public class SqlSessionFactoryExample { public static void main(String[] args) throws Exception { // 读取配置文件 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } }
SqlSession
是 MyBatis 中另一个非常重要的接口,它是一个线程不安全的接口,提供了执行 SQL 语句的手段,可以用来执行存储过程调用和查询,同时也可以用于管理事务。
import org.apache.ibatis.session.SqlSession; public class SqlSessionExample { public static void main(String[] args) throws Exception { // 创建 SqlSession SqlSessionFactory sqlSessionFactory = SqlSessionFactoryExample.main(args); try (SqlSession session = sqlSessionFactory.openSession()) { // 执行 SQL 语句 UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user.getName()); } } }
mybatis-config.xml
是 MyBatis 的主配置文件,用于配置数据库连接、映射文件、类型处理器等。
<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/mytest"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
typeAliases
元素用于为 Java 类指定一个简短的别名,以便在配置文件中使用。
<typeAliases> <typeAlias alias="User" type="com.example.model.User"/> </typeAliases>
mappers
元素用于指定全部映射文件的位置,可以使用 mapper
子元素来指定单个文件的位置。
<mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers>
MyBatis 通过执行 SQL 语句与数据库进行交互。主要有 SELECT、INSERT、UPDATE、DELETE 四种基本操作。
<select id="selectUserById" resultType="User"> SELECT id, name, password FROM users WHERE id = #{id} </select>
<insert id="insertUser" parameterType="User"> INSERT INTO users (id, name, password) VALUES (#{id}, #{name}, #{password}) </insert>
<update id="updateUser" parameterType="User"> UPDATE users SET name = #{name}, password = #{password} WHERE id = #{id} </update>
<delete id="deleteUserById" parameterType="int"> DELETE FROM users WHERE id = #{id} </delete>
MyBatis 的 Mapper 接口简化了数据库操作,将 SQL 语句映射到 Java 接口的方法上。
public interface UserMapper { User selectUserById(int id); void insertUser(User user); void updateUser(User user); void deleteUserById(int id); }
MyBatis 支持多种参数类型,如基本类型、复杂对象、List 和 Map 等。
<select id="selectUserById" resultType="User"> SELECT id, name, password FROM users WHERE id = #{id} </select>
<insert id="insertUser" parameterType="User"> INSERT INTO users (id, name, password) VALUES (#{id}, #{name}, #{password}) </insert>
<insert id="insertUsers" parameterType="List"> INSERT INTO users (id, name, password) VALUES <foreach item="item" index="index" collection="list" separator=","> (#{item.id}, #{item.name}, #{item.password}) </foreach> </insert>
MyBatis 支持多种结果集映射方式,包括一对一、一对多、多对多等复杂映射关系。
一对一映射通常用于关联表的数据映射。例如,用户表和用户详细信息表可以一对一关联。
<select id="selectUserWithDetails" resultType="UserWithDetails"> SELECT u.id, u.name, u.password, d.detail, d.remark FROM users u LEFT JOIN user_details d ON u.id = d.user_id WHERE u.id = #{userId} </select>
一对多映射通常用于关联多个子表的数据映射。例如,用户表和用户订单表可以一对多关联。
<resultMap id="userResultMap" type="User"> <id column="id" property="id"/> <result column="name" property="name"/> <collection property="orders" ofType="Order"> <id column="order_id" property="id"/> <result column="product_name" property="name"/> </collection> </resultMap> <select id="selectUserWithOrders" resultMap="userResultMap"> SELECT u.id, u.name, o.order_id, o.product_name FROM users u LEFT JOIN orders o ON u.id = o.user_id WHERE u.id = #{userId} </select>
动态SQL 可以让 SQL 语句更加灵活,以适应不同的查询场景。
if
标签用于条件判断,只有条件满足时才会执行 SQL 语句。
<select id="selectUserByCondition" resultType="User"> SELECT id, name, password FROM users WHERE 1=1 <if test="id != null"> AND id = #{id} </if> <if test="name != null"> AND name = #{name} </if> </select>
choose
标签用于选择性执行条件语句,类似于 SQL 中的 CASE
语句。
<select id="selectUserByCondition" resultType="User"> SELECT id, name, password FROM users WHERE 1=1 <choose> <when test="id != null"> AND id = #{id} </when> <when test="name != null"> AND name = #{name} </when> <otherwise> AND password = #{password} </otherwise> </choose> </select>
foreach
标签用于循环操作,常用于处理 IN 语句。
<select id="selectUsersByIds" resultType="User"> SELECT id, name, password FROM users WHERE id IN <foreach item="item" index="index" collection="ids" open="(" separator="," close=")"> #{item} </foreach> </select>
MyBatis 通过执行 SQL 语句与数据库进行交互。主要有 SELECT、INSERT、UPDATE、DELETE 四种基本操作。
<select id="selectUserById" resultType="User"> SELECT id, name, password FROM users WHERE id = #{id} </select>
<insert id="insertUser" parameterType="User"> INSERT INTO users (id, name, password) VALUES (#{id}, #{name}, #{password}) </insert>
<update id="updateUser" parameterType="User"> UPDATE users SET name = #{name}, password = #{password} WHERE id = #{id} </update>
<delete id="deleteUserById" parameterType="int"> DELETE FROM users WHERE id = #{id} </delete>
MyBatis 的 Mapper 接口简化了数据库操作,将 SQL 语句映射到 Java 接口的方法上。
public interface UserMapper { User selectUserById(int id); void insertUser(User user); void updateUser(User user); void deleteUserById(int id); }
MyBatis 支持多种参数类型,如基本类型、复杂对象、List 和 Map 等。
<select id="selectUserById" resultType="User"> SELECT id, name, password FROM users WHERE id = #{id} </select>
<insert id="insertUser" parameterType="User"> INSERT INTO users (id, name, password) VALUES (#{id}, #{name}, #{password}) </insert>
<insert id="insertUsers" parameterType="List"> INSERT INTO users (id, name, password) VALUES <foreach item="item" index="index" collection="list" separator=","> (#{item.id}, #{item.name}, #{item.password}) </foreach> </insert>
MyBatis 支持多种分页方法,如使用 RowBounds 类、PageHelper 插件等。
RowBounds rowBounds = new RowBounds(offset, limit); List<User> users = sqlSession.selectList("com.example.mapper.UserMapper.selectUsers", null, rowBounds);
<!-- 引入 PageHelper 插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageInterceptor"> <property name="helperDialect" value="mysql"/> <property name="reasonable" value="true"/> </plugin> </plugins>
PageHelper.startPage(pageNum, pageSize); List<User> users = sqlSession.selectList("com.example.mapper.UserMapper.selectUsers"); PageInfo<User> pageInfo = new PageInfo<>(users);
MyBatis 有两种级别的缓存:一级缓存和二级缓存。
一级缓存是 SqlSession 级别的缓存,每次调用 SqlSession 的 select 方法时,先会从缓存中查找,如果查不到才去数据库中查找。
二级缓存是 Mapper 级别的缓存,可以配置为全局缓存,共享多个 SqlSession 的结果。
<cache/>
MyBatis 提供了插件机制,可以通过拦截器实现自定义功能。
@Intercepts({@Signature(type = Executor.class, method = "update", args = {MappedStatement.class, Object.class})}) public class MyPlugin implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 获取被拦截的方法名 String methodName = invocation.getMethod().getName(); // 进行操作 return invocation.proceed(); } }
MyBatis 的代码结构设计应该清晰、合理,推荐使用三层架构:DAO 层、Service 层和 Controller 层。
DAO 层负责与数据库交互,使用 Mapper 接口和 XML 文件定义 SQL 语句。
public interface UserMapper { User selectUserById(int id); void insertUser(User user); void updateUser(User user); void deleteUserById(int id); }
Service 层负责业务逻辑处理,调用 DAO 层的方法。
@Service public class UserService { @Autowired private UserMapper userMapper; public User getUserById(int id) { return userMapper.selectUserById(id); } public void insertUser(User user) { userMapper.insertUser(user); } }
Controller 层负责处理 HTTP 请求,调用 Service 层的方法。
@RestController @RequestMapping("/users") public class UserController { @Autowired private UserService userService; @GetMapping("/{id}") public User getUserById(@PathVariable int id) { return userService.getUserById(id); } @PostMapping public void insertUser(@RequestBody User user) { userService.insertUser(user); } }
MyBatis 性能优化主要包括几个方面:合理使用缓存、减少数据库交互、优化 SQL 语句、使用分页插件等。
合理使用 MyBatis 的一级缓存和二级缓存可以减少数据库的访问次数,提高性能。
尽量减少对数据库的多次查询操作,可以使用批量操作,如批量插入、批量更新等。
确保 SQL 语句的正确性和高效性,避免使用复杂的 SQL 语句。
使用分页插件如 PageHelper 可以更好地管理查询结果,提高性能。
MyBatis 提供了丰富的异常处理机制,如 SqlSession 提供了 try-with-resources 的方式来管理资源。
try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUserById(1); System.out.println(user.getName()); } catch (Exception e) { e.printStackTrace(); }
同时,MyBatis 支持通过配置文件来设置日志级别,可以使用 Log4j 或 SLF4J 等日志框架。
<settings> <setting name="logImpl" value="LOG4J"/> </settings>