本文将详细介绍Mybatis持久层框架学习入门的相关内容,涵盖基本概念、优势、应用场景及安装与环境搭建等。文章还深入讲解了Mybatis的核心配置、CRUD操作、动态SQL应用以及与Spring的集成方法。通过示例代码和配置文件,读者可以全面掌握Mybatis的使用技巧和性能优化策略。
Mybatis是一个优秀的持久层框架,它支持定制化SQL查询,存储过程和高级映射。Mybatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。Mybatis可以使用简单的XML或注解进行配置和原始映射,将接口和Java的POJO(Plain Old Java Object,普通的Java对象)映射成数据库中的记录。
Mybatis主要由以下几个部分组成:
Mybatis适用于那些需要根据业务逻辑频繁修改SQL语句的应用场景。例如,当应用程序需要频繁地修改和优化SQL语句以提高查询效率和性能时,Mybatis提供了灵活的SQL编写方式和强大的动态SQL支持。
以下是一个简单的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/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
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> </dependencies>
mybatis-config.xml
,配置环境信息、数据库连接信息等。以下是一个简单的Mybatis环境搭建示例:
mybatis-config.xml
文件:<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/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
CREATE TABLE `user` ( `id` INT(11) NOT NULL AUTO_INCREMENT, `name` VARCHAR(50) NOT NULL, `age` INT(11) NOT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
public class User { private int id; private String name; private int age; // Getters and setters }
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="com.example.model.User"> SELECT id, name, age FROM user WHERE id = #{id} </select> </mapper>
public interface UserMapper { User selectUser(int id); }
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; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUser(1); System.out.println(user.getName()); } } }
通过以上步骤,可以搭建一个简单的Mybatis环境。
Mybatis的配置文件通常命名为mybatis-config.xml
,该文件主要包含以下几个部分:
以下是一个简单的mybatis-config.xml
配置文件示例:
<configuration> <properties> <property name="driver" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </properties> <settings> <setting name="cacheEnabled" value="true"/> <setting name="lazyLoadingEnabled" value="true"/> </settings> <typeAliases> <typeAlias type="com.example.model.User" alias="User"/> </typeAliases> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
在Mybatis中,数据库连接配置可以通过<environment>
标签进行设置。<environment>
标签用于指定数据库连接和事务管理的配置。
<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/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </dataSource> </environment> </environments> </configuration>
JDBC
、MANAGED
。UNPOOLED
、POOLED
、JNDI
。映射文件通常命名为*.Mapper.xml
,用于定义SQL语句和结果映射。
映射文件主要包含以下几个部分:
以下是一个简单的UserMapper.xml
映射文件示例:
<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="com.example.model.User"> SELECT id, name, age FROM user WHERE id = #{id} </select> <insert id="insertUser" parameterType="com.example.model.User"> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> <update id="updateUser" parameterType="com.example.model.User"> UPDATE user SET name=#{name}, age=#{age} WHERE id=#{id} </update> <delete id="deleteUser" parameterType="int"> DELETE FROM user WHERE id=#{id} </delete> </mapper>
CRUD是Create(创建)、Read(读取)、Update(更新)和Delete(删除)四个操作的缩写。Mybatis提供了简单的SQL语句和映射规则来实现这些操作。
以下是一个简单的CRUD操作示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="com.example.model.User"> SELECT id, name, age FROM user WHERE id = #{id} </select> <insert id="insertUser" parameterType="com.example.model.User"> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> <update id="updateUser" parameterType="com.example.model.User"> UPDATE user SET name=#{name}, age=#{age} WHERE id=#{id} </update> <delete id="deleteUser" parameterType="int"> DELETE FROM user WHERE id=#{id} </delete> </mapper>
public interface UserMapper { User selectUser(int id); void insertUser(User user); void updateUser(User user); void deleteUser(int id); }
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; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); // 插入用户 User user = new User(1, "Alice", 25); mapper.insertUser(user); session.commit(); // 查询用户 User queryUser = mapper.selectUser(1); System.out.println(queryUser.getName()); // 更新用户 user.setName("Bob"); mapper.updateUser(user); session.commit(); // 删除用户 mapper.deleteUser(1); session.commit(); } } }
Mybatis提供了丰富的SQL标签来执行SQL语句,如<select>
, <insert>
, <update>
, <delete>
等。
结果映射用于将查询结果映射到Java对象。可以通过resultType
或resultMap
进行结果映射。
以下是一个简单的SQL语句执行示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="com.example.model.User"> SELECT id, name, age FROM user WHERE id = #{id} </select> <insert id="insertUser" parameterType="com.example.model.User"> INSERT INTO user(name, age) VALUES(#{name}, #{age}) </insert> <update id="updateUser" parameterType="com.example.model.User"> UPDATE user SET name=#{name}, age=#{age} WHERE id=#{id} </update> <delete id="deleteUser" parameterType="int"> DELETE FROM user WHERE id=#{id} </delete> </mapper>
public interface UserMapper { User selectUser(int id); void insertUser(User user); void updateUser(User user); void deleteUser(int id); }
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; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); // 插入用户 User user = new User(1, "Alice", 25); mapper.insertUser(user); session.commit(); // 查询用户 User queryUser = mapper.selectUser(1); System.out.println(queryUser.getName()); // 更新用户 user.setName("Bob"); mapper.updateUser(user); session.commit(); // 删除用户 mapper.deleteUser(1); session.commit(); } } }
以下是一个结果映射示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <resultMap id="UserResultMap" type="com.example.model.User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> </resultMap> <select id="selectUser" resultMap="UserResultMap"> SELECT id, name, age FROM user WHERE id = #{id} </select> </mapper>
Mybatis支持多种类型的参数处理,包括基本类型、复杂类型、Map等。
结果集处理主要是通过结果映射resultType
或resultMap
进行映射。
以下是一个参数处理示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUserByName" resultType="com.example.model.User"> SELECT id, name, age FROM user WHERE name = #{name} </select> </mapper>
public interface UserMapper { List<User> selectUserByName(String name); }
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; import java.util.List; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.selectUserByName("Alice"); for (User user : users) { System.out.println(user.getName()); } } } }
以下是一个结果集处理示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <resultMap id="UserResultMap" type="com.example.model.User"> <id property="id" column="id"/> <result property="name" column="name"/> <result property="age" column="age"/> </resultMap> <select id="selectUser" resultMap="UserResultMap"> SELECT id, name, age FROM user WHERE id = #{id} </select> </mapper>
public interface UserMapper { User selectUser(int id); }
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; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); User user = mapper.selectUser(1); System.out.println(user.getName()); } } }
if
标签用于执行条件分支逻辑。当条件满足时,才会执行SQL语句。
choose
标签用于执行多条件分支逻辑。类似于Java中的switch
语句,可以选择多个when
条件,满足任一条件即可执行相应的SQL语句。
以下是一个简单的动态SQL示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUser" resultType="com.example.model.User"> SELECT id, name, age FROM user <where> <if test="id != null"> AND id = #{id} </if> <if test="name != null"> AND name = #{name} </if> </where> </select> </mapper>
public interface UserMapper { List<User> selectUser(int id, String name); }
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; import java.util.List; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.selectUser(1, null); for (User user : users) { System.out.println(user.getName()); } } } }
foreach
标签用于遍历集合或数组,并在SQL语句中生成相应的SQL语句片段。
以下是一个简单的foreach标签示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUserList" resultType="com.example.model.User"> SELECT id, name, age FROM user WHERE id in <foreach item="item" index="index" collection="ids" open="(" separator="," close=")"> #{item} </foreach> </select> </mapper>
public interface UserMapper { List<User> selectUserList(List<Integer> ids); }
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; import java.util.ArrayList; import java.util.List; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); List<Integer> ids = new ArrayList<>(); ids.add(1); ids.add(2); List<User> users = mapper.selectUserList(ids); for (User user : users) { System.out.println(user.getName()); } } } }
LIMIT
语句实现分页查询。foreach
标签批量插入或删除数据。以下是一个简单的分页查询示例:
UserMapper.xml
:<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUserPage" resultType="com.example.model.User"> SELECT id, name, age FROM user LIMIT #{offset}, #{pageSize} </select> </mapper>
public interface UserMapper { List<User> selectUserPage(int offset, int pageSize); }
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; import java.util.List; public class MybatisTest { public static void main(String[] args) throws IOException { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); try (SqlSession session = sqlSessionFactory.openSession()) { UserMapper mapper = session.getMapper(UserMapper.class); List<User> users = mapper.selectUserPage(0, 10); for (User user : users) { System.out.println(user.getName()); } } } }
Spring框架提供了丰富的事务管理和依赖注入功能,通过将Mybatis与Spring整合,可以利用Spring的这些功能,简化Mybatis的使用。
Mybatis与Spring的整合可以通过配置Spring的SqlSessionFactoryBean
和SqlSessionTemplate
来实现。
以下是一个简单的Spring配置文件示例:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:mapper/*.xml"/> </bean> <bean id="userMapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.mapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
通过Spring的SqlSessionFactoryBean
和SqlSessionTemplate
,可以轻松管理Mybatis的Session工厂。
以下是一个简单的Spring配置示例:
mybatis-config.xml
配置文件:<configuration> <typeAliases> <typeAlias type="com.example.model.User" alias="User"/> </typeAliases> <mappers> <mapper resource="com/example/mapper/UserMapper.xml"/> </mappers> </configuration>
applicationContext.xml
:<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis-config.xml"/> <property name="mapperLocations" value="classpath*:mapper/*.xml"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="userMapper" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.example.mapper"/> <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory"/> </bean>
public interface UserMapper { User selectUser(int id); }
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; import java.util.List; public class SpringTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper mapper = context.getBean("userMapper", UserMapper.class); User user = mapper.selectUser(1); System.out.println(user.getName()); } }
Mybatis默认使用SLF4J作为日志框架,可以通过配置文件进行日志级别和输出格式的设置。
可以通过Mybatis的debug
属性开启调试模式,输出详细的SQL执行信息。
以下是一个简单的日志配置示例:
log4j.properties
配置文件:log4j.rootLogger=DEBUG, stdout log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n log4j.logger.org.mybatis=DEBUG log4j.logger.org.mybatis.spring=DEBUG log4j.logger.org.apache.ibatis=DEBUG
mybatis-config.xml
配置文件中启用日志:<settings> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> `` ### 解析 - **log4j.properties**:用于配置日志的级别和输出格式。 - **settings**:用于设置Mybatis的运行时环境配置,启用日志输出。 ## 常见问题与解决办法 ### 常见问题 1. **SQL执行错误**:SQL语句语法错误或参数类型不匹配。 2. **结果映射错误**:结果映射配置不正确,导致结果集无法正确映射到Java对象。 3. **事务管理问题**:事务管理配置不当,导致数据一致性问题。 ### 解决办法 1. **SQL执行错误**:检查SQL语句的语法和参数类型,确保SQL语句正确。 2. **结果映射错误**:检查结果映射配置,确保结果集能够正确映射到Java对象。 3. **事务管理问题**:检查事务管理配置,确保事务管理正确。 ### 示例代码 以下是一个简单的事务管理配置示例: 1. **创建`applicationContext.xml`配置文件**: ```xml <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="password"/> </bean> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="mapperLocations" value="classpath*:mapper/*.xml"/> </bean> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven transaction-manager="transactionManager"/>
public interface UserMapper { @Transactional void insertUser(User user); }
import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; public class SpringTest { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserMapper mapper = context.getBean("userMapper", UserMapper.class); User user = new User(1, "Alice", 25); mapper.insertUser(user); } }
foreach
标签批量插入或删除数据。LIMIT
语句实现分页查询,减少数据传输量。以下是一个简单的性能优化示例:
<settings> <setting name="cacheEnabled" value="true"/> </settings>
<mapper namespace="com.example.mapper.UserMapper"> <insert id="batchInsertUser" parameterType="java.util.List"> INSERT INTO user(name, age) VALUES <foreach item="item" index="index" collection="users" separator=","> (#{item.name}, #{item.age}) </foreach> </insert> </mapper>
<mapper namespace="com.example.mapper.UserMapper"> <select id="selectUserPage" resultType="com.example.model.User"> SELECT id, name, age FROM user LIMIT #{offset}, #{pageSize} </select> </mapper>
通过以上内容,可以更好地理解和使用Mybatis持久层框架,同时也可以通过Spring框架更好地管理和维护Mybatis的Session工厂。