MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录。
Mybatis与Hibernate区别
两个都是持久层框架,操作数据库,但是两者还是有区别的
hibernate:它是一个标准的orm框架,比较重量级,学习成本高.
优点:高度封装,使用起来不用写sql,开发的时候,会减低开发周期.
缺点:sql语句无法优化
应用场景:oa(办公自动化系统), erp(企业的流程系统)等,还有一些政府项目,
总的来说,在用于量不大,并发量小的时候使用.
mybatis:它不是一个orm框架, 它是对jdbc的轻量级封装, 学习成本低,比较简单
优点:学习成本低, sql语句可以优化, 执行效率高,速度快
缺点:编码量较大,会拖慢开发周期
应用场景: 互联网项目,比如电商,P2p等
总的来说是用户量较大,并发高的项目。
工作原理解析
mybatis应用程序通过SqlSessionFactoryBuilder从mybatis-config.xml配置文件(也可以用Java文件配置的方式,需要添加@Configuration)中构建出SqlSessionFactory(SqlSessionFactory是线程安全的);
然后,SqlSessionFactory的实例直接开启一个SqlSession,再通过SqlSession实例获得Mapper对象并运行Mapper映射的SQL语句,完成对数据库的CRUD和事务提交,之后关闭SqlSession。
说明:SqlSession是单线程对象,因为它是非线程安全的,是持久化操作的独享对象,类似jdbc中的Connection,底层就封装了jdbc连接。
详细流程如下:
1、加载mybatis全局配置文件(数据源、mapper映射文件等),解析配置文件,MyBatis基于XML配置文件生成Configuration,和一个个MappedStatement(包括了参数映射配置、动态SQL语句、结果映射配置),其对应着
他们之间的区别用最直接的话来说就是:#相当于对数据 加上 双引号,$相当于直接显示数据。
1、#对传入的参数视为字符串,也就是它会预编译,select * from user where name = #{name},比如我传一个csdn,那么传过来就是 select * from user where name = 'csdn';
2、$将不会将传入的值进行预编译,select * from user where name=${name},比如我穿一个csdn,那么传过来就是 select * from user where name=csdn;
3、#的优势就在于它能很大程度的防止sql注入,而$则不行。比如:用户进行一个登录操作,后台sql验证式样的:select * from user where username=#{name} and password = #{pwd},如果前台传来的用户名是“wang”,密码是 “1 or 1=1”,用#的方式就不会出现sql注入,而如果换成$方式,sql语句就变成了 select * from user where username=wang and password = 1 or 1=1。这样的话就形成了sql注入。
4、MyBatis排序时使用order by 动态参数时需要注意,用$而不是#
org.springframework.boot
spring-boot-starter
org.springframework.boot
spring-boot-starter-test
test
org.springframework.boot
spring-boot-starter-web
org.mybatis.spring.boot
mybatis-spring-boot-starter
com.github.pagehelper
pagehelper-spring-boot-starter
1.1.1
mysql
mysql-connector-java
org.springframework.boot
spring-boot-devtools
true
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8
username: root
password: root
#mybatis,批量定义别名
mybatis:
type-aliases-package: com.yimingkeji.mybatis.entity
public interface UserMapper {
@Select("select * from user")
@Results({
@Result(property = "phoneNumber", column = "phone_number"),
@Result(property = "createTime", column = "create_time", javaType = Date.class)
})
List findAll();
@Select("select * from user where id = #{id}")
User findOne(int id);
@Insert("insert into user(name, age, phone_number, available, create_time) values (#{name}, #{age}, #{phoneNumber}, #{available}, #{createTime})")
int add(User user);
@Update("update user set name=#{name} where id = #{id}")
int update(User user);
@Delete("delete from user where id = #{id}")
int delete(int id);
}
在启动类中添加@MapperScan注解
@SpringBootApplication
@MapperScan(basePackages = {"com.yimingkeji.mybatis.mapper"})//或者每个mapper接口上加 @Mapper 注解
public class MybatisApp {
public static void main(String[] args) {
SpringApplication.run(MybatisApp.class, args);
}
}
@RestController
public class UserController1 {
@Autowired private UserMapper userMapper;
@GetMapping("user")
public List list(){
return userMapper.findAll();
}
@GetMapping("user/{id}")
public User one(@PathVariable int id){
return userMapper.findOne(id);
}
@PostMapping("user")
public int add(@RequestBody User user){
return userMapper.add(user);
}
@PutMapping("user")
public int update(@RequestBody User user){
return userMapper.update(user);
}
@DeleteMapping("user/{id}")
public int del(@PathVariable int id){
return userMapper.delete(id);
}
}
#加载Mybatis配置文件
mybatis.mapper-locations = classpath:mapper/*Mapper.xml
mybatis.config-location = classpath:config/sqlMapConfig.xml
#数据源必填项
spring.datasource.driver-class-name= com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = 123456
注:通常,若mybatis配置信息较少,只是针对基本配置无需复杂配置,则只需在application.yml文件中配置即可,否则最好配置在 mybatis-config.xml中。
编写Mapper.Xml和sqlMapConfig.xml
userMapper.xml
sqlMapConfig.xml
编写mapper
public interface UserMapper {
/**
* 获取所有的user对象
*
* @return
*/
List getAll();
}
编写service
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public List getAll() {
return userMapper.getAll();
};
}
主运行类
@SpringBootApplication
@MapperScan(basePackages = {"com.liujia.springdemo.mapper"})
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
总结:
两种方式的区别
1:是否需要在application.properties中配置mapper.xml和sqlMapperConfig.xml
2:将SQL语句写在了XML中
由于第二种方式将比较繁琐的SQL语句写在了配置文件中,整个代码结构更加清晰,本人更加喜欢此种配置方式。