一、准备工作
1、引入maven依赖
<dependencies> <!--junit测试类--> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--mybatis依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.10</version> </dependency> <!--数据库驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.30</version> </dependency> <!--引入logback日志框架依赖,这个日志框架实现了slf4j规范--> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</artifactId> <version>1.2.11</version> </dependency> </dependencies>
2、开发工具类 SqlSessionUtil
作用: 1、SqlSessionUtil,方便用来获取SqlSession对象 2、避免多次重复创建SqlSessionFactory 对象, 因为一个环境下,只需要创建一个SqlSessionFactory
package com.powernode.util; 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; public class SqlSessionUtil { private SqlSessionUtil(){}; private static SqlSessionFactory sqlSessionFactory; static { try { sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml")); } catch (IOException e) { e.printStackTrace(); } } /** * 获取会话对象, * @return */ public static SqlSession openSqlSession(){ return sqlSessionFactory.openSession(); } }
3、准备 mybatis-config.xml文件
在resources目录下,添加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/powernode?useUnicode=true&characterEncoding=utf-8"/> <property name="username" value="root"/> <property name="password" value="root"/> </dataSource> </environment> </environments> <mappers> <mapper resource="com/CarMapper.xml"/> </mappers> </configuration>
4、准备日志文件logback.xml
<?xml version="1.0" encoding="UTF-8"?> <configuration debug="false"> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> <pattern>%d{HH:mm:ss.SSS} %contextName [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender> <logger name="com.apache.ibatis" 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>
二、INSERT 功能
1、JDBC和mybatis占位符对比
JDBC的代码是怎么写的? string sql ="insert into t_car(id,car_num,brand,guide_price,produce_time,car_type) values(null,?,?,?,?,?)"; ps.setstring(1,xxx); ps.setstring(2, yyy); .... 在JDBC当中占位符采用的是? 在mybatis当中不能使用?占位符,必须使用 #{} 来代替JDBC当中的 ?#{} 和 JDBC当中的 ? 是等效的。
2、java程序中使用Map可以给SQL语句的占位符传值:
Map<String, Object> map = new HashMap<>(); map.put("k1","1111"); map.put("k2","比亚迪汉"); map.put("k3",10.0); map.put("k4","2020-11-11"); map.put("k5","电车");
xml文件写法
insert into t car(id.car_num.brandquide priceproduce_timecartype)values(null,#{k1},#{k2}.#{k3}.#{k4}.#{k5})
注意:#{这里写什么?写map集合的key,如果key不存在,获取的是null}
一般map集合的key起名的时候要见名知意。
map.put("carNum","1111"); map.put("brand","比亚迪汉2"); map.put("guidePrice",10.0); map.put("produceTime","2020-11-11"); map.put("carType","电车"); insert into t car(id,car_num,brand,guide_price,produce_time,car_type values(null,#{carNum},#{brand},#fauidePrice},#{produceTime},#{carType})
3、java程序中使用POJO类给SQL语句的占位符传值
java程序中使用POJO类给SQL语句的占位符传值:
Car car =new Car(null,“3333”,“比亚迪秦”,30.0,“2020-11-11”,“新能源”);
注意:占位符#{},大括号里面写:pojo类的属性名
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null.#{carNum}.#{brand}.#{quidePrice}.#{produceTime},#{carType}
把SQL语句写成这个德行:
insert into t_car(id,car_num,brand,guide_price,produce_time,car_type)
values(null,#{xyz},#{brand},#{guidePrice},#{produceTime},#{carType})
出现了什么问题呢?
There is no getter for property named 'xyz’ in 'class com.powernode.mybatis.pojo.Car mybatis去找:Car类中的getXyz()方法去了。没找到。报错了。
怎么解决的?
可以在Car类中提供一个getxyz()方法。这样问题就解决了。
通过这个测试,得出一个结论:
严格意义上来说:如果使用POJO对象传递值的话,#{}这个大括号中到底写什么? 写的是get方法的方法名去掉get,然后将剩下的单词首字母小写,然后放进去。 例如:getUsername() --> #{username}例如:getEmail() --> #{email} 也就是说mybatis在底层给?传值的时候,先要获取值,怎么获取的? 调用了pojo对象的get方法。例如:car.getCarNum(),car.getCarType(),car.getBrand()
完整的代码:
pojo实体类 Car
package com.powernode.pojo; public class Car { private Long id; private String carNum; private String brand; private Double guidePrice; private String produceTime; private String carType; public Car(Long id, String carNum, String brand, Double guidePrice, String produceTime, String carType) { this.id = id; this.carNum = carNum; this.brand = brand; this.guidePrice = guidePrice; this.produceTime = produceTime; this.carType = carType; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } public String getCarNum() { return carNum; } public void setCarNum(String carNum) { this.carNum = carNum; } public String getBrand() { return brand; } public void setBrand(String brand) { this.brand = brand; } public Double getGuidePrice() { return guidePrice; } public void setGuidePrice(Double guidePrice) { this.guidePrice = guidePrice; } public String getProduceTime() { return produceTime; } public void setProduceTime(String produceTime) { this.produceTime = produceTime; } public String getCarType() { return carType; } public void setCarType(String carType) { this.carType = carType; } }
CarMapper.xml文件配置
<?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="jskdlf"> <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> </mapper>
测试类
@Test public void testInsertPojo(){ SqlSession sqlSession = SqlSessionUtil.openSqlSession(); Car car = new Car(null,"333","比亚迪秦",30.0,"220-10-09","新能源"); int count = sqlSession.insert("insertCar",car); System.out.println(count); sqlSession.commit(); sqlSession.close(); }
三、delete 功能
需求:根据id删除记录 1、pojo实体类同上 2、CarMapper.xml文件sql语句配置
<delete id="deleteById"> delete from t_car where id = #{id} </delete>
3、测试类
@Test public void testDelete(){ SqlSession sqlSession = SqlSessionUtil.openSqlSession(); int count = sqlSession.delete("deleteById",15); System.out.println(count); sqlSession.commit(); sqlSession.close(); }
注意:如果占位符只有一个,那么#{}的大括号里可以随意写,但是最好是见名知意
四、update 功能
需求:根据id修改记录 1、pojo实体类同上 2、CarMapper.xml文件sql语句配置
<update id="updateById"> update t_car set car_num=#{carNum},brand=#{brand} where id=#{id} </update>
3、测试类
@Test public void testUpdateById(){ SqlSession sqlSession = SqlSessionUtil.openSqlSession(); Car car = new Car(); car.setId(14L); car .setCarNum("999"); car.setBrand("GTR"); int count = sqlSession.update("updateById",car); System.out.println(count); sqlSession.commit(); sqlSession.close(); }
五、select查询功能
需求:根据id查询,返回一个目标对象
1、pojo实体类同上 2、CarMapper.xml文件sql语句配置
<select id="selectById" resultType="com.powernode.pojo.Car"> select * from t_car where id = #{id} </select>
3、测试类
@Test public void testSelectOne(){ SqlSession sqlSession = SqlSessionUtil.openSqlSession(); Car car = sqlSession.selectOne("selectById",12); System.out.println(car.toString()); sqlSession.commit(); sqlSession.close(); }
运行结果
发现问题: Car{id=12, carNum='null', brand='auto', guidePrice=null, produceTime='null', carType='null'} 为什么只有id和brand有值,其他字段都没有查询到值? 原理是因为数据库的列名和pojo实体类的名字不一致,造成的
解决办法:
可以使用mysql的as关键字起别名 sql文件修改成这样:
<select id="selectById" resultType="com.powernode.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>
运行测试类结果,
需求:查询所有对象
1、pojo实体类同上 2、CarMapper.xml文件sql语句配置
<select id="selectAll" resultType="com.powernode.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>
3、测试类
@Test public void testSelectAll(){ SqlSession sqlSession = SqlSessionUtil.openSqlSession(); List<Car> carList = sqlSession.selectList("selectAll"); carList.forEach(c-> System.out.println(c)); sqlSession.commit(); sqlSession.close(); }
运行结果
注意:
如果查询的结果为List,那么resultType还是指定要封装的结果集的类型,不是指定list类型,是指定list集合中元素的类型 selectList方法:mybatis通过这个方法就可以得知你需要一个list集合 ,他会自动给你返回一个List集合