Mybatis
SSM框架作用:配置文件
1.概念
1.1简介
MyBatis 是一款优秀的持久层框架
它支持定制化 SQL、存储过程以及高级映射
MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
MvBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
1.2持久化
持久化就是将程序的数据在持久状态和瞬时状态转化的过程
1.3持久层
完成持久化工作的代码,层界限十分明显
2.mybatis程序
连接数据库,导入需要的mysql和mybatis的jar包,需要一个SqlSessionFactory,为此建造一个工具类(mybatis官网入门中的三行代码),编写了mybatis核心配置文件-->mybatis-config.xml,配置文件连接了数据库,写实体类User,写接口UserDao,写Mapper文件
2.1搭建环境
搭建数据库
CREATE DATABASE `mybatis`; USE `mybatis`; CREATE TABLE `user`( `id` INT(20) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, `pwd` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (`id`) )engine=innoDB DEFAULT CHARSET=utf8; INSERT INTO `user`(`id`,`name`,`pwd`) VALUES (1,'张三','123'), (2,'李四','456'), (3,'王五','789');
新建项目
1.新建一个maven
2.删除src
3.导入maven依赖
pom.xml
<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/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>org.example</groupId> <artifactId>Mybatis1</artifactId> <packaging>war</packaging> <version>1.0-SNAPSHOT</version> <name>Mybatis1 Maven Webapp</name> <url>http://maven.apache.org</url> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>3.8.1</version> <scope>test</scope> </dependency> <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.33</version> </dependency> <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.19</version> </dependency> </dependencies> <build> <finalName>Mybatis1</finalName> </build> </project>
2.2创建一个模块
去这里复制这一段配置
MyBatis 3 | Getting started – mybatis
在resource中创建一个文件mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <!-- <mappers>--> <!-- <mapper resource="org/mybatis/example/BlogMapper.xml"/>--> <!-- </mappers>--> </configuration>
配置一下
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "https://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=UTF8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!-- <mappers>--> <!-- <mapper resource="org/mybatis/example/BlogMapper.xml"/>--> <!-- </mappers>--> </configuration>
编写mybatis工具类
在java里创建一个软件包utils,再创建MybatisUtils
package com.lyj.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; //sqlSessionFactory public class MybatisUtils { private static SqlSessionFactory sqlSessionFactory; static { try { //使用Mybatis第一步: 获取sqlSessionFactory对象 String resource = "mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); /*SqlSessionFactory*/ sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); }catch (IOException e){ e.printStackTrace(); } } //现在您有了SqlSessionFactory,您可以获取SqlSession的实例。SqlSession包含对数据库执行SQL命令所需的所有方法。 public static SqlSession getSqlSession(){ // SqlSession sqlSession = sqlSessionFactory.openSession(); // return sqlSession; return sqlSessionFactory.openSession();//优化上面两行代码 } }
2.3编写代码
-
实体类
package com.lyj.pojo; //实体类 public class User { private int id; private String name; private String pwd; public User(){} public User(int id, String name, String pwd) { this.id = id; this.name = name; this.pwd = pwd; } public int getId() { return id; } public void setId(int id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getPwd() { return pwd; } public void setPwd(String pwd) { this.pwd = pwd; } @Override public String toString() { return "User{" + "id=" + id + ", name='" + name + '\'' + ", pwd='" + pwd + '\'' + '}'; } }
-
Dao接口
package com.lyj.dao; import com.lyj.pojo.User; import java.util.List; public interface UserDao { List<User> getUserLise(); }
-
接口实现类由原来的UserDaoImpl转变为一个Mapper配置文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace= 绑定一个对应的Dao/Mapper接口--> <mapper namespace="com.lyj.dao.UserDao"> <select id="getUserList" resultType="com.lyj.pojo.User"> select * from mybatis.user </select> <!-- <select id="selectBlog" resultType="Blog">--> <!-- select * from Blog where id = #{id}--> <!-- </select>--> </mapper>
2.4测试
每一个Mapper.xml都需要再Mybatis核心配置文件中注册
org.apache.ibatis.binding.BindingException: Type interface com.lyj.dao.UserDao is not known to the MapperRegistry.
junit测试
package com.lyj.dao; import com.lyj.pojo.User; import com.lyj.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class UserDaoTest { @Test public void test(){ //第一步:获取SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); //方式一:getMapper UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.getUserList(); for (User user : userList) { System.out.println(user); } //关闭SqlSession sqlSession.close(); } }
3.CRUD
3.1namespace
namespace中的包名要和Dao/Mapper接口的包名一致
3.2select
选择,查询语句
-
id:就是对应的namespace中的方法名
-
resultType:Sql语句执行的返回值
步骤:
1.编写接口
2.测试对应的mapper中的sql语句
3.测试
4.增删改要提交事务commit
UserDao
package com.lyj.dao; import com.lyj.pojo.User; import java.util.List; public interface UserDao { //查询全部用户 List<User> getUserList(); //根据id查询用户 User getUserById(int id); //增加insert int addUser(User user); //修改用户 int updateUser(User user); //删除一个用户 int deleteUser(int id); }
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "https://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!--namespace= 绑定一个对应的Dao/Mapper接口--> <mapper namespace="com.lyj.dao.UserDao"> <select id="getUserList" resultType="com.lyj.pojo.User"> select * from mybatis.user </select> <select id="getUserById" parameterType="int" resultType="com.lyj.pojo.User"> select * from mybatis.user where id= #{id}; </select> <insert id="addUser" parameterType="com.lyj.pojo.User" > insert into mybatis.user(id,name,pwd) values(#{id},#{name},#{pwd}); </insert> <update id="updateUser" parameterType="com.lyj.pojo.User"> update mybatis.user set name=#{name}, pwd=#{pwd} where id=#{id}; </update> <delete id="deleteUser" parameterType="int"> delete from mybatis.user where id=#{id}; </delete> </mapper>
UserDaoTest
package com.lyj.dao; import com.lyj.pojo.User; import com.lyj.utils.MybatisUtils; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; public class UserDaoTest { @Test public void test(){ //第一步:获取SqlSession对象 SqlSession sqlSession = MybatisUtils.getSqlSession(); //方式一:getMapper推荐 UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> userList = userDao.getUserList(); //方式二不推荐 //List<User>userlist = sqlSession.selectList("com.lyj.dao.UserDao.getUserList"); for (User user : userList) { System.out.println(user); } //关闭SqlSession sqlSession.close(); } @Test public void getUserById(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); User user = userDao.getUserById(1); System.out.println(user); sqlSession.close(); } @Test public void addUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); int addUser = userDao.addUser(new User(4, "张一", "111")); sqlSession.commit(); sqlSession.close(); } @Test public void updateUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); int updateUser = userDao.updateUser(new User(4, "不是张一", "222")); sqlSession.commit(); sqlSession.close(); } @Test public void deleteUser(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); int deleteUser = userDao.deleteUser(4); sqlSession.commit(); sqlSession.close(); } }
3.3Map
假设,我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map
<!--对象中的属性,可以直接取出来 传递map的key--> <insert id="addUser2" parameterType="map"> insert into mybatis.user (id, pwd) values (#{userid},#{password}); </insert>
// JUnit测试注解,标记该方法为测试方法,可独立运行 @Test public void addUser2(){ // 1. 通过工具类获取SqlSession对象,SqlSession是MyBatis与数据库交互的核心对象 // 包含了执行SQL所需的所有方法,且默认开启事务(需手动提交) SqlSession sqlSession = MybatisUtils.getSqlSession(); try { // 2. 通过SqlSession获取Mapper接口的代理实现类 // MyBatis会自动生成接口的实现类,将接口方法与XML中的SQL语句绑定 UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 3. 创建Map集合作为参数容器 // 当需要传递的参数较多或参数名与SQL中的占位符不一致时,使用Map更灵活 Map<String, Object> map = new HashMap<String, Object>(); // 4. 向Map中存入键值对,key需与XML中SQL的占位符(#{userid}、#{password})完全一致 // 此处"userid"对应SQL中的#{userid},"password"对应#{password} map.put("userid",5); // 存入用户ID为5 map.put("password","2222333"); // 存入密码为"2222333" // 5. 调用Mapper接口的addUser2方法,传入Map参数执行插入操作 // 该方法对应XML中id="addUser2"的<insert>标签,MyBatis会自动解析Map参数并填充SQL mapper.addUser2(map); // 6. 提交事务(MyBatis默认关闭自动提交,增删改操作必须手动提交) // 若忘记提交,数据不会真正写入数据库 sqlSession.commit(); } catch (Exception e) { // 7. 若执行过程中出现异常,回滚事务,避免脏数据 sqlSession.rollback(); e.printStackTrace(); // 打印异常堆栈信息,便于调试 } finally { // 8. 关闭SqlSession,释放数据库连接资源 // 放在finally块中确保无论是否发生异常都会执行 sqlSession.close(); } }
Map传递参数,直接在sql中取出key即可 (parameterType = "map")
对象传递参数,直接在sql中取对象的属性即可 (parameterType = "Object")
只有一个基本类型参数的情况下,可以直接在sql中取到(parameterType =可以不写)
多个参数用Map或者注解
3.4 模糊查询
<select id="getUserLike" resultType="com.kuang.pojo.User"> select * from mybatis.user where name like "%"#{value}"%" </select>
// 导入必要的包(实际代码中需确保引入对应的MyBatis、JUnit、实体类等包) import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.util.List; import java.util.HashMap; import java.util.Map; public class UserMapperTest { // 假设这是测试类,实际类名以项目为准 // JUnit的@Test注解,标记该方法为测试方法,运行时会被识别执行 @Test public void getUserLike() { // 1. 获取SqlSession对象,通过工具类MybatisUtils建立与数据库的会话连接 SqlSession sqlSession = MybatisUtils.getSqlSession(); try { // 2. 获取UserMapper接口的代理实现类,MyBatis会动态生成代理类来执行SQL UserMapper mapper = sqlSession.getMapper(UserMapper.class); // 3. 调用UserMapper接口中定义的getUserLike方法,传入模糊查询的参数 // "%李%" 表示查询name字段中包含"李"字的记录,符合SQL的LIKE语法 List<User> userList = mapper.getUserLike("李"); // 4. 遍历查询结果集,打印每个User对象信息 for (User user : userList) { System.out.println(user); } } finally { // 5. 关闭SqlSession,释放数据库连接资源,避免连接泄漏 sqlSession.close(); } } }