- Mybatis简介
- 什么是 MyBatis?
- 如何获得Mybatis
- 持久化
- 持久层
- 为什么需要Mybatis
- 第一个Mybatis程序
- 搭建环境
- 建库建表
- 新建父工程
- 新建普通maven项目
- 删除src目录,作为父工程
- 导入maven依赖
- 创建第一个子模块
- 编写mybatis的核心配置文件
- 编写mybatis工具类,获取SqlSession
- 编写代码测试
- 实体类
- 接口
- Mapper
- 测试
- 问题一:Mapper.xml未注册
- 问题二:Mapper文件编译后不存在
- 问题三:数据库连接SSL错误
- 测试成功
- 搭建环境
- CRUD
- namespace中的包名要和Mapper接口的包名一致
- select 选择,查询语句
- id 对应接口中的方法名
- parameterType 对应接口中方法的请求参数
- resultType 对应接口中方法的返回值
- 集合类型写集合泛型类型
- insert/update/delete 增删改必须提交事务
- 编写接口
- 编写Mapper
- 测试
- Map的应用
- Map传递参数,用key获取即可
- 对象传递参数,用属性获取即可
- 只有一个基本类型参数,可以直接获取,可不写parameterType
- 编写接口
- 编写Mapper
- 测试
Mybatis简介
什么是 MyBatis?
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- MyBatis 是一款优秀的持久层框架
- 它支持自定义 SQL、存储过程以及高级映射。
- MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
- MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
- MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
如何获得Mybatis
- maven仓库
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency>
- 中文文档:https://mybatis.org/mybatis-3/zh/index.html
- Github:https://github.com/mybatis/mybatis-3/releases
持久化
持久层
为什么需要Mybatis
第一个Mybatis程序学习新东西方法:搭建环境-》导入mybatis-》编写代码-》测试
搭建环境
建库建表
CREATE DATABASE `mybatis`CHARACTER SET utf8 COLLATE utf8_general_ci; USE `mybatis`; CREATE TABLE `mybatis`.`user` ( `id` INT(20) NOT NULL COMMENT '主键', `name` VARCHAR(100) NOT NULL COMMENT '用户名', `pwd` VARCHAR(100) NOT NULL COMMENT '密码', PRIMARY KEY (`id`) ) ENGINE=INNODB CHARSET=utf8 COLLATE=utf8_general_ci; DESCRIBE `mybatis`.`user`; INSERT INTO `mybatis`.`user` (`id`, `name`, `pwd`) VALUES ('1', 'zhangyq', '123456'); INSERT INTO `mybatis`.`user` (`id`, `name`, `pwd`) VALUES ('2', 'zhangsf', '123456'); INSERT INTO `mybatis`.`user` (`id`, `name`, `pwd`) VALUES ('3', 'zhangdl', '123456');
新建父工程
新建普通maven项目
删除src目录,作为父工程
导入maven依赖
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <!--父工程--> <groupId>com.qing</groupId> <artifactId>mybatis-study</artifactId> <version>1.0-SNAPSHOT</version> <dependencies> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.49</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- https://mvnrepository.com/artifact/junit/junit --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.13.2</version> </dependency> </dependencies> </project>
创建第一个子模块
编写mybatis的核心配置文件
官网:https://mybatis.org/mybatis-3/zh/index.html
<?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.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> </configuration>
编写mybatis工具类,获取SqlSession
SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
package com.qing.utils; 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 MybatisUtils { // 构建 SqlSessionFactory 的实例 private static SqlSessionFactory sqlSessionFactory; static { try { String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } catch (IOException e) { e.printStackTrace(); } } /** * 获取 SqlSession * @return */ public static SqlSession getSqlSession() { return sqlSessionFactory.openSession(); } }
编写代码测试
实体类
接口
package com.qing.dao; import com.qing.pojo.User; import java.util.List; /** * 接口 */ public interface UserMapper { List<User> getUserList(); }
Mapper
<?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.qing.dao.UserMapper"> <!--id对应接口的方法,返回值类型对应接口返回值,参数类型对应接口方法参数,集合类型写集合泛型类型--> <select id="getUserList" resultType="com.qing.pojo.User"> select * from mybatis.user </select> </mapper>
测试
package com.qing.dao; import com.qing.pojo.User; import com.qing.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class UserMapperTest { /** * 方式一:sqlSession.getMapper(UserMapper.class) */ @Test public void test() { // 获取sqlSession SqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.getUserList(); for (User user : userList) { System.out.println(user); } // 关闭sqlSession sqlSession.close(); } }
问题一:Mapper.xml未注册
org.apache.ibatis.binding.BindingException: Type interface com.qing.dao.UserMapper is not known to the MapperRegistry. at org.apache.ibatis.binding.MapperRegistry.getMapper(MapperRegistry.java:47) at org.apache.ibatis.session.Configuration.getMapper(Configuration.java:845) at org.apache.ibatis.session.defaults.DefaultSqlSession.getMapper(DefaultSqlSession.java:288) at com.qing.dao.UserMapperTest.test(UserMapperTest.java:20)
解决:mybatis-config.xml中注册Mapper,resource绑定Mapper,必须使用路径/
<?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.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/qing/dao/UserMapper.xml"/> </mappers> </configuration>
问题二:Mapper文件编译后不存在
java.lang.ExceptionInInitializerError at com.qing.dao.UserMapperTest.test(UserMapperTest.java:18) Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### The error may exist in com/qing/dao/UserMapper.xml ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource com/qing/dao/UserMapper.xml at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30)
解决:pom.xml中配置编译配置
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <parent> <artifactId>mybatis-study</artifactId> <groupId>com.qing</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <artifactId>mybatis-01</artifactId> <!--配置resources,防止资源导出失败问题--> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
问题三:数据库连接SSL错误
org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure The last packet successfully received from the server was 2,729 milliseconds ago. The last packet sent successfully to the server was 2,715 milliseconds ago. ### The error may exist in com/qing/dao/UserMapper.xml ### The error may involve com.qing.dao.UserMapper.getUserList ### The error occurred while executing a query ### Cause: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure Caused by: javax.net.ssl.SSLHandshakeException: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors Caused by: java.security.cert.CertificateException: java.security.cert.CertPathValidatorException: Path does not chain with any of the trust anchors
解决:mybatis-config.xml中useSSL=true改为useSSL=false
<?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.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis?useSSL=false&useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/qing/dao/UserMapper.xml"/> </mappers> </configuration>
测试成功
CRUD
namespace中的包名要和Mapper接口的包名一致
<?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.qing.dao.UserMapper"> <!--id对应接口的方法,返回值类型对应接口返回值,参数类型对应接口方法参数,集合类型写集合泛型类型--> <select id="getUserList" resultType="com.qing.pojo.User"> select * from mybatis.user </select> </mapper>
package com.qing.dao; import com.qing.pojo.User; import java.util.List; /** * 接口 */ public interface UserMapper { /** * 查询全部用户 * @return */ List<User> getUserList(); }
select 选择,查询语句
id 对应接口中的方法名
parameterType 对应接口中方法的请求参数
resultType 对应接口中方法的返回值
集合类型写集合泛型类型
<?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.qing.dao.UserMapper"> <!--查询全部用户--> <select id="getUserList" resultType="com.qing.pojo.User"> select * from mybatis.user </select> <!--id对应接口的方法,返回值类型对应接口返回值,参数类型对应接口方法参数,集合类型写集合泛型类型--> <!--根据ID查询用户--> <select id="getUserById" parameterType="int" resultType="com.qing.pojo.User"> select * from mybatis.user where id=#{id} </select> </mapper>
package com.qing.dao; import com.qing.pojo.User; import java.util.List; /** * 接口 */ public interface UserMapper { /** * 查询全部用户 * @return */ List<User> getUserList(); /** * 根据ID查询用户 * @param id * @return */ User getUserById(int id); }
package com.qing.dao; import com.qing.pojo.User; import com.qing.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class UserMapperTest { /** * 查询全部用户 */ @Test public void getUserList() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.getUserList(); for (User user : userList) { System.out.println(user); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } /** * 根据ID查询用户 */ @Test public void getUserById() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(1); System.out.println(user); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } }
insert/update/delete 增删改必须提交事务
编写接口
package com.qing.dao; import com.qing.pojo.User; import java.util.List; /** * 接口 */ public interface UserMapper { /** * 查询全部用户 * * @return */ List<User> getUserList(); /** * 根据ID查询用户 * * @param id * @return */ User getUserById(int id); /** * 新增用户 * * @param user * @return */ int insert(User user); /** * 修改用户 * @param user * @return */ int update(User user); /** * 删除用户 * @param id * @return */ int delete(int id); }
编写Mapper
<?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.qing.dao.UserMapper"> <!--查询全部用户--> <select id="getUserList" resultType="com.qing.pojo.User"> select * from mybatis.user </select> <!--id对应接口的方法,返回值类型对应接口返回值,参数类型对应接口方法参数,集合类型写集合泛型类型--> <!--根据ID查询用户--> <select id="getUserById" parameterType="int" resultType="com.qing.pojo.User"> select * from mybatis.user where id=#{id} </select> <!--新增用户--> <insert id="insert" parameterType="com.qing.pojo.User"> insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd}) </insert> <!--修改用户--> <update id="update" parameterType="com.qing.pojo.User"> update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id} </update> <!--删除用户--> <delete id="delete" parameterType="int"> delete from mybatis.user where id=#{id} </delete> </mapper>
测试
package com.qing.dao; import com.qing.pojo.User; import com.qing.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class UserMapperTest { /** * 查询全部用户 */ @Test public void getUserList() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> userList = mapper.getUserList(); for (User user : userList) { System.out.println(user); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } /** * 根据ID查询用户 */ @Test public void getUserById() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserById(1); System.out.println(user); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } /** * 新增用户 */ @Test public void insert() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(4, "张仲景", "123456"); int rows = mapper.insert(user); System.out.println(rows); // 提交事务 sqlSession.commit(); System.out.println("提交事务"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } /** * 修改用户 */ @Test public void update() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(4, "张仲景二号", "123456"); int rows = mapper.update(user); System.out.println(rows); // 提交事务 sqlSession.commit(); System.out.println("提交事务"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } /** * 删除用户 */ @Test public void delete() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); int rows = mapper.delete(4); System.out.println(rows); // 提交事务 sqlSession.commit(); System.out.println("提交事务"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } }
Map的应用
Map传递参数,用key获取即可
对象传递参数,用属性获取即可
只有一个基本类型参数,可以直接获取,可不写parameterType
编写接口
package com.qing.dao; import com.qing.pojo.User; import java.util.List; import java.util.Map; /** * 接口 */ public interface UserMapper { /** * 通过Map新增用户 * @param map * @return */ int insertByMap(Map<String,Object> map); /** * 通过Map查询用户 * @param map * @return */ List<User> getByMap(Map<String,Object> map); }
编写Mapper
<?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.qing.dao.UserMapper"> <!--通过Map新增用户--> <insert id="insertByMap" parameterType="map"> insert into mybatis.user(id,name,pwd) values(#{userId},#{userName},#{password}) </insert> <!--通过Map查询用户--> <select id="getByMap" parameterType="map" resultType="com.qing.pojo.User"> select * from mybatis.user where id=#{userId} and name=#{userName} </select> </mapper>
测试
package com.qing.dao; import com.qing.pojo.User; import com.qing.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.HashMap; import java.util.List; import java.util.Map; public class UserMapperTest { /** * 通过Map新增用户 */ @Test public void insertByMap() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<String, Object>(); map.put("userId",4); map.put("userName","张仲景"); map.put("password","123456"); int rows = mapper.insertByMap(map); System.out.println(rows); // 提交事务 sqlSession.commit(); System.out.println("提交事务"); } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } /** * 通过Map查询用户 */ @Test public void getByMap() { SqlSession sqlSession = null; try { // 获取sqlSession sqlSession = MybatisUtils.getSqlSession(); // 执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String,Object> map = new HashMap<String, Object>(); map.put("userId",4); map.put("userName","张仲景"); List<User> userList = mapper.getByMap(map); for (User user : userList) { System.out.println(user); } } catch (Exception e) { e.printStackTrace(); } finally { // 关闭sqlSession sqlSession.close(); } } }