Spring
-
描述:轻量级框架,是一个开源免费的框架 , 容器, 非侵入式的,总的来说:Spring是一个轻量级的控制反转(IoC)和面向切面(AOP)的容器(框架)。
-
Spring核心内容:IoC控制反转、DI依赖注入、Bean工厂、SpringAOP面向切面编程、事务控制
模块说明 -
核心容器Spring Core 核心容器提供Spring框架的基本功能。核心容器的主要组件是BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转(IOC)模式,将应用程序的配置和依赖性规范与实际的应用程序代码分开。
-
Spring上下文
Spring Context Spring上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。 -
Spring AOP 通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。可以很容易地使 Spring框架管理的任何对象支持AOP。Spring AOP模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
-
Spring DAO JDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
-
Spring ORM Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括JDO、Hibernate和iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
-
Spring Web Web上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以Spring 框架支持与 Jakarta Struts的集成。Web模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
-
Spring MVC框架 MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText 和 POI。
-
Java框架的分层:
- Dao层:数据库访问层,主要做数据库的交互工作,就是用来访问数据库实现数据的持久化
- Modle层: 是模型 存放你的实体类(数据库表的实体类);
- Service层:业务逻辑层, 做相应的业务逻辑处理
- Action层:业务层的一部分,是一个控制器(取出前台界面的数据,调用biz方法,转发到下一个action或者页面)
IOC控制反转
控制反转:IoC(Inversion of Control)简单来说就是将对象的创建的权力及对象的生命周期的管理过程交由Spring框架IOC容器来处理,从此在开发过程中不在需要关注对象的创建和生命周期的管理,更多的注业务的实现 ,耦合性大大降低, 在需要的时候由Spring框架管理对象创建和生命周期的机制称之为控制反转。
DI依赖注入
依赖注入:在创建对象的过程中Spring可以依据对象的关系,自动把其它对象注入(无需创建对象,直接拿着使用)进来,这个过程称之为DI(Dependency Injection)依赖注入。
AOP面向切面编程
- 描述:AOP (Aspect Orient Programming)面向切面编程是一种编程思想,是面向对象编程(OOP)的一种补充。面向对象编程将程序抽象成各个层次的对象,而面向切面编程是将程序抽象成各个切面。切面实现了横切关注点的模块化。
- 特点:
a. 它可以纵向编程,一下管理所有类
b. 可以随时加入,可随时移除
c. 代码没有侵入性,既完成使命,不改你类
d. 架构松耦合,加入和移除不会影响原来代码 - 本质:AOP不修改源代码的前提下,去为系统中的业务组件添加某种通用功能,Spring 中的 AOP 是通过动态代理实现的
- AOP 实现分类:
-
静态 AOP 实现: AOP 框架在编译阶段对程序源代码进行修改,生成了静态的 AOP 代理类(生成的 *.class 文件已经被改掉了,需要使用特定的编译器),比如 AspectJ。该机制称为静态织入,优点是对系统性能无影响,但灵活性不高
-
动态 AOP 实现: AOP 框架在运行阶段对动态生成代理对象(在内存中以 JDK 动态代理,或 CGlib 动态地生成 AOP 代理类),如SpringAOP,系统测试,试运行阶段,打印日志,执行方法耗时等等。灵活性高,切入的关注点需要实现接口,对系统有性能的影响,以下案例将测试方法的运行耗时。
-
模型对象
package cn.tedu.car.pojo;
//Model模型,View视图,Controller控制:MVC框架
//保时捷718 Cayman T,红色,641000元起
//POJO 它使用各个属性使用包装类型,和后期其它框架对接,简单java对象
public class Car {
private Integer id; //编号,718
private String name; //保时捷
private String type; //Cayman T
private String color; //红色
private Double price; //641000元
public Integer getId() { //获取id方法
return id;
}
public void setId(Integer id) { //设置id方法
this.id = id; //前面id类的属性,后面id参数
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public Double getPrice() {
return price;
}
public void setPrice(Double price) {
this.price = price;
}
@Override //这个就不是pojo中标准内容,它是为了调试方便,看对象中属性值
public String toString() {
return "Car [id=" + id + ", name=" + name + ", type=" + type + ", color=" + color + ", price=" + price + "]";
}
}
- Controller层
package cn.tedu.car.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.car.pojo.Car;
import cn.tedu.car.service.CarService;
//保时捷718 Cayman T,红色,641000元起
//@Controller //SpringMVC底层会创建这个对象实例,返回的java
@RestController //返回的java对象再次进行转换,json字符串
public class CarController {
@Autowired //carService对象直接在beans容器中,实现set注入
private CarService carService; //体现对象关联关系
//网页:http://localhost:8080/car/get
@RequestMapping("/car/get")
public Car get() {
System.out.println("car get");
return carService.get();
}
}
- Service层
package cn.tedu.car.service;
import cn.tedu.car.pojo.Car;
public interface CarService {
public Car get();
}
package cn.tedu.car.service;
import org.springframework.stereotype.Service;
import cn.tedu.car.pojo.Car;
@Service //标识,spring就会按service类进行初始化
public class CarServiceImpl implements CarService {
@Override
public Car get() {
// Repository、Database,模拟
Car car = new Car(); // 模型就是临时保存数据,在各层中传递
car.setId(718);
car.setName("保时捷");
car.setType("Cayman T");
car.setColor("红色");
car.setPrice(641000.0);
return car;
}
}
- 程序启动类RunApp
package cn.tedu.car;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//它必须放在controller类的父目录中,如果目录不对Controller不会加载(包扫描)
@SpringBootApplication
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class, args);
}
}
启动程序,返回响应到界面如下:
- 拦截器 interceptor实现切面模块编程
作用:拦截类的方法的执行 car/get方法
三点的
preHandle 方法执行之前
get controller层
postHandle 方法执行之后
complete 方法返回页面之前 - 实现步骤:
1)写拦截器 CarInterceptor/UserInterceptor,实现接口 HandlerInterceptor
2)告诉spring框架这个拦截器类,注册@Configuration,实现接口 WebMvcConfigurer
3)记录执行耗时,拦截器起作用
package cn.tedu.car.interceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
//实现WebMvcConfigurer接口
//@Configuration //告诉spring框架,我是一个配置类
public class SysInterceptorConfig implements WebMvcConfigurer{
@Autowired
private MyInterceptor myic;
@Autowired
private TimeInterceptor timeic;
@Override
public void addInterceptors(InterceptorRegistry registry) {
//注册自己写的拦截器,如果是多个拦截器,形成一个拦截器链
//拦截器链执行顺序,前面先后出
//myic.pre > timeic.pre > timeic.post > myic.post
registry.addInterceptor(myic);
registry.addInterceptor(timeic);
}
}
package cn.tedu.car.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component //实现HandlerInterceptor接口
public class MyInterceptor implements HandlerInterceptor{
//这里不提示它方法,alt+/快捷键生成
//业务方法执行之前
@Override //true代表放行,false代表拦截,后面代码都不会执行
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
System.out.println("我是拦截器 preHandle");
return true; //代表放行
}
@Override //业务方法执行之后
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
System.out.println("我是拦截器 postHandle");
}
@Override //返回页面之前
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
throws Exception {
System.out.println("我是拦截器 completion");
}
}
运行结果:
由此可见,拦截器放行之后,再执行controller层代码car/get,拦截器代理类起到了效果
package cn.tedu.car.interceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;
@Component //拦截所有方法,打印执行时间
public class TimeInterceptor implements HandlerInterceptor{
//现在写法有问题,高并发下,出错
//private long startTime; //定义成员变量,两个方法就可以共享这个变量
private ThreadLocal<Long> startTimeTL = new ThreadLocal<Long>();
//在类的不同方法中共享,而且避免线程安全!
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
long startTime = System.currentTimeMillis(); //记录当前系统时间,毫秒值,long
startTimeTL.set(startTime); //绑定自己的线程上,私有
return true; //放行
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
ModelAndView modelAndView) throws Exception {
long endTime = System.currentTimeMillis(); //再次记录当前时间
long startTime = startTimeTL.get();
startTimeTL.remove(); //移除,必须写,防止内存内存泄露
System.out.println(handler.toString()+" 执行耗时:" + (endTime-startTime) +" ms" );
}
}
代码的优化,将变量绑定在线程上,防止高并发下程序运行异常,而且避免了线程的安全
ApringAOP
- Spring核心特征中除了IoC控制反转、DI依赖注入,还有一个核心就是强大的面向切面编程AOP(Aspect Oriented Programming)的实现。
Sring AOP有三要素:
- Aspect定义切面;
- 通过通知(Advice)来指定具体做什么事情。如方法执行前做什么,方法执行后做什么,抛出异常做什么,从而实现对象行为(方法)的增强;
- 具体通过切点(PointCut)配置切点表达式(expression)来指定在哪些类的哪些方法上织入(ware)横切逻辑;被切的地方叫连接点(JoinPoint);
AOP 领域中的特性术语: - 通知(Advice): AOP 框架中的增强处理。通知描述了切面何时执行以及如何执行增强处理。
- 连接点(join point): 连接点表示应用执行过程中能够插入切面的一个点,这个点可以是方法的调用、异常的抛出。在 Spring AOP 中,连接点总是方法的调用。
- 切点(PointCut): 可以插入增强处理的连接点。
- 切面(Aspect): 切面是通知和切点的结合。
- 引入(Introduction):引入允许我们向现有的类添加新的方法或者属性。
- 织入(Weaving): 将增强处理添加到目标对象中,并创建一个被增强的对象,这个过程就是织入。
- 通知的执行顺序
Spring框架实现了AOP面向切面,其引入了第三方AspectJ框架来具体实现。AspectJ提供了五种切入方式,术语称为通知advice。
具体五种为:
1)前置通知before
2)后置通知after
3)环绕通知around
4)返回后通知afterReturning
5)异常通知afterThrowing。
异常通知特殊,这里暂不讨论。
可以看到,分别在业务方法(Business Method)的执行前后进行拦截,执行指定的代码
- 开发步骤
- 添加依赖,整合aspectJ
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-aop</artifactId>
</dependency>
- HelloController.java
package cn.tedu.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello() {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "hi aop";
}
@RequestMapping("/welcome")
public String welcome() {
try {
Thread.sleep(800);
} catch (InterruptedException e) {
e.printStackTrace();
}
return "welcome aop";
}
}
4.3.6TimeAspect.java
package cn.tedu.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component //组件,交给spring容器
@Aspect //切面
public class TimeAspect {
String methodName; //方法名
long startTime; //开始时间
//切点表达式,处理所有controller下包括其子目录中的*.*所有类的所有方法
//匹配所有目标类的public方法,第一个*为返回类型,第二个*为方法名
@Pointcut("execution( public * cn.tedu.controller..*.*(..))")
public void aopPointCut() {}
@Before("aopPointCut()") //前置通知,业务执行前
public void doBefore(JoinPoint joinPoint) {
methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
startTime = System.currentTimeMillis();
}
@After("aopPointCut()") //后置通知,业务执行后
public void doAfter() {
long endTime = System.currentTimeMillis() - startTime;
System.out.println("执行 " + methodName + " 耗时为:" + endTime + "ms");
}
//正常返回通知,返回后执行
@AfterReturning(returning = "object", pointcut = "aopPointCut()")
public void doAfterReturning(Object object) {
System.out.println("response={"+object.toString()+"}");
}
@Around("aopPointCut()") //环绕通知
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
try {
Object result = joinPoint.proceed(); //回调业务方法
long end = System.currentTimeMillis();
System.out.println("==around " + joinPoint + "\t耗时 : " + (end - start) + " ms!");
return result;
} catch (Throwable e) {
long end = System.currentTimeMillis();
System.out.println("==around " + joinPoint + "\t耗时 : " + (end - start) + " ms with exception : " + e.getMessage());
throw e;
}
}
}
- TimeAspect.java
package cn.tedu.aspect;
import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.After;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component //组件,交给spring容器
@Aspect //切面
public class TimeAspect {
String methodName; //方法名
long startTime; //开始时间
//切点表达式,处理所有controller下包括其子目录中的*.*所有类的所有方法
//匹配所有目标类的public方法,第一个*为返回类型,第二个*为方法名
@Pointcut("execution( public * cn.tedu.controller..*.*(..))")
public void aopPointCut() {}
@Before("aopPointCut()") //前置通知,业务执行前
public void doBefore(JoinPoint joinPoint) {
methodName = joinPoint.getSignature().getDeclaringTypeName() + "." + joinPoint.getSignature().getName();
startTime = System.currentTimeMillis();
}
@After("aopPointCut()") //后置通知,业务执行后
public void doAfter() {
long endTime = System.currentTimeMillis() - startTime;
System.out.println("执行 " + methodName + " 耗时为:" + endTime + "ms");
}
//正常返回通知,返回后执行
@AfterReturning(returning = "object", pointcut = "aopPointCut()")
public void doAfterReturning(Object object) {
System.out.println("response={"+object.toString()+"}");
}
@Around("aopPointCut()") //环绕通知
public Object doAround(ProceedingJoinPoint joinPoint) throws Throwable{
long start = System.currentTimeMillis();
try {
Object result = joinPoint.proceed(); //回调业务方法
long end = System.currentTimeMillis();
System.out.println("==around " + joinPoint + "\t耗时 : " + (end - start) + " ms!");
return result;
} catch (Throwable e) {
long end = System.currentTimeMillis();
System.out.println("==around " + joinPoint + "\t耗时 : " + (end - start) + " ms with exception : " + e.getMessage());
throw e;
}
}
}
- RunApp.java
package cn.tedu;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class RunApp {
public static void main(String[] args) {
SpringApplication.run(RunApp.class, args);
}
}
使用注解开发
-
@Autowired:自动装配,DI依赖注入,通过类型,名字,实现对象的关联关系,如果@Autowired不能唯一自动装配上属性,需要通过@Qualifier(value=“XXX”)装配
-
@Nullable 字段标记了这个注解,则说明这个字段可以为null
-
@Resource 自动装配上名字,类型
-
@Component 组件,放在类上,表示这个类被spring管理了 ,让spring进行对象的创建
@Component衍生注解:@Repository(dao层),@Service(service层),@Controller(controller层),@Mapper (Mybatis层) 作用是spring包扫描,创建对象实例,并放入容器
-
@Scope 作用域
-
@Value(“属性值”),为属性赋值,放在变量上以及SetName()方法上
-
@Configuration 配置类,相当于xml文件
-
@Controller,@RestController,对象被spring容器管理,后者具有注解标识@ResponseBody响应
-
@SpringBootApplication springboot 引导项目的启动,把所有的@Component,@Controller,@RestController,@Service修饰的类创建对象实例,初始化并放入容器
-
@ResquestMapping: springMVC提供,和浏览器上输入的URL进行匹配
-
@Test :Junit单元测试,用于方法上,方法必须public 和void
-
Retention:标识注解的运行阶段
Mybatis
mybatis半面向对象ORM框架
使用方法:把所有的sql语句写入xml文件中,ItemMapper.xml
select查询语句,id唯一表示语句,resultTYpe返回pojo对象,全限命名
底层自动查询sql,完成结果集,自动保存对象中,默认为list集合
Mybatis结构:
开发步骤:
1)准备数据库 jtdb-small.sql
2)创建pojo对象 Item.java
3)核心配置文件 sqlMapConfig.xml
4)写映射文件 ItemMapper.xml
测试类
读取配置文件:Resourses ibatis提供,返回InputStream
SqlSessionFactory factory = 读取sqlMapConfig.xml,builder创建工厂对象
SqlSession执行sql语句
statement = namespace.id(find)
按规则写完,mybatis会把这些按约定规则串接,底层执行xml里sql语句,最终映射到java对象
返回值java对象(model)
创建项目新增依赖:springboot官网产生pom.xml,增加mybatis/web/mysql驱动
创建两个核心配置文件:
DTD文件描述xml由哪些标签组成,它会和eclipse配置形成提示
1)sqlMapConfig.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="test"> <!--environments环境配置,default属性选择默认id-->
<environment id="test"> <!--environment id唯一标识-->
<!-- 事务:JDBC、MANAGE -->
<transactionManager type="JDBC"/>
<dataSource type="POOLED"> <!-- 数据源:UNPOOLED 非池化、POOLED 池化、JNDI 过气-->
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://localhost:3306/jtdb-small?
characterEncoding=utf8&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 告诉mybatis,映射文件存在 -->
<mappers>
<mapper resource="mappers/ItemMapper.xml"/>
</mappers>
</configuration>
- ItemMapper.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 = "cn.tedu.jt.mapper.ItemMapper"><!-- 命名空间 -->
<select id = "find" resultType = "cn.tedu.jt.pojo.Item">
select * from tb_item
</select> <!-- id唯一标识,resultType返回结果,默认List,返回在pojo模型中 -->
</mapper>
3).创建module对象
package cn.tedu.pojo;
import java.util.Date;
public class Item {
private Long id;//编号
private String title;//标题
private String sellPoint;//卖点
private Long price;//价格
private Integer num;//数量
private String barcode;//条形码
private String image;//图片地址
private Integer cid;//所述分类
private Integer status;//状态:1正常,2下架
private Date created;//创建时间
private Date updated;//修改时间
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getSellPoint() {
return sellPoint;
}
public void setSellPoint(String sellPoint) {
this.sellPoint = sellPoint;
}
public Long getPrice() {
return price;
}
public void setPrice(Long price) {
this.price = price;
}
public Integer getNum() {
return num;
}
public void setNum(Integer num) {
this.num = num;
}
public String getBarcode() {
return barcode;
}
public void setBarcode(String barcode) {
this.barcode = barcode;
}
public String getImage() {
return image;
}
public void setImage(String image) {
this.image = image;
}
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public Date getCreated() {
return created;
}
public void setCreated(Date created) {
this.created = created;
}
public Date getUpdated() {
return updated;
}
public void setUpdated(Date updated) {
this.updated = updated;
}
@Override
public String toString() {
return "返回结果Item [id=" + id + ", title=" + title + ", sellPoint=" + sellPoint + ", price=" + price + ", num=" + num
+ ", barcode=" + barcode + ", image=" + image + ", cid=" + cid + ", status=" + status + ", created="
+ created + ", updated=" + updated + "]";
}
}
4).测试类
package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
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 cn.tedu.pojo.Item;
public class TestMybatis {
@Test
public void mybatis() throws IOException {
//读取流读取资源文件
InputStream is
= Resources.getResourceAsStream("sqlMapConfig.xml");//Resources类加载文件
//创建工厂文件, ibatis提供,传入资源文件
SqlSessionFactory factory
= new SqlSessionFactoryBuilder().build(is);
//创建SqlSession对象
SqlSession session = factory.openSession();
String statement = "cn.tedu.jt.mapper.ItemMapper.find";
//namespace.id 找到对应<select>标签
//mybatis,它会去找<select>标签,sql语句执行ResultSet,自动映射List<Item>
List<Item> list = session.selectList(statement);
for(Item o : list) {
System.out.println(o);
}
}
}
运行结果
有些没有获取到,是因为java属性与sql字段不一样,
解决方法:
sql自身解决:1。 改sql语句:select t.*,t.sell_point AS sellPoint from tb_item t
2.。写映射规则:resultMap
<?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 = "cn.tedu.jt.mapper.ItemMapper"><!-- 命名空间 -->
<!-- id属性,必须在这个命名空间下唯一
resultType 返回值类型,如果集合List,只写集合中元素类型
resultMap 先的构造映射规则,然后select标签引用新的规则
-->
<!-- 定义映射规则,创建ResultMap标签,
type类型,指封装的pojo对象名称
id就是一个命名在这个文件中唯一,
-->
<resultMap type="cn.tedu.pojo.Item" id="itemRM">
<result property="sellPoint" column="sell_point"/>
</resultMap>
<select id = "find" resultMap = "itemRM">
select * from tb_item
</select> <!-- id唯一标识,resultType返回结果,默认List,返回在pojo模型中 -->
</mapper>