MyBatis入门后如何实现高效增删改查操作?

摘要:了解Mybatis Mybatis是一个持久层框架,半自动化ORM(Hibernate属于全自动化ORM)。 Mybatis的特点: 支持定制化sql、存储过程、基本映射以及高级映射 避免了几乎所有的JDBC代码中手动设置参数以及获取结果集
了解Mybatis Mybatis是一个持久层框架,半自动化ORM(Hibernate属于全自动化ORM)。 Mybatis的特点: 支持定制化sql、存储过程、基本映射以及高级映射 避免了几乎所有的JDBC代码中手动设置参数以及获取结果集 支持XML开发,也支持注解式开发 将接口和Java的pojo映射成数据库中的记录 体积小,易上手 完全做到sql解耦 提供了基本映射标签和高级映射标签 提供XML标签、支持动态sql Mybatis入门程序 引入依赖 <!-- mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.14</version> </dependency> <!-- MySQL驱动依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> 从XML中构建SqlSessionFactory SqlSessionFactory是mybatis中一个重要的对象。 SqlSessionFactory对象的创建需要xml 编写mybatis-config.xml文件(mybatis的核心配置文件) 文件不是必须叫mybatis-config.xml,可以采用其他名字 文件存放路径不是固定的,一般放在类的根路径下,一般放在resources文件夹下 mybatis中有两个主要的配置文件: mybatis-config.xml是核心配置文件,主要配置连接数据库的信息 <?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/spring6"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <!-- 执行xxxMapper.xml文件中的SQL语句--> <!-- resource属性自动从类的路径下加载xxxMapper.xml文件--> <mapper resource="CarMapper.xml"/> <!-- url属性直接从文件系统绝对路径加载xxxMapper.xml文件(不推荐)--> <!-- <mapper url="file:///D:/JavaProject/mybatis-001/src/main/resources/CarMapper.xml"/>--> </mappers> </configuration> xxxxMapper.xml是用来编写SQL的配置文件 <?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="carMapper"> <insert id="insertCar" > INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, '1003', '丰田霸道',30.0,'2000-10-11','燃油车') </insert> </mapper> 在mybatis当中,负责执行sql语句的那个对象叫做SqlSession。 SqlSession是专门执行sql语句的,是一个Java程序和数据库之间的一次会话。 要想获取SqlSession对象,需要先获取SqlSessionFactory对象,通过SqlSessionFactory来创建SqlSession对象。 怎么获取SqlSessionFactory对象? ​ 需要先获取SqlSessionFactoryBuilder对象。 ​ 通过SqlSessionFactoryBuilder对象的build方法来获取SqlSessionFactory对象。 所以mybatis的核心对象包括: SqlSessionFactoryBuilder SqlSessionFactory SqlSession SqlSessionFactoryBuilder--》SqlSessionFactory--》SqlSession 编写测试程序: public class MyBatisTes { public static void main(String[] args) throws IOException { // 获取 SqlSessionFactoryBuilder 对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 获取 SqlSessionFactory 对象 // Resources.getResourceAsStream默认从类路径下加载资源文件 InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); // 一般情况下,一个数据库对应一个SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream); // 获取 SqlSession 对象 SqlSession sqlSession = sqlSessionFactory.openSession(); int insertCar = sqlSession.insert("insertCar"); System.out.println("插入了" + insertCar + "条数据"); sqlSession.commit(); } } mybatis的事务管理机制 在mybatis-config.xml文件中,可以通过以下配置进行mybatis的事务管理 ​ type属性值包括JDBC和MANAGED 在mybatis中提供了2中事务管理机制 jdbc事务管理器:mybatis框架自己管理事务,自己采用原生的jdbc代码去管理事务 conn.setAutoCommit(false); // 开启事务 。。。。业务处理。。。。 conn.commit();// 手动提交事务 如果设置了自动提交(sqlSessionFactory.openSession(true);)。那么就没有开启事务,这是不推荐的 如果没有开启事务,那么就会自动提交 MANAGED事务管理器:mybatis不负责事务管理,事务管理交给其他容器来负责,例如Spring mybatis程序完善版: public static void main(String[] args) { SqlSession sqlSession = null; try { // 获取 SqlSessionFactoryBuilder 对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder(); // 获取 SqlSessionFactory 对象 // Resources.getResourceAsStream默认从类路径下加载资源文件 InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(resourceAsStream); // 获取 SqlSession 对象,底层会开启事务 sqlSession = sqlSessionFactory.openSession(); int insertUser = sqlSession.insert("insertCar"); System.out.println("插入了" + insertUser + "条数据"); sqlSession.commit(); } catch (IOException e) { if (sqlSession != null) { sqlSession.rollback(); } throw new RuntimeException(e); }finally { if (sqlSession != null) { sqlSession.close(); } } } mybatis开启日志 在mybatis-config.xml中配置如下: <settings> <!-- 开启日志:STDOUT_LOGGING是标准日志实现,mybatis已经实现了这个标准日志 settings标签必须出现在environments标签之前--> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> 集成logback日志框架 logback实现了slf4j标准。 引入logback依赖 <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.4.5</version> </dependency> 引入logback的xml配置文件 配置文件名字必须叫做logback.xml或者logback-test.xml,不能是其他名字。 配置文件必须放在类的根路径下,不能是其他位置。 内容如下: <configuration debug="false"> <!-- 控制台输出--> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> </appender> <!-- 每天生成日志文件--> <!-- <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> &lt;!&ndash; 日志文件按日期滚动生成的文件名 &ndash;&gt; <fileNamePattern>mybatis-%d{yyyy-MM-dd}.log</fileNamePattern> &lt;!&ndash; 保留最近30天的日志文件 &ndash;&gt; <maxHistory>30</maxHistory> </rollingPolicy> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{yyyy-MM-dd HH:mm:ss} [%thread] %-5level %logger{50} - %msg%n</pattern> </encoder> <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy"> &lt;!&ndash; 当日志文件大小超过100MB时触发滚动 &ndash;&gt; <maxFileSize>100MB</maxFileSize> </triggeringPolicy> </appender>--> <logger name="com.ali" level="trace" /> <logger name="java.sql.Connection" level="debug" /> <logger name="java.sql.Statement" level="debug" /> <logger name="java.sql.PreparedStatement" level="debug" /> <root level="debug"> <appender-ref ref="STDOUT" /> <!-- <appender-ref ref="FILE" /> --> </root> </configuration> MyBatis工具类 public class SqlSessionUtil { // 构造方法私有化,防止外部创建实例 private SqlSessionUtil(){} private static SqlSessionFactory sqlSessionFactory; // 类加载时执行,初始化 SqlSessionFactory static { try { sqlSessionFactory =new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")); } catch (Exception e) { throw new RuntimeException("初始化 SqlSessionFactory 失败", e); } } // 提供一个公共的静态方法,获取 SqlSession 对象 public static SqlSession openSqlSession(){ return sqlSessionFactory.openSession(); } } mybatis中增删改查 新增 在mybatis中使用#{}来代替jdbc当中?占位符 @Test public void TestInsertCar() { SqlSession sqlSession = SqlSessionUtil.openSqlSession(); Map<String, Object> map = new HashMap<String, Object>(); map.put("k1", "1111"); map.put("k2", "比亚迪汉"); map.put("k3", 10.0); map.put("k4", "2024-06-01"); map.put("k5", "新能源"); sqlSession.insert("insertCar", map); sqlSession.commit(); sqlSession.close(); } <insert id="insertCar" > INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{k1}, #{k2},#{k3},#{k4},#{k5}) </insert> 使用pojo类传值 @Test public void TestInsertCarByPojo() { SqlSession sqlSession = SqlSessionUtil.openSqlSession(); Car car = new Car(null, "3333", "比亚迪秦", 30.0,"2020-10-11","新能源"); sqlSession.insert("insertCar", car); sqlSession.commit(); sqlSession.close(); } <insert id="insertCar" > INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) </insert> #{carNum}中的carNum实际上是pojo类中的get方法getCarNum() 的方法名去掉get,然后首字母小写的字符串。不是属性名 删除 @Test public void testDeleteCarById() { SqlSession sqlSession = SqlSessionUtil.openSqlSession(); sqlSession.delete("deleteCarById", 1); sqlSession.commit(); sqlSession.close(); } <delete id="deleteCarById" > DELETE FROM t_car WHERE id = #{id} </delete> 如果占位符只有一个。那么#{}里面可以随意写,最好见名知意 更新 @Test public void testUpdateCarById() { SqlSession sqlSession = SqlSessionUtil.openSqlSession(); Car car = new Car(2L, "3333", "比亚迪秦Pro", 30.0, "2020-10-11", "新能源"); sqlSession.update("updateCarById", car); sqlSession.commit(); sqlSession.close(); } <update id="updateCarById" > UPDATE t_car SET car_num = #{carNum}, brand = #{brand},guide_price = #{guidePrice},produce_time = #{produceTime},car_type = #{carType} WHERE id = #{id} </update> 查一个 @Test public void testSelectCarById() { SqlSession sqlSession = SqlSessionUtil.openSqlSession(); // mybatis底层执行select后,会返回一个结果集对象:ResultSet // jdbc中叫做ResultSet,在mybatis中叫做ResultMap Car car = sqlSession.selectOne("selectCarById", 2); System.out.println(car); sqlSession.close(); } <!-- resultType表示要将查询结果封装成哪个类的对象--> <select id="selectCarById" resultType="com.ali.pojo.Car"> SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car WHERE id = #{id} </select> 查所有 @Test public void testSelectAllCar() { SqlSession sqlSession = SqlSessionUtil.openSqlSession(); // mybatis底层执行select后,会返回一个结果集对象:ResultSet // jdbc中叫做ResultSet,在mybatis中叫做ResultMap List<Car> cars = sqlSession.selectList("selectAllCar"); for (Car car : cars) { System.out.println(car); } sqlSession.close(); } <select id="selectAllCar" resultType="com.ali.pojo.Car"> SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car </select> 关于sql Mapper中的namespace 标签中的namespace 用来指定命名空间。用来防止id重复。 在Java程序中的写法(.): List cars = sqlSession.selectList("carMapper.selectAllCar");