前言
具体的项目我已经上传到了CSDN上面,里面除了项目书和matlabcontrol-4.1.0之外都有了。哪里不会可以私信我。这个框架是我繁琐地学习了要配置的ibatis框架,简单到爆炸的mybatis-plus框架以及不灵活的tkmybatis框架之后。总结出自己用的一套,无配置,少代码。但是又不像mybatis plus有那么大争议的框架
提示:以下是本篇文章正文内容,下面案例可供参考
一、代码解释
0.项目的基本情况
为了方便大家对代码进行理解,我将一些数据库的结构和项目结构的截图放在这里。
导入的包是这些
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.0.1</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
<version>2.3.7.RELEASE</version>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>2.1.5</version>
</dependency>
Mapper层
实体层
数据库结构
Apply表
USER_PRIZE表
1.基本的单表查询
这个单表查询是十分简单,但是在日常编程过程中用的十分多的一个查询,可以用tkmtbatis来代替我们繁复的劳动。以下为Mapper。
package com.example.app.mapper;
import com.example.app.pojo.Admin;
import tk.mybatis.mapper.common.Mapper;
@org.apache.ibatis.annotations.Mapper
public interface AdminMapper extends Mapper<Admin> {//这个Mapper<Admin>就是tkmabatis人家写好的基本的单表映射
}
这个是tkmybatis已经将基本的CRUD写好了,在对于没有多表查询,只是单表操作的对象来说,只要在实体层,配好下面这个就行了。
package com.example.app.pojo;
import com.sun.istack.Nullable;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "admin")//这个是实体类对应的表名
public class Admin {
@Id
@Column(columnDefinition = "account")//这个名字是数据库里面的字段.
String account;
@Column(columnDefinition = "password")
String password;
@Column(columnDefinition = "name")
String name;
}
虽然可以自动映射,但是我觉得还是加上Column注解更稳当一些。
然后配完后就可以在Service层这样用了
ackage com.example.app.service;
import com.example.app.mapper.AdminMapper;
import com.example.app.pojo.Admin;
import com.example.app.pojo.User;
import org.apache.ibatis.annotations.Select;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
/**
* @author mac
*/
@Service
public class AdminService {
@Autowired
private AdminMapper adminMapper;
@Transactional(rollbackFor=Exception.class)//这是事务回滚的注解
public Admin queryByAccount(String account){
return adminMapper.selectByPrimaryKey(account);
}
@Transactional(rollbackFor=Exception.class)
public void updateAdmin(Admin admin){
adminMapper.updateByPrimaryKeySelective(admin);
}
}
这样的话配置是极少的
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.url=jdbc:h2:file:~/app2;MV_STORE=false;
spring.datasource.hikari.username=zqqm112233
spring.datasource.hikari.password=112233
#h2配置账户密码时候用hikari配置
#h2的账户密码是user表内的
#这是配置的是数据库链接池hikari
mybatis.type-aliases-package=com.example.app.model
#配置包路径
mybatis.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl
2.多表查询
以下是通过具体需求,除了复杂的多表查询外,还有不同于一般单表查询的特殊单表查询。即自定义内容。
package com.example.app.mapper;
import com.example.app.pojo.Prize;
import com.example.app.pojo.User;
import org.apache.ibatis.annotations.*;
import tk.mybatis.mapper.common.Mapper;
import java.util.List;
/**
* @author mac
*/
@org.apache.ibatis.annotations.Mapper
public interface PrizeMapper extends Mapper<Prize> {
@Select("select * from user_prize Up,user u ,prize p where p.pname=Up.pname and Up.account=u.account and u.account like #{account}")//Up,u,p分别为user_prize表,user表,prize表的别名,这是一个多表查询
@Results({
@Result(id = true,column = "pname",property = "pname"),
@Result(column = "reward",property = "reward"),
@Result(column = "request_score",property = "requestScore"),
@Result(column = "gmt_create",property = "gmtCreate"),
@Result(column = "gmt_modified",property = "gmtModified")
})
public List<Prize> findByAccount(String account);
/** @Select("select * from orders")
@Results({
@Result(column = "id",property = "id"),
@Result(column = "ordertime",property = "ordertime"),
@Result(column = "total",property = "total"),
@Result(
property = "user", //要封装的属性名称
column = "uid", //根据那个字段去查询user表的数据
javaType = User.class, //要封装的实体类型
//select属性 代表查询那个接口的方法获得数据
one = @One(select = "com.itheima.mapper.UserMapper.findById")
)
})
public List<Order> findAll();
订单和用户是多对一的关系,这是一的那方的代码,只是吧Many替换成One
*/
@Select("select * from prize")
@Results({
@Result(id = true,column = "pname",property = "pname"),
@Result(column = "reward",property = "reward"),
@Result(column = "request_score",property = "requestScore"),
@Result(column = "gmt_create",property = "gmtCreate"),
@Result(column = "gmt_modified",property = "gmtModified"),
@Result(
property = "userList",
column = "pname",
javaType = List.class,
many = @Many(select = "com.example.app.mapper.UserMapper.findByPname")
)
})
public List<Prize> findPrizeAndUser();//这是一个级联查询,因为prize实体里面有个属性是列表,即获得该项奖学金的学生名单userlist。
@Select("select * from prize where pname like #{pname}")
@Results({
@Result(id = true,column = "pname",property = "pname"),
@Result(column = "reward",property = "reward"),
@Result(column = "request_score",property = "requestScore"),
@Result(column = "gmt_create",property = "gmtCreate"),
@Result(column = "gmt_modified",property = "gmtModified"),
@Result(
property = "userList",
column = "pname",
javaType = List.class,
one = @One(select = "com.example.app.mapper.UserMapper.findByPname")
)
})
public List<Prize> findPrizeAndUserByPname(String pname);//通过奖学金名字查询获得奖学金的学生
}
它调用的UserMapper中的方法是这样的
@Select("select * from user_prize Up,user u ,prize p where u.account=Up.account and Up.pname=p.pname and Up.pname like #{pname}")
@Results({
@Result(id = true, column = "account", property = "account"),
@Result(column = "password", property = "password"),
@Result(column = "name", property = "name"),
@Result(column = "token", property = "token"),
@Result(column = "gmt_create", property = "gmtCreate"),
@Result(column = "gmt_modified", property = "gmtModified"),
})
public List<User> findByPname (String account);
配置的实体类是这样的
package com.example.app.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.List;
/**
* class Prize
*
* @author ZhangQi
* @date 2020/12/20
*/
@Data
@AllArgsConstructor
@NoArgsConstructor
@Table(name = "prize")
public class Prize {
@Id
String pname;
@Column(columnDefinition = "reward")
Long reward;
@Column(columnDefinition = "request_score")
Integer requestScore;
@Column(columnDefinition = "gmt_create")
Long gmtCreate;
@Column(columnDefinition = "gmt_modified")
Long gmtModified;
List<User> userList;//奖学金和学生是多对多的关系,一个奖学金可以多个人获得,一个人也可以获得多个奖学金
}
然后Service层是这样的,基本的操作就用tkmybatis代替了,复杂的操作调用mapper中写好的。
package com.example.app.service;
import com.example.app.mapper.PrizeMapper;
import com.example.app.pojo.Prize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.List;
@Service
public class PrizeService {
@Autowired
private PrizeMapper prizeMapper;
@Transactional(rollbackFor=Exception.class)
public List<Prize> queryAll(){
return prizeMapper.selectAll();
}
@Transactional(rollbackFor=Exception.class)
public Prize queryByName(String pname){
return prizeMapper.selectByPrimaryKey(pname);
}
@Transactional(rollbackFor=Exception.class)
public List<Prize> queryPrizeAndUserByName(String name){
return prizeMapper.findPrizeAndUserByPname(name);
}
@Transactional(rollbackFor=Exception.class)
public List<Prize> queryPrizeAndUser(){
return prizeMapper.findPrizeAndUser();
}
@Transactional(rollbackFor=Exception.class)
public List<Prize> queryPrizeByAccount(String account){
return prizeMapper.findByAccount(account);
}
@Transactional(rollbackFor=Exception.class)
public int addPrize(Prize prize){
return prizeMapper.insertSelective(prize);
}
@Transactional(rollbackFor=Exception.class)
public int updatePrize(Prize prize){
return prizeMapper.updateByPrimaryKeySelective(prize);
}
@Transactional(rollbackFor=Exception.class)
public int deletePrizeByPname(String pname){
return prizeMapper.deleteByPrimaryKey(pname);
}
}
二、总结
普通的CRUD可以用tkmybatis解决,个性化的CRUD用mybatis和ibatis结合进行非xml,@注解的方式进行解决。注解分为实体类上面的映射注解和Mapper上面的@Select注解之类的。
具体步骤归纳如下
- 导包
- 继承tkmybatis写好的Mapper<写具体实体类>
- 将Mapper对应的实体类写好@Table和@Column注解,创建映射。
- 如果普通的单表CRUD,不能满足你,可以在Mapper里用@Select注解进行自定义操作。
- 将Mapper用@Autowire注解自动注入,在Service层中进行使用。
衷心希望你能够从这篇博文中收获到什么,如果有不太容易懂的地方可以私信我或者在下面留言,谢谢你的关注。