怎么学:学习spring框架的设计思想;学习基础操作;学习案例
在不惊动原始设计的基础上为其进行功能增强
IOC入门案例:
导入spring的坐标spring-context
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
定义spring管理的类
public interface BookService {
public void save();
}
public class BookServiceImpl implements BookService {
private BookDao bookDao = new BookDaoImpl();
@Override
public void save() {
bookDao.save();
System.out.println("book service save...");
}
}
创建spring配置文件,配置bean
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--id属性给bean起名字,class属性表示给bean定义类型-->
<bean id="bookDao" class="com.xin.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.xin.service.impl.BookServiceImpl"></bean>
</beans>
初始化Ioc容器,通过容器获取bean
public static void main(String[] args) {
//获取IOC容器
ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = (BookService) ctx.getBean("bookService");
bookService.save();
}
}
DI入门案例:
删除使用new的形式创建对象的代码
public class BookServiceImpl implements BookService {
private BookDao bookDao;
@Override
public void save() {
bookDao.save();
System.out.println("book service save...");
}
}
提供依赖对象对应的setter方法
public class BookServiceImpl implements BookService {
private BookDao bookDao;
@Override
public void save() {
bookDao.save();
System.out.println("book service save...");
}
public void setBookDao(BookDao bookDao) {
this.bookDao = bookDao;
}
}
配置service和dao之间的关系
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--id属性给bean起名字,class属性表示给bean定义类型-->
<bean id="bookDao" class="com.xin.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.xin.service.impl.BookServiceImpl">
<!--配置service与dao的关系-->
<!--property标签表示配置当前bean的属性
name属性表示配置哪一个具体的属性
ref属性表示参照哪一个bean
-->
<property name="bookDao" ref="bookDao"></property>
</bean>
</beans>
起别名
在写Spring配置文件的时候,也可以使用name属性来给bean起多个名称(别名),这样就可以使用配置的其他名称来使用bean,需要注意的是,要使用的别名必须在spring配置文件中被定义,否则会抛出一个异常,起多个别名的时候可以使用逗号(,)封号(;)空格( )隔开
作用范围
spring默认提供的bean对象是单例的,也就是说如果使用getbean获取同一个bean,获取两次并直接将该对象打印的时候,会发现两个对象的地址值是相同的,但是开发环境中有时候需要创建非单例的对象,这个时候就需要给bean配置一个作用范围了(scope)
bean本质上就是对象
构造方法:提供可访问的构造方法(无参构造方法)
通过静态工厂创建对象
//静态工厂
public class BookDaoFactory {
public static BookDao getBookDao(){
return new BookDaoImpl();
}
}
//配置
<bean id="bookDao1" factory-method="getBookDao" class="com.xin.factory.BookDaoFactory"></bean>
实例工厂创建
//实例工厂
public class BookDaoFactory {
public BookDao getBookDao(){
return new BookDaoImpl();
}
}
//配置:先将工厂bean配置出来
<bean id="bookFactory" class="com.xin.factory.BookDaoFactory"></bean>
<bean id="bookDao2" factory-method="getBookDao" factory-bean="bookFactory"></bean>
FactoryBean 代替原始实例工厂中创建对象的方法,默认是单例的
public class BookDaoFactoryBean implements FactoryBean<BookDao> {
@Override
public BookDao getObject() throws Exception {
return new BookDaoImpl();
}
@Override
public Class<?> getObjectType() {
return BookDao.class;
}
@Override
public boolean isSingleton() {
return false;
}
}
<bean id="bookDao3" class="com.xin.factory.BookDaoFactoryBean"></bean>
bean的生命周期:bean从创建到销毁的整个过程
bean的生命周期控制:在bean创建后到销毁前做一些事情
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println("book dao save...");
}
public void init(){
System.out.println("init...");
}
public void destroy(){
System.out.println("destroy...");
}
}
<bean id="bookDao" class="com.xin.dao.impl.BookDaoImpl" init-method="init" destroy-method="destroy"></bean>
Ⅰ.初始化容器
Ⅱ.使用bean
Ⅲ.关闭/销毁容器
setter注入
//在bean中定义引用类型属性并提供可访问的set方法
public class BookDaoImpl implements BookDao {
private int number;
public void setNumber(int number) {
this.number = number;
}
}
//配置中使用property标签value属性注入简单类型数据
<bean id="bookDao" class="com.xin.dao.impl.BookDaoImpl">
<property name="number" value="100"></property>
</bean>
构造器注入
<bean id="bookDao" class="com.xin.dao.impl.BookDaoImpl"></bean>
<bean id="bookService" class="com.xin.service.impl.BookServiceImpl">
<!--name为构造器形参变量名-->
<constructor-arg name="bookDao" ref="bookDao"></constructor-arg>
</bean>
Ioc容器根据bean所依赖的资源在容器中自动查找并注入到bean中的过程
<bean id="programmer" class="com.model.Programmer">
<property name="cars">
<!-- 1. list数据注入 //有序集合-->
<list>
<value>ofo</value>
<value>mobai</value>
<value>宝马</value>
</list>
</property>
<property name="pats">
<!-- 2. set数据注入 //无序集合-->
<set>
<value>小黑</value>
<value>小红</value>
<value>小白</value>
</set>
</property>
<property name="infos">
<!-- 3. map数据注入 -->
<map>
<entry key="name" value="cjx"></entry>
<entry key="age" value="23"></entry>
<entry key="id" value="20821111355"></entry>
</map>
</property>
<property name="mysqlInfos">
<!-- 4. properties数据注入 //实际也是set类型是无序的-->
<props>
<prop key="url">mysql:jdbc://localhost:3306/dbname</prop>
<prop key="user">root</prop>
<prop key="password">123456</prop>
</props>
</property>
<property name="numbers">
<!-- 5. 数组的数据注入 -->
<array>
<value>哥哥</value>
<value>弟弟</value>
<value>妹妹</value>
<value>姐姐</value>
</array>
</property>
</bean>
spring加载properties文件:
开启context命名空间
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
使用context命名空间加载properties文件
<context:property-placeholder location="classpath:*.properties"/>
使用属性占位符${}读取properties文件中的属性
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}"></property>
<property name="url" value="${jdbc.url}"></property>
<property name="username" value="${jdbc.username}"></property>
<property name="password" value="${jdbc.password}"></property>
</bean>
注解开发定义bean:
使用@Component定义bean
@Component("userDao")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("user save...");
}
}
@Component("userDao") 等价于在核心配置文件中
<bean id="bookDao" class="com.xin.dao.impl.BookDaoImpl"></bean>
核心配置文件中通过组件扫描加载bean
<!--扫描基于注解的方式配置bean-->
<context:component-scan base-package="com.xin.dao.impl"/>
spring提供@Component注解的三个衍生注解,方便理解:
纯注解开发:
用配置类代替xml配置
@Configuration
@ComponentScan("com.xin")
public class SpringConfig {}
使用配置类加载spring容器
public class AppForAnnotation {
public static void main(String[] args) {
ApplicationContext ctx = new AnnotationConfigApplicationContext(SpringConfig.class);
UserDao userDao = (UserDao) ctx.getBean("userDao");
userDao.save();
}
}
@Component("userDao")
@Scope("prototype")
public class UserDaoImpl implements UserDao {
@Override
public void save() {
System.out.println("user save...");
}
@PostConstruct
public void init() {
System.out.println("init...");
}
@PreDestroy
public void destroy() {
System.out.println("destroy...");
}
}
使用@Autowired注解开启自动装配模式,使用@Qualifier注解开启指定名称装配bean
@Service
public class UserServiceImpl implements UserService {
@Autowired
//多个userDaoImpl,即多个相同类型的bean
@Qualifier("userDao")
private UserDao userDao;
@Override
public void save() {
System.out.println("user service save...");
userDao.save();
}
}
将独立的配置类加入核心配置
public class JdbcConfig {
// 1.定义一个方法获得要管理的对象
// 2.添加@Bean,表示当前方法的返回值是一个bean
@Bean
public DataSource dataSource() {
DruidDataSource ds = new DruidDataSource();
ds.setDriverClassName("com.mysql.jc.jdbc.Driver");
ds.setUrl("");
ds.setUsername("");
ds.setPassword("");
return ds;
}
}
@Configuration
@Import(JdbcConfig.class)
public class SpringConfig {
}
第三方bean依赖注入
引入坐标
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.3.0</version>
</dependency>`
设置配置类
@Configuration
@ComponentScan("com.xin")
@PropertySource("jdbc.properties")
@Import({JdbcConfig.class, MybatisConfig.class})
public class SpringConfig {}
public class MybatisConfig {
@Bean
public SqlSessionFactoryBean sqlSessionFactory(DataSource dataSource) {
SqlSessionFactoryBean sfb = new SqlSessionFactoryBean();
sfb.setTypeAliasesPackage("com.xin.pojo");
sfb.setDataSource(dataSource);
//设置驼峰命名
Configuration configuration = new Configuration();
configuration.setMapUnderscoreToCamelCase(true);
sfb.setConfiguration(configuration);
return sfb;
}
@Bean
public MapperScannerConfigurer mapperScannerConfigurer() {
MapperScannerConfigurer configurer = new MapperScannerConfigurer();
configurer.setBasePackage("com.xin.dao");
return configurer;
}
}
//引入坐标
<!--整合junit-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
//编写测试类
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = SpringConfig.class)
public class UserServiceTest {
@Autowired
private UserService userService;
@Test
public void testSelectAll() {
System.out.println(userService.selectAll());
}
}
面向切面编程,在不惊动原始设计的基础上为其进行功能增强
连接点 ( JoinPoint)∶程序执行过程中的任意位置,粒度为执行方法、抛出异常、设置变量等,在SpringAOP中理解为方法的执行
切入点(Pointcut ) :匹配连接点的式子
通知( Advice ) :在切入点处执行的操作,也就是共性功能
通知类:定义通知的类
切面(Aspect ):描述通知与切入点的对应关系
导入aop相关坐标
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.2.10.RELEASE</version>
</dependency>
<dependency>
<groupId>org.aspectj</groupId>
<artifactId>aspectjweaver</artifactId>
<version>1.8.7</version>
</dependency>
定义接口和实现类
public interface BookDao {
public void save();
public void update();
}
@Repository
public class BookDaoImpl implements BookDao {
@Override
public void save() {
System.out.println(System.currentTimeMillis());
System.out.println("book dao save...");
}
@Override
public void update() {
System.out.println("book dao update...");
}
}
定义通知类,切入点,绑定切入点和通知关系
@Component
@Aspect
public class MyAdvice {
//定义切入点
@Pointcut("execution(void com.xin.dao.BookDao.update())")
private void pt() {
}
//绑定切入点和功能的关系
@Before("pt()")
public void method() {
System.out.println(System.currentTimeMillis());
}
}
开启spring对aop注解驱动支持
@Configuration
@ComponentScan("com.xin")
@EnableAspectJAutoProxy
public class SpringConfig {
}
标准格式:动作关键字(访问修饰符 返回值 包名.类/接口名.方法名(参数)异常名)
@Pointcut("execution(void com.xin.dao.BookDao.update())")
使用通配符描述切入点:
建议:
前置通知@Before:在切入点方法调用之前执行的通知。
后置通知@After:在切入点方法调用之后执行的通知。(无法与异常通知同时执行)
环绕通知@Around:设置当前通知方法与切入点之间的绑定关系,当前通知方法在原始切入点方法前后运行
@Around("pt()")
public Object around(ProceedingJoinPoint point) throws Throwable {
System.out.println("around before advice...");
Object proceed = point.proceed();
System.out.println("around after advice...");
return proceed;
}
异常通知@AfterThrowing:在程序发生异常时执行的通知。(无法与后置通知同时执行)
最终通知@AfterReturning:切入点方法调用之后执行的通知,与后置通知不同的是,无论切入点方法是否正常执行都会执行该通知。
场景一: 记录日志
场景二: 监控方法运行时间 (监控性能)
场景三: 权限控制
场景四: 缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )
场景五: 事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )
事务的作用:在数据层保障一系列的数据库操作同成功同失败
spring事务的作用:在数据层或业务层保障一系列的数据库操作同成功同失败
快速入门:
导入坐标
<!--1.导入坐标springmvc与servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>5.3.15</version>
</dependency>
创建springmvc控制器类
@Controller
public class UserController {
@RequestMapping("/save")
@ResponseBody
public String save() {
System.out.println("user save...");
return "{'module':'springmvc'}";
}
}
初始化springmvc环境,设定springmvc对应的bean
//3.创建springmvc的配置文件,加载controller对应的bean
@Configuration
@ComponentScan("com.xin.controller")
public class SpringMvcConfig {
}
初始化servlet容器,加载springmvc环境,并设置springmvc技术处理的请求
//4,定义一个servlet容器启动的配置类,在里面加载spring的配置
public class ServletContainersInitConfig extends AbstractDispatcherServletInitializer {
//加载springmvc容器配置
@Override
protected WebApplicationContext createServletApplicationContext() {
AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext();
ctx.register(SpringMvcConfig.class);
return ctx;
}
//设置哪些请求归属springmvc处理
@Override
protected String[] getServletMappings() {
return new String[]{"/"};
}
//加载spring容器配置
@Override
protected WebApplicationContext createRootApplicationContext() {
return null;
}
}
@RequestBody与@RequestParam区别
REST表示访问资源的格式,隐藏了资源访问行为
使用行为动作区分对资源进行的操作
根据REST风格对资源进行访问叫做RESTful
@RequestMapping(value = "/users", method = RequestMethod.POST)
@ResponseBody
public String save(@RequestBody User user) {
System.out.println("user save..." + user);
return "{'module':'user save'}";
}
@RequestMapping(value = "/users", method = RequestMethod.PUT)
@ResponseBody
public String update(@RequestBody User user) {
System.out.println("user update..." + user);
return "{'module':'user update'}";
}
@RequestMapping(value = "/users/{id}", method = RequestMethod.DELETE)
@ResponseBody
public String delete(@PathVariable Integer id) {
System.out.println("user delete..." + id);
return "{'module':'user delete'}";
}
SSM整合流程
创建工程
SSM整合
功能模块
设置同一数据返回结果类:
public class Result {
private Integer code;
private Object data;
private String msg;
}
设置统一数据返回结果编码:
public class Code {
public static final Integer SAVE_OK = 20011;
public static final Integer DELETE_OK = 20021;
public static final Integer UPDATE_OK = 20031;
public static final Integer GET_OK = 20041;
public static final Integer SAVE_ERR = 20010;
public static final Integer DELETE_ERR = 20020;
public static final Integer UPDATE_ERR = 20030;
public static final Integer GET_ERR = 20040;
}
异常处理器:便于快速统一地处理异常
@RestControllerAdvice
public class ProjectExceptionAdvice {
@ExceptionHandler(Exception.class)
public Result doException(Exception ex) {
return new Result(500, null, "出错了");
}
}
自定义异常:程序出现异常抛出自定义异常
public class SystemException extends RuntimeException {
private Integer code;
public SystemException(Integer code) {
this.code = code;
}
public SystemException(Integer code, String message) {
super(message);
this.code = code;
}
public SystemException(Integer code, String message, Throwable cause) {
super(message, cause);
this.code = code;
}
}
一种动态拦截方法调用地机制,在springmvc中动态拦截控制器方法的执行
作用:
拦截器和过滤器的区别
@Component
public class ProjectInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
return HandlerInterceptor.super.preHandle(request, response, handler);
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
}
}
分模块开发
将原生模块按照功能拆分成若干个子模块,方便模块间的相互调用,接口共享
步骤:
依赖传递:
依赖冲突:
依赖管理:
聚合和继承
maven-parent:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xin</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--1.父工程的打包方式为pom-->
<packaging>pom</packaging>
<modules>
<module>../maven-dao</module>
</modules>
<!--2.在父工程的pom文件中配置依赖关系,子工程将沿用父工程中的依赖关系-->
<dependencies>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.5</version>
</dependency>
</dependencies>
<!--3.配置子工程中可选的依赖关系-->
<dependencyManagement>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
</dependencies>
</dependencyManagement>
</project>
maven-dao:
<?xml version="1.0" encoding="UTF-8"?>
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xin</groupId>
<artifactId>maven-dao</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<!--4.在子工程中配置当前工程所继承的父工程-->
<parent>
<groupId>com.xin</groupId>
<artifactId>maven-parent</artifactId>
<version>1.0-SNAPSHOT</version>
<!--快速找到对应的parent-->
<relativePath>../maven-parent/pom.xml</relativePath>
</parent>
<dependencies>
<!--5.在子工程中配置使用父工程中可选依赖的坐标-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
</project>
多环境开发
<!--配置多环境-->
<profiles>
<!--开发环境-->
<profile>
<id>env_dep</id>
<properties>
<jdbc.url>jdbc:mysql://127.0.0.1:3306/db</jdbc.url>
</properties>
<activation>
<!--设定是否为默认启动环境-->
<activeByDefault>true</activeByDefault>
</activation>
</profile>
<!--生产环境-->
<profile>
<id>env_pro</id>
<properties>
<jdbc.url>jdbc:mysql://127.0.0.2:3306/db</jdbc.url>
</properties>
</profile>
<!--测试环境-->
<profile>
<id>env_test</id>
<properties>
<jdbc.url>jdbc:mysql://127.0.0.3:3306/db</jdbc.url>
</properties>
</profile>
</profiles>
私服:
MP是基于MyBatis框架基础上开发的增强型工具,旨在简化开发、提高效率
入门案例:
导依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.16</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.26</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.1</version>
</dependency>
</dependencies>
配置yml
spring:
datasource:
type: com.alibaba.druid.pool.DruidDataSource
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test1
username: root
password: 123456
mybatis-plus:
global-config:
db-config:
table-prefix: tb_
id-type: auto #开启主键id自增
configuration:
#开启日志详细过程,方便调试
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
制作实体类
定义数据接口,继承BaseMapper
使用mybatis-plus进行分页操作:mybatisplus的分页实现其实是借助了拦截器的拦截功能,在查询之前进行了两次拦截,最终完成封装操作
写一个mybatis-plus配置类进行拦截器操作
@Configuration
public class MPConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
return interceptor;
}
}
接口测试,执行分页查询
@Test
void testPage() {
IPage page = new Page(1, 3);
bookDao.selectPage(page, null);
System.out.println(page.getCurrent());//当前页码
System.out.println(page.getSize());//页面大小,一页多少数据
System.out.println(page.getTotal());//所有记录数
System.out.println(page.getPages());//一共页码数
System.out.println(page.getRecords());//数据总数
}
条件查询:使用QueryWrapper或者LambdaQueryWrapper对象封装查询条件
@Test
void testQuery() {
String type = "计算机";
//方式一:按条件查询
QueryWrapper qw = new QueryWrapper<>();
qw.like(type != null, "type", type);
bookDao.selectList(qw);
//方式二:lambda格式按条件查询(推荐)
QueryWrapper qw2 = new QueryWrapper<>();
qw.lambda.like(type != null, Book::getType, type);
bookDao.selectList(qw2);
//方式三:lambda格式按条件查询(推荐)
LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
lqw.like(type != null, Book::getType, type);
bookDao.selectList(lqw);
}
查询结果包含模型类中的部分属性:
LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
//查询显示部分字段信息
lqw.select(Book::getId, Book::getName, Book::getType);
List books = bookDao.selectList(lqw);
System.out.println(books);
查询结果包含模型类中未定义的属性:
QueryWrapper qw = new QueryWrapper<>();
qw.select("count(*) as count,type").groupBy("type");
List
LambdaQueryWrapper lqw = new LambdaQueryWrapper<>();
//等同于=
lqw.eq(Book::getName, "生活大爆炸").eq(Book::getType, "生活百科");
Book book = bookDao.selectOne(lqw);
System.out.println(book);
//范围查询 lt le gt ge eq between
lqw.between(Book::getId,1,10);
List books = bookDao.selectList(lqw);
System.out.println(books);
//模糊查询 like
lqw.like(Book::getName,"2");
表字段与编码属性设计不同步:@TableField(value=“xxx”)
编码中添加了数据库中未定义的属性:@TableField(exist=false)
采用默认查询开放了更多的字段查看权限:@TableField(value=“xxx”,select=false)
表名与编码开发设计不同步:@TableName(“xxx”)
id生成策略控制:@TableId(type = IdType.xxx)
按照主键删除多条记录:
List ids = Arrays.asList(new Long[]{2L, 3L});
bookDao.deleteBatchIds(ids);
根据主键查询多条记录:
List ids = Arrays.asList(new Long[]{2L, 3L});
List books = bookDao.selectBatchIds(ids);
逻辑删除:并不是真正的将数据删除而是将数据做上标记
实体类中添加对应字段,并设定当前字段为逻辑删除标记字段:@TableLogic(value=“1”,delval=“0”)
配置逻辑删除字面值
mybatis-plus:
global-config:
db-config:
logic-delete-field: deleted
logic-not-delete-value: 0
logic-delete-value: 1
乐观锁:@Version
@Configuration
public class MpConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
//1.定义MP拦截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
//2.添加具体的拦截器
interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
//3.添加乐观锁拦截器
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
return interceptor;
}
}
步骤:
导入依赖:
com.baomidou
mybatis-plus-generator
3.5.1
org.apache.velocity
velocity
1.7
编写生成代码工具类:
public class CodeGenerator {
//直接运行帮我们生成代码
public static void main(String[] args) {
/**
* 第一步: 使用代码生成器
*/
//怎么用代码生成器呢?
// 1.创建代码生成器对象
// 2.执行代码生成器 //mp包里面的AutoGenerator
AutoGenerator autoGenerator = new AutoGenerator();
// 告诉它怎么生成,在哪生成
//datasource数据源配置
DataSourceConfig dataSource = new DataSourceConfig();
dataSource.setDriverName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/mybatisplus_db?serverTimezone=UTC");
dataSource.setUsername("root");
dataSource.setPassword("123456");
autoGenerator.setDataSource(dataSource);
//会在D盘生成一个com文件,但是这个位置是不对的,需要我们再进一步配置
/**
* 第二步: 设置全局配置
*/
GlobalConfig globalConfig = new GlobalConfig();
//默认输出D盘根下,设置到这一目录下 mybatis_04-generator/src/main/java
globalConfig.setOutputDir(System.getProperty("user.dir")+"/mybatis_04-generator/src/main/java");
//globalConfig.setOutputDir(System.getProperty("user.dir")+"\\src\\main\\java");
// \\src\\main\\java
//设置完之后是否打开资源管理器 NO
globalConfig.setOpen(false);
//设置作者
globalConfig.setAuthor("黑马程序员");
//设置是否覆盖原始生成的文件
globalConfig.setFileOverride(true);
//设置数据层接口名,%s为占位符 代表数据库中的表名或模块名
globalConfig.setMapperName("%sDao");
//设置id生成策略
globalConfig.setIdType(IdType.ASSIGN_ID);
autoGenerator.setGlobalConfig(globalConfig);
/**
* 第三步: 设置包名相关配置
*/
PackageConfig packageConfig =new PackageConfig();
//设置生成的包名,与代码所在位置不冲突,二者叠加组成完整路径
packageConfig.setParent("com.aaa");
//设置实体类包名
packageConfig.setEntity("domain");
//设置数据层包名
packageConfig.setMapper("dao");
autoGenerator.setPackageInfo(packageConfig);
/**
* 第四步: 策略设置
*/
StrategyConfig strategyConfig = new StrategyConfig();
//设置当前参与生成的表名,参数为可变参数 生成指定表
strategyConfig.setInclude("tbl_user");
//设置数据库表的前缀名称,模块名=数据库表名-前缀名 User=tbl_user - tbl_
strategyConfig.setTablePrefix("tbl_");
//是否启用Rest风格
strategyConfig.setRestControllerStyle(true);
//设置乐观锁字段名
strategyConfig.setVersionFieldName("version");
//设置逻辑删除字段名
strategyConfig.setLogicDeleteFieldName("deleted");
//设置是否启用Lombok
strategyConfig.setEntityLombokModel(true);
autoGenerator.setStrategy(strategyConfig);
autoGenerator.execute();//执行
}
}