Spring事务
事务回滚
@Transactional(rollbackFor = Exception.class)//加在方法上,当前方法开启事务标准写法
事务配置
1.方法上加上@Transactional(rollbackFor=Exception)
2.配置类加上@EnableTransactionManagement和DataSourceTransactionManager bean
@Service
public class AccountServiceImpl implements AccountService {
@Autowired
private AccountMapper accountMapper;
@Override
// @Transactional(rollbackFor = Exception.class)标准写法
@Transactional(rollbackFor = Exception.class)//加在方法上,当前方法开启事务
public void transfer(String out,String in,Float money) throws Exception {
//1 扣钱
accountMapper.subtract(out, money);
//模拟异常
if(true){
throw new Exception();
}
//2 加钱
accountMapper.add(in, money);
}
}
package com.itheima.config;
import com.alibaba.druid.pool.DruidDataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.mapper.MapperScannerConfigurer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.EnableAspectJAutoProxy;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
//配置类
@ComponentScan("com.itheima")
@EnableTransactionManagement//开启事务
public class SpringConfig {
//配置mapper位置
@Bean
public MapperScannerConfigurer scannerConfigurer(){
MapperScannerConfigurer scannerConfigurer = new MapperScannerConfigurer();
scannerConfigurer.setBasePackage("com.itheima.mapper");//设置接口包位置
return scannerConfigurer;
}
//配置数据源
@Bean
public DruidDataSource dataSource(){
DruidDataSource dataSource = new DruidDataSource();
dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
dataSource.setUrl("jdbc:mysql://localhost:3306/t3");
dataSource.setUsername("root");
dataSource.setPassword("root");
return dataSource;
}
//配置SqlSessionFactory
@Bean
public SqlSessionFactoryBean sqlSessionFactoryBean(DruidDataSource dataSource){
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setDataSource(dataSource);//设置数据源
return sqlSessionFactoryBean;
}
@Bean
//把数据库事务管理器加入IOC容器
public DataSourceTransactionManager transactionManager(DruidDataSource dataSource){
DataSourceTransactionManager manager = new DataSourceTransactionManager();
manager.setDataSource(dataSource);
return manager;
}
}
SpringMvc
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private String username;
private int age;
}
package com.itheima.controller;
import com.itheima.domain.User;
import lombok.Data;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
//@Controller
//@RestController=@Controller+@ResponseBody类的所有方法都自动加入@ResponseBody
@RestController
public class UserController {
@RequestMapping("/user/demo1")//给当前方法绑定一个请求地址
@ResponseBody//把返回值(对象)转为json格式
public User demo1(String username, int password){
System.out.println(username);
System.out.println(password);
User user = new User(username,password);
return user;
}
@RequestMapping(value = "/user/demo2",method={RequestMethod.GET,RequestMethod.POST})//给当前方法绑定一个请求地址
@ResponseBody//把返回值(对象)转为json格式
public User demo2(String username, int age){
System.out.println(username);
System.out.println(age);
User user = new User(username,age);
return user;
}
//method指定请求方式,如果没写method默认全部都支持,但几乎不这样写
@RequestMapping(value ={"/demo3","/demo4"})
@ResponseBody
public User demo03(String username,int age){
return new User(username,age);
}
//简单类型参数:前端参数名称和方法形参名称一致
@RequestMapping("/user/demo5")
public String demo5(String username,Integer age){
System.out.println("name"+username+"age"+age);
return "OK";
}
//对象类型:前端传的参数和方法参数对象的属性一致
@RequestMapping("/user/demo6")
public String demo06(User user){
System.out.println(user);
return "OK";
}
//数组类型 :前端参数和方法的形参对象的属性一致
@RequestMapping("/user/demo7")
public String demo07(@RequestParam("hobby") String[] hobby){
System.out.println(Arrays.toString(hobby));
return "OK";
}
//集合类型:前端参数 和方法形参一致
//@RequestParam("xxx"):建立前端参数 和 方法形参的映射关系
@RequestMapping("/user/demo8")
public String demo8(@RequestParam("hobby") List<String> hobby){
System.out.println(hobby);
return "OK";
}
//日期类型 :使用@DateTimeFormat(pattern="自定义日期格式")
@RequestMapping("/user/demo9")
public String demo9(@DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") Date updateTime){
System.out.println(updateTime);
return "OK";
}
@RequestMapping("/user/demo10")
//@RequestBody自动介绍json类型字符串,转成对象
public String demo10(@RequestBody User user){
System.out.println(user);
return "OK";
}
//map可以接收json类型参数,但不推荐
@RequestMapping("/user/demo11")
public String demo11(@RequestBody Map<String ,Object> map){
System.out.println(map.get("name"));
System.out.println(map.get("age"));
return "OK";
}
//路径参数
//@PathVariable("xxx")从请求路径上获取参数
@RequestMapping("/user/demo12/name/{name}/age/{age}")
public String demo12(@PathVariable("name") String name,
@PathVariable("age") int age){
//localhost:8080/user/demo12/name/kun/age/18
System.out.println("name"+name+",age"+age);
return "OK";
}
//@RequestParam 使用场景
//1 请求参数名 和 方法参数名不一致 可用Value
//2 参数可要可不要 required = false
//3 参数赋默认值 defaultValue="xxx"
//4 接收List参数
@RequestMapping("/user/demo13")
//required=false :可要可不要
public String demo13(@RequestParam(value = "name",required = false)String name,
@RequestParam(value = "age",defaultValue="18")int age){
System.out.println(name);
System.out.println(age);
return "OK";
}
}
如果不想传递参数把required=false即可
SpringBoot
配置类
# 大小写敏感
# 缩进代表
# 参数值和冒号一定要有空格
# #代表注解
server:
port: 8081
servlet:
context-path: /itheima
# 对象:键值对的集合
user:
username: '张三'
password: '123456'
addressList: #数组:固定写法
- '杭州'
- '北京'
- '上海'
读取配置一
@RestController
public class IndexController {
@Value("${配置路径}"):读取配置
@Value("${user.username}")
private String username;
@Value("${user.password}")
private String password;
@Autowired
@GetMapping("/index")
public String index(){
System.out.println(username);
System.out.println(password);
return "hello spring boot";
}
}
读取配置二
@RestController
public class IndexController {
@Autowired
private UserConfig userConfig;
@GetMapping("/index")
public String index(){
System.out.println(userConfig);
return "hello spring boot";
}
}
springBoot增删改查完整步骤
Student类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {
private Long id;
private String number;
private String userName;
//格式转换 设置时间东八区
@JsonFormat(pattern = "yyyy-MM-dd",timezone = "Asia/Shanghai")
private Date birthday;
private String address;
}
StudentMapper类
package com.itheima.mapper;
import com.itheima.domain.Student;
import org.apache.ibatis.annotations.*;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.PathVariable;
import java.util.List;
@Mapper
@Repository//避免报错
public interface StudentMapper {
@Select("select id,number,user_name,birthday,address from tb_student")
List<Student> findAll();
@Delete("delete from tb_student where id=#{id}")
void deleteById(@Param("id") Long id);
@Select("select id,number ,user_name,birthday,address from tb_student where id=#{id}")
Student findById(@Param("id") Long id);
@Update("update tb_student set number = #{student.number},user_name = #{student.userName}," +
"birthday=#{student.birthday},address=#{student.address} where id = #{student.id}")
void updateById(@Param("student") Student student);
@Insert("insert into tb_student values (#{student.id},#{student.number},#{student.userName}," +
"#{student.birthday},#{student.address})")
void addById(@Param("student") Student student);
}
StudentService类
package com.itheima.Service;
import com.itheima.domain.Student;
import java.util.List;
public interface StudentService {
List<Student> findAll();
void deleteById (Long id);
Student findById(Long id);
void updateById(Student student);
void addById(Student student);
}
StudentServiceImpl类
package com.itheima.Service.impl;
import com.itheima.Service.StudentService;
import com.itheima.domain.Student;
import com.itheima.mapper.StudentMapper;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@Mapper
public class StudentServiceImpl implements StudentService {
@Autowired
private StudentMapper studentMapper;
@Override
public List<Student> findAll(){
return studentMapper.findAll();
}
@Override
public void deleteById(Long id) {
studentMapper.deleteById(id);
}
@Override
public Student findById(Long id) {
return studentMapper.findById(id);
}
@Override
public void updateById(Student student) {
studentMapper.updateById(student);
}
@Override
public void addById(Student student) {
studentMapper.addById(student);
}
}
Result类
package com.itheima.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Result {
private Integer code;//响应码,1 代表成功; 0 代表失败
private String msg; //响应信息 描述字符串
private Object data; //返回的数据
//增删改 成功响应
public static Result success(){
return new Result(1,"success",null);
}
//查询 成功响应
public static Result success(Object data){
return new Result(1,"success",data);
}
//失败响应
public static Result error(String msg){
return new Result(0,msg,null);
}
}
StudentController类
package com.itheima.controller;
import com.itheima.Service.StudentService;
import com.itheima.domain.Student;
import com.itheima.vo.Result;
import org.apache.ibatis.annotations.Mapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
public class StudentController {
@Autowired
private StudentService studentService;
//查询所有
@GetMapping("/student")
public Result findAll() {
List<Student> students = studentService.findAll();
return Result.success(students);
}
@DeleteMapping("/student/{id}")
public Result deleteById(@PathVariable("id") Long id) {
studentService.deleteById(id);
return Result.success();
}
@GetMapping("/student/{id}")
public Result findById(@PathVariable Long id) {
Student student = studentService.findById(id);
return Result.success(student);
}
@PutMapping("/student")
public Result updateById(@RequestBody Student student) {
studentService.updateById(student);
return Result.success();
}
@PostMapping("/student")
public Result add(@RequestBody Student student) {
// 调用service层新增方法
studentService.addById(student);
return Result.success();
}
}
SpringBootDemoApplication类
package com.itheima;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//启动类,位置高于其他类
@SpringBootApplication//启动类注解
@MapperScan("com.itheima.mapper")//指定mapper接口所在的包
public class SpringBootDemoApplication {
//springboot内置了tomcat,端口号默认8080(预订大于配置)
public static void main(String[] args) {
//固定写法
//参数一:启动类:.class
//参数二:args
SpringApplication.run(SpringBootDemoApplication.class,args);
}
}
resources-static-application.yaml
# 大小写敏感
# 缩进代表
# 参数值和冒号一定要有空格
# #代表注解
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot
username: root
password: root
mybatis:
configuration:
#开启驼峰映射
map-underscore-to-camel-case: true
# 日志级别(debug info warn error)
logging:
level:
com.itheima: info
file:
分页查询
PageBean类
package com.itheima.vo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class PageBean<T> {
//总条数
private Long total;
//每页返回的数据
private List<T> rows;
}
EmpMapper类
package com.itheima.mapper;
import com.itheima.domain.Emp;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
@Mapper
public interface EmpMapper {
//total
@Select("select count(*) from emp")
Long findCount();
//rows
@Select("select id,username,password,name,gender,image,job,entrydate," +
"dept_id,create_time,update_time from emp limit #{startIndex},#{pageSize} ;")
List<Emp> findList(@Param("startIndex") Integer startIndex,
@Param("pageSize") Integer pageSize);
}
EmpService类
package com.itheima.service;
import com.itheima.domain.Emp;
import com.itheima.vo.PageBean;
public interface EmpService {
/**
* 分页查询
* @param page
* @param pageSize
* @return
*/
//点击方法名alt+enter 点击add Javadoc
PageBean<Emp> findByPage(Integer page,Integer pageSize);
}
EmpServiceImpl类
package com.itheima.service.Impl;
import com.itheima.domain.Emp;
import com.itheima.mapper.EmpMapper;
import com.itheima.service.EmpService;
import com.itheima.vo.PageBean;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean<Emp> findByPage(Integer page, Integer pageSize) {
//1 拿到总条数 total
Long count = empMapper.findCount();
// 2 拿到当前页的数据
// 2.1 计算下标
Integer startIndex =(page-1)*pageSize;
List<Emp> empList = empMapper.findList(startIndex,pageSize);
//PageBean有参构造创建对象并返回
return new PageBean<>(count,empList);
}
}
EmpController类
package com.itheima.controller;
import com.itheima.domain.Emp;
import com.itheima.service.EmpService;
import com.itheima.vo.PageBean;
import com.itheima.vo.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class EmpController {
@Autowired
private EmpService empService;
@GetMapping("/emps")
public Result findByPage(@RequestParam("page") Integer page,
@RequestParam("pageSize") Integer pageSize){
PageBean<Emp> pageBean = empService.findByPage(page, pageSize);
return Result.success(pageBean);
}
}
SpringBootDemoApplication类(通用)
package com.itheima;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
//启动类,位置高于其他类
@SpringBootApplication//启动类注解
@MapperScan("com.itheima.mapper")//指定mapper接口所在的包
public class SpringBootDemoApplication {
//springboot内置了tomcat,端口号默认8080(预订大于配置)
public static void main(String[] args) {
//固定写法
//参数一:启动类:.class
//参数二:args
SpringApplication.run(SpringBootDemoApplication.class,args);
}
}
resources-static-application.yaml
# 大小写敏感
# 缩进代表
# 参数值和冒号一定要有空格
# #代表注解
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/springboot
username: root
password: root
mybatis:
configuration:
#开启驼峰映射
map-underscore-to-camel-case: true
# 日志级别(debug info warn error)
logging:
level:
com.itheima: info
file:
分页查询第二种方式(更改部分)
导入依赖
com.github.pagehelper pagehelper-spring-boot-starter 1.4.2EmpMapper类
@Select("select id,username,password,name,gender,image,job,entrydate,dept_id,create_time,update_time from emp")
List<Emp> findList2();
EmpService类
@Service
public class EmpServiceImpl implements EmpService {
@Autowired
private EmpMapper empMapper;
@Override
public PageBean<Emp> findByPage(Integer page, Integer pageSize) {
//1 设置分页参数
PageHelper.startPage(page,pageSize);
//2 执行查询
List<Emp> empList = empMapper.findList2();
//3 查询结果转Page对象
Page<Emp> p =(Page<Emp>) empList;
//4 封装对象返回
return new PageBean<>(p.getTotal(),p.getResult());
}
批量删除(xml形式)
<delete id="deleteByIds">
delete from emp where id in
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
</delete>