SpringBoot+Mybatis---这一篇就够了!
2020-05-18 16:26:13来源:博客园 阅读 ()
SpringBoot+Mybatis---这一篇就够了!
typora-copy-images-to: SpringBoot+Mybatis\images
SpringBoot整合MyBatis
------ 既然你都开始整合Mybatis了,我相信基本的SpringBoot项目创建你自己肯定是可以搞定的,所以我在这里就不多赘述了,话不多B,让我们直奔主题
MyBatis---半自动ORM框架
现如今,常见的持久层框架有:Hibernate,MyBatis , JPA....
相对于Hibernate来说,MyBatis更容易上手一些
今天我就把SpringBoot如何整合Mybatis给大家演示一下,共同学习。
如果有没有接触过这两个技术栈的小伙伴,那你们可以先去康康,稍后再来~~。
这是一段来自百度百科的权威解释
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
MyBatis 是支持普通 SQL查询,存储过程和高级映射的优秀持久层框架。MyBatis 消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索。MyBatis 使用简单的 XML或注解用于配置和原始映射,将接口和 Java 的POJOs(Plain Ordinary Java Objects,普通的 Java对象)映射成数据库中的记录。
项目框架
Maven的pom.xml文件
需要导入的依赖---可以在创建SpringBoot项目时可以勾选导入的技术栈
<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.6.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.cody</groupId>
<artifactId>sbootmybatis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sbootmybatis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
<resources>
<!--此处的配置是识别到mapper.xml文件,也可以在application.properties中配置-->
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>
</project>
mapper配置文件
UserMapper.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">
<!-- namespace:改mapper.xml映射文件的唯一标识并且必须和数据处理层的接口的路径相同-->
<mapper namespace="com.cody.sbootmybatis.sbootmybatis.mapper.UserMapper">
<!-- 必须添加property属性 ,区别于是否加主键-->
<resultMap id="user" type="User">
<id column="userid" property="userid" javaType="int" ></id>
<result column="username" property="username" javaType="String" ></result>
<result column="userage" property="userage" javaType="int" ></result>
<result column="userpwd" property="userpwd" javaType="String" ></result>
</resultMap>
<!--id的值必须和数据处理层的接口名一致-->
<!--此处的User-->
<select id="queryAlluser" resultType="User">
select * from user
</select>
<select id="queryuserbyid" parameterType="int" resultMap="user" resultType="User">
select * from user
<trim suffixOverrides="and" prefixOverrides="and">
<where>
<if test="userid!=null">
and userid = #{userid}
</if>
</where>
</trim>
</select>
<select id="queryuserbyname" resultType="User" parameterType="string" resultMap="user">
select * from user
<trim suffixOverrides="and" prefixOverrides="and">
<where>
<if test="username!=null">
and username = #{username}
</if>
</where>
</trim>
</select>
<update id="UpdUser" parameterType="User">
</update>
<delete id="DelUser"></delete>
<insert id="AddUser" parameterType="User" >
insert into user value (${userid},#{username},${userage},#{userpwd})
</insert>
</mapper>
application.properties的配置
# 端口的配置
server.port=8081
# 数据库访问配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
#将database_name改成自己的数据库的名称
spring.datasource.url=jdbc:mysql://localhost:3306/database_name?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
spring.datasource.username=root
spring.datasource.password=123456
application.yml的配置
# 配置Mybatis的包的别名,在mapper.xml文件中xxxType="xxx" 此处直接可以写实体类的类名即可,不需要将全类名都写上
#<select id="queryAlluser" resultType="User">
# select * from user
# </select>
#<select id="queryAlluser" resultType="com.xxx.xxx.entity.User">
# select * from user
# </select>
mybatis:
type-aliases-package: com.xxx.xxx.entity
#禁用掉模板缓冲,在开发环境中可以实时的观察到html页面的更改
spring:
thymeleaf:
cache: false
controller
logincontroller.java
/**
loginController
简单的登录测试
与index.html一起使用
*/
import com.cody.sbootmybatis.sbootmybatis.entity.User;
import com.cody.sbootmybatis.sbootmybatis.mapper.UserMapper;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.annotation.Resource;
import java.util.Map;
/**
* @author xxx
* @date 2020/5/6 - 10:09
*/
@Controller
public class logincontrollor {
@Resource
private UserMapper userMapper;
@RequestMapping(value = "/user/login" ,method = RequestMethod.POST)
@ResponseBody
public String login(@RequestParam("username") String username ,
@RequestParam("password")String password , Map<String,Object> map){
User user=userMapper.queryuserbyname(username);
if (username.equals(user.getUsername())&&password.equals(user.getuserpwd())){
return "登录成功";
}
else{
return "登录失败";
}
}
}
mycontroller.java
/**
增删改查
*/
package com.cody.sbootmybatis.sbootmybatis.controllor;
import com.cody.sbootmybatis.sbootmybatis.mapper.UserMapper;
import com.cody.sbootmybatis.sbootmybatis.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping("/user")
public class mycontroller {
@Autowired(required = false)
private UserMapper userMapper;
@RequestMapping(value ={"/queryAlluser"},method = RequestMethod.GET)
/**
*
*
* @return List<User>
*
*
* */
public List<User> queryalluser(){
List<User> list = userMapper.queryAlluser();
return list;
}
@RequestMapping(value = {"/queryuserbyid"} , method = RequestMethod.GET)
/**
*
*
* @param userid
* @return user
*
*
*/
public User queryuserbyid(String userid){
User user = userMapper.queryuserbyid(Integer.parseInt(userid));
return user;
}
@RequestMapping(value = {"/adduser"} , method = RequestMethod.GET)
/**
*
*
* @param useri
* @return user
*
*
*/
public String adduser(User user){
boolean flag = userMapper.AddUser((User) user);
return flag ?"success":"fail";
}
@RequestMapping(value = {"/Upuserbyid"} , method = RequestMethod.GET)
/**
*
*
* @param userid
* @return user
*
*
*/
public String Upuser(User user){
boolean flag = userMapper.UpdUser((User) user);
return flag?"success":"fail";
}
@RequestMapping(value = {"/Deluserbyid"} , method = RequestMethod.GET)
/**
*
*
* @param userid
* @return user
*
*
*/
public String Deluserbyid(String userid){
boolean flag = userMapper.DelUser(Integer.parseInt(userid));
return flag?"success":"fail";
}
}
mapper
package com.cody.sbootmybatis.sbootmybatis.mapper;
import com.cody.sbootmybatis.sbootmybatis.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author Cody
* @date 2020/5/2 - 13:25
* @Decription :
*/
@Mapper
public interface UserMapper {
/**
*查 读取(Retrieve)
* fetch data
* @return List<User>
*/
List<User> queryAlluser();
/**
*查 读取(Retrieve)
* fetch data by userid
* @param userid
* @return User
*/
/**
@Select("select * from user where userid = #{userid}")
本人喜欢讲SQL语句写在mapper.xml文件中,这样显得代码比较整齐
在后期开发中,一旦SQL语句变得繁琐起来,不利于维护
但是这样用注解的形式也完全可行,毕竟有些人可能写配置文件可能已经快写吐了
*/
User queryuserbyid( int userid);
/**
* 增加(Create)
* add data by user
* @param user
* @return int
*/
boolean AddUser(User user);
/**
* 删除(Delete)
* @param id
* @return int
*/
boolean DelUser(int id);
/**
* 更新(Update)
* @param user
* @return boolean
*/
boolean UpdUser(User user);
User queryuserbyname(String name);
}
前端
将index.html文件放在template文件夹下
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Title</title>
</head>
<body >
<form method="post" action="/user/login" >
<input name="username" type="text" placeholder="请输入用户名"/>
<input type="password" name="password" />
<input type="submit" th:value="登录"/>
</form>
</body>
</html>
测试
测试登录操作
数据库的信息:
测试CRUD(即增删改查)
查询全部
根据ID查询
增加User
通过?和&传值
注意事项
1.mappe.xml文件的路径包括文件名必须同数据层的接口完全一致
2.application.properties文件和application.yml文件不需要都写,二选一即可,只不过这里我都写了而已
使开发更加便利的IDEA插件
给大家安利一款IDEA插件 : MyBatisX
作用: 在接口中写方法可以直接在mapper.xml文件中写CRUD方法生成相应的标签
图中使用的快捷键是 :alt+enter
MyBatis框架的优点
-
与JDBC相比,减少了50%以上的代码量。
-
MyBatis是最简单的持久化框架,小巧并且简单易学。
-
MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,并可重用。
-
提供XML标签,支持编写动态SQL语句。
-
提供映射标签,支持对象与数据库的ORM字段关系映射。
MyBatis框架的缺点
-
SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。
-
SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。
SpringBoot整合Mybatis中遇到的Errors
这是我自己在整合的时候遇到的一些问题,希望自己走过的弯路可以多多帮助到大家。
There was an unexpected error (type=Internal Server Error, status=500).
Error attempting to get column 'u_account' from result set. Cause: java.sql.SQLDataException: Cannot determine value type from string '201577D0510' ; Cannot determine value type from string '201577D0510'; nested exception is java.sql.SQLDataException: Cannot determine value type from string '201577D0510'
org.springframework.dao.DataIntegrityViolationException: Error attempting to get column 'u_account' from result set. Cause: java.sql.SQLDataException: Cannot determine value type from string '201577D0510'
; Cannot determine value type from string '201577D0510'; nested exception is java.sql.SQLDataException: Cannot determine value type from string '201577D0510'
at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:84)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81)
at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:73)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy65.selectList(Unknown Source)
解决方法:
添加了entity子类中的无参构造方法,异常消失
java.sql.SQLException: Access denied for user ''@'localhost' (using password: NO)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:129)
at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
at com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)
at com.mysql.cj.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:836)
at com.mysql.cj.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:456)
at com.mysql.cj.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:246)
解决方法:时区报错
更改配置信息:
spring:
datasource:
username: root
password: 123456
# 如果时区报错就需要添加 serverTimezone=UTC
url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
driver-class-name: com.mysql.cj.jdbc.Driver
使用@Autowired注解有错误提示
使用Spring boot +mybatis框架时,在service实现类中使用Mapper类,给Mapper类添加@Autowired注解时发现有错误提示:could not autowire,no beans of "XXX" type found,但程序的编译和运行都正常。
处理方式:
方案一:@Autowired(required = false) 设置required 属性值为 false,错误消失
方案二:用@Resource注解替换@Autowired注解,错误消失
@Resource注解与@Autowired注解的异同点
这两个注解都是用作bean的注入时使用,都是为一个对象变量省去写get,set方法,自动为这个对象注入实例化对象(即注入依赖)注入的方式还是有所区别的 :
@Autowired是基于spring的注解org.springframework.beans.factory.annotation.Autowired,它默认是按类型进行的装配的,如果想要它按名字进行装配则需在@autowired下面添加@qualifier("name")`注解,都无法找到唯一的一个实现类的时候报错。@Autowired注解默认情况下必须要求依赖对象必须存在,如果要允许null值,则应该设置它的required属性为false,
@Resource 是基于j2ee的注解(可以减少了与spring的耦合),(JDK1.6以上支持)默认是按名字进行注解,若不指定装配bean的名字,当注解写在字段上时,默认取字段名,按照名称查找通过set方法进行装配,倘若有多个子类,则会报错。需要注意的是name属性一旦指定,就只会按照名称进行装配
解与@Autowired注解的异同点
这两个注解都是用作bean的注入时使用,都是为一个对象变量省去写get,set方法,自动为这个对象注入实例化对象(即注入依赖)注入的方式还是有所区别的 :
@Autowired是基于spring的注解org.springframework.beans.factory.annotation.Autowired,它默认是按类型进行的装配的,如果想要它按名字进行装配则需在@autowired下面添加@qualifier("name")`注解,都无法找到唯一的一个实现类的时候报错。@Autowired注解默认情况下必须要求依赖对象必须存在,如果要允许null值,则应该设置它的required属性为false,
@Resource 是基于j2ee的注解(可以减少了与spring的耦合),(JDK1.6以上支持)默认是按名字进行注解,若不指定装配bean的名字,当注解写在字段上时,默认取字段名,按照名称查找通过set方法进行装配,倘若有多个子类,则会报错。需要注意的是name属性一旦指定,就只会按照名称进行装配
``
The Ending
? **----------每天进步“亿”点点---------- **
? -----Relyonyouself--
原文链接:https://www.cnblogs.com/RelyC/p/12872982.html
如有疑问请与原作者联系
标签:
版权申明:本站文章部分自网络,如有侵权,请联系:west999com@outlook.com
特别注意:本站所有转载文章言论不代表本站观点,本站所提供的摄影照片,插画,设计作品,如需使用,请与原作者联系,版权归原作者所有
- 今天来介绍java 各版本的新特性,一篇文章让你了解 2020-06-10
- 读了这一篇,让你少踩 ArrayList 的那些坑 2020-05-29
- Maven整合JaCoCo和Sonar,看看你的测试写够了没 2020-05-21
- 学习Spring,看这几本书就够了 2020-05-18
- 搞定JVM基本原理和面试题,看看这几本书妥妥够了! 2020-05-18
IDC资讯: 主机资讯 注册资讯 托管资讯 vps资讯 网站建设
网站运营: 建站经验 策划盈利 搜索优化 网站推广 免费资源
网络编程: Asp.Net编程 Asp编程 Php编程 Xml编程 Access Mssql Mysql 其它
服务器技术: Web服务器 Ftp服务器 Mail服务器 Dns服务器 安全防护
软件技巧: 其它软件 Word Excel Powerpoint Ghost Vista QQ空间 QQ FlashGet 迅雷
网页制作: FrontPages Dreamweaver Javascript css photoshop fireworks Flash