修改Car表里name=bmw的价格
CarService接口
void update(Car c) throws Exception;//修改汽车数据
CarServiceImpl类
package cn.tedu.service;
import cn.tedu.pojo.Car;
import org.springframework.stereotype.Component;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
//实现类实现了接口,要重写所有 抽象方法
@Component //交给spring容器进行ioc
public class CarServiceImpl implements CarService{
//重写的要求:子类的方法声明必须和父类一样 + 要有足够的权限
@Override
//利用jdbc,修改car表的数据
public void update(Car c) throws Exception {
//1,注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2,获取数据库的连接
String url = "jdbc:mysql:///cgb2104?characterEncoding=utf8&serverTimezone=Asia/Shanghai" ;
Connection conn = DriverManager.getConnection(url,"root","root");
//3,执行SQL
String sql = "update car set price=? where name=? " ;
PreparedStatement ps = conn.prepareStatement(sql);
//给SQL设置的参数
ps.setDouble(1,c.getPrice());
ps.setString(2,c.getName());
ps.executeUpdate();
//4,释放资源
ps.close();
conn.close();
}
@Override//新增数据
public void add(Car c) {
//TODO 发起jdbc,把数据入库
System.out.println(c);
}
@Override//获取汽车数据
public Car get(){
Car c = new Car();
c.setName("保时捷");
c.setColor("红色");
c.setPrice(641000.0);
return c;//准备要返回的数据,谁调用给谁返回
}
}
CarController类
//接受请求,解析请求参数
@RequestMapping("update")
public void update(Car c) throws Exception {
carService.update(c);
}
简化了JDBC的开发,还提供了缓存,支持各种SQL的写法。
自动完成ORM的映射:是指类和表的关系,是属性和字段值的关系
–核心配置文件:mybatis-config.xml,里面写数据源,事务,映射文件
–映射文件:XxxMapper.xml ,里面写了大量的SQL
–SqlSessionFactory:是SQL的会话工厂,用来产生很多的会话,对象唯一共享
–SqlSession:是SQL的会话,用来执行SQL
ORM:对象关系的自动映射,把car表里的字段的值查出来,一个一个,给Car类里的属性赋值
创建新的module,修改pom,添加mybatis的jar包的坐标
<dependencies>
<!--mybatis依赖包-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.4</version>
</dependency>
<!--jdbc依赖包-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
</dependencies>
创建核心配置文件:数据源,事务,映射文件
<?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">
<!-- mybatis的核心配置文件 -->
<configuration>
<environments default="test">
<environment id="test">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf8&serverTimezone=Asia/Shanghai" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
</configuration>
创建核心映射文件:存大量的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">
<!--这是mybatis的映射文件,用来写大量的SQL
namespace属性是每个映射文件的唯一标识
-->
<mapper namespace="userMapperNS">
<!--查询user表里的所有数据
id属性是每条SQL的唯一标识
resultType属性用来完成ORM,把表里每个字段的值 自动映射给 类里的属性
-->
<select id="getAll" resultType="cn.tedu.pojo.User">
select * from user
</select>
<!--查询id=1的用户信息 resultType需要指定一个类的全路径-->
<select id="getById" resultType="cn.tedu.pojo.User">
select * from user where id=1
</select>
</mapper>
修改核心配置文件,引入映射文件
<!-- 用来引入映射文件 -->
<mappers>
<mapper resource="UserMapper.xml"></mapper>
</mappers>
创建User类
package cn.tedu.pojo;
//为了 封装User表里的每个字段的值
//要求:类名和表名对应,属性名和字段名一致
public class User {
private Integer id ;
private String name ;
private String addr ;
private Integer age ;
//set get toString
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", addr='" + addr + '\'' +
", age=" + age +
'}';
}
}
创建测试类
package cn.tedu.mybatis;
import cn.tedu.pojo.User;
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 org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
//测试 mybatis
public class Test1 {
@Test
public void getAll() throws IOException {
//1,读取核心配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2,创建会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3,打开SQL会话
SqlSession session = factory.openSession();
//4,执行SQL -- 定位SQL的方式是namespace的值.id的值
List<User> list = session.selectList("userMapperNS.getAll");
//5,遍历list并打印
for (User u : list) {
System.out.println(u);
}
//Mybatis为了提高查询效率,会提供缓存的技术--减少了和数据库的交互次数
//当第一次查询数据时,缓存中当然没有,直接发起SQL查询了数据库,把数据存入缓存
//第二次查询 相同的数据时,先去查缓存,有就直接用,没有再去查数据库
//这是Mybatis默认就已经开启的一级缓存/SqlSession级别,必须是同一个SqlSession。
List<User> list2 = session.selectList("userMapperNS.getAll");
//5,遍历list并打印
for (User u : list2) {
System.out.println(u);
}
//根据id查询,selectOne()只返回一个结果
User u = session.selectOne("userMapperNS.getById");
System.out.println(u);
}
}
目前都是xml配置文件的使用方式,当执行SQL时,只能自己使用namespace的值.id的值,定位SQL。
需求:
获取所有dept表里的数据
创建deptDao接口
package cn.tedu.dao;
import cn.tedu.pojo.Dept;
import java.util.List;
//修饰符 返回值 方法名(参数列表)
public interface DeptDao {
List<Dept> getAll(); //获取所有dept表里的数据
}
创建Dept类
package cn.tedu.pojo;
//完成ORM,自动实现把dept表里字段的值 封装给不同属性
public class Dept {
private Integer id;//描述dept表里的id字段
private String dname;//描述dept表里的dname字段
private String loc;//描述dept表里的loc字段
//set get toString
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
}
创建DeptMapper.xml映射文件:选中resources-右键-new-file-起个名字-回车
<?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属性用来作为mapper文件的唯一标识
namespace属性的值是 接口的全路径
-->
<mapper namespace="cn.tedu.dao.DeptDao">
<!--select用来标记着这是一个查询的SQL语句
id属性是SQL的唯一标识
id属性的值是 接口里对应的方法名
resultType属性的值是 要把查询结果封装给哪个类的全路径
-->
<select id="getAll" resultType="cn.tedu.pojo.Dept">
select * from dept
</select>
</mapper>
修改核心配置文件,把deptMapper.xml 引进来
<!-- 用来引入映射文件 ,底层维护了MapperRegistry,用来存各种Mapper文件-->
<mappers>
<mapper resource="UserMapper.xml"></mapper>
<mapper resource="DeptMapper.xml"></mapper>
</mappers>
测试类
//测试接口的方式开始
@Test
public void inter() throws IOException {
//1,读取核心配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2,创建会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3,开启会话
SqlSession session = factory.openSession();
//4,执行SQL -- 参数是接口文件的class对象
DeptDao dao = session.getMapper(DeptDao.class);//获取指定的接口
List<Dept> list = dao.getAll();//定位到了SQL
//5,遍历打印
for (Dept d : list) {
System.out.println(d);
}
}
按照id查询dept的数据
package cn.tedu.pojo;
//完成ORM,自动实现把dept表里字段的值 封装给不同属性
public class Dept {
private Integer id;//描述dept表里的id字段
private String dname;//描述dept表里的dname字段
private String loc;//描述dept表里的loc字段
//set get toString
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
@Override
public String toString() {
return "Dept{" +
"id=" + id +
", dname='" + dname + '\'' +
", loc='" + loc + '\'' +
'}';
}
}
<?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">
<!--这个文件,是mybatis框架的核心配置文件,都配置了数据源,事务,映射文件-->
<configuration>
<environments default="test">
<!--配置数据源,事务-->
<environment id="test">
<!--配置了事务,使用jdbc提供的事务-->
<transactionManager type="JDBC"></transactionManager>
<!--配置了数据源,指定连接数据库的4个参数-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatisdb?characterEncoding=utf8&serverTimezone=Asia/Shanghai" />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 用来引入映射文件 ,底层维护了MapperRegistry,用来存各种Mapper文件-->
<mappers>
<mapper resource="UserMapper.xml"></mapper>
<mapper resource="DeptMapper.xml"></mapper>
</mappers>
</configuration>
<?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属性用来作为mapper文件的唯一标识
namespace属性的值是 接口的全路径
-->
<mapper namespace="cn.tedu.dao.DeptDao">
<!--select用来标记着这是一个查询的SQL语句
id属性是SQL的唯一标识
id属性的值是 接口里对应的方法名
resultType属性的值是 要把查询结果封装给哪个类的全路径
-->
<select id="getAll" resultType="cn.tedu.pojo.Dept">
select * from dept
</select>
<!--按照id查询dept的数据
ID属性的值=接口中的方法名
-->
<select id="getById" resultType="cn.tedu.pojo.Dept">
SELECT * FROM DEPT WHERE ID=1
</select>
</mapper>
package cn.tedu.mybatis;
import cn.tedu.dao.DeptDao;
import cn.tedu.pojo.Dept;
import cn.tedu.pojo.User;
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 org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
//测试 mybatis
public class Test1 {
SqlSessionFactory factory ;
//测试接口的方式开始
//@BeforeEach在执行@Test前执行,以下两步代码重复出现,提取出来,提高代码的复用性
@BeforeEach
public void init() throws IOException {
//1,读取核心配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2,创建会话工厂
factory = new SqlSessionFactoryBuilder().build(in);
}
//按照id获取数据
@Test
public void getById() {
//1,开启会话
SqlSession session = factory.openSession();
//2,执行接口中的方法
DeptDao dao = session.getMapper(DeptDao.class);//获取指定的接口文件
Dept d = dao.getById();//好像是调用了接口里的方法,本质上已经找到了mapper里的sql了
System.out.println(d);
}
@Test
public void inter() throws IOException {
//3,开启会话
SqlSession session = factory.openSession();
//4,执行SQL -- 参数是接口文件的class对象
DeptDao dao = session.getMapper(DeptDao.class);//获取指定的接口
List<Dept> list = dao.getAll();//定位到了SQL
//5,遍历打印
for (Dept d : list) {
System.out.println(d);
}
}
//测试xml的方式开始
@Test
public void getAll() throws IOException {
//1,读取核心配置文件
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//2,创建会话工厂
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
//3,打开SQL会话
SqlSession session = factory.openSession();
//4,执行SQL -- 定位SQL的方式是namespace的值.id的值
List<User> list = session.selectList("userMapperNS.getAll");
//5,遍历list并打印
for (User u : list) {
System.out.println(u);
}
//Mybatis为了提高查询效率,会提供缓存的技术--减少了和数据库的交互次数
//当第一次查询数据时,缓存中当然没有,直接发起SQL查询了数据库,把数据存入缓存
//第二次查询 相同的数据时,先去查缓存,有就直接用,没有再去查数据库
//这是Mybatis默认就已经开启的一级缓存/SqlSession级别,必须是同一个SqlSession。
List<User> list2 = session.selectList("userMapperNS.getAll");
//5,遍历list并打印
for (User u : list2) {
System.out.println(u);
}
//根据id查询,selectOne()只返回一个结果
User u = session.selectOne("userMapperNS.getById");
System.out.println(u);
}
}
练习mybatis接口,查询car表里的所有数据。