groupid和artifactId被统称为“坐标”是为了保证项目唯一性而提出的,如果你要把你项目弄到maven本地仓库去,你想要找到你的项目就必须根据这两个id去查找。
groupId和artifactId是maven管理项目包时用作区分的字段,就像是地图上的坐标。
artifactId:artifactId一般是项目名或者模块名。
groupId:groupId分为几个字段,例如cn.com.fullstack,前面的com叫【域】,后面的是你自己起的域名。
groupId一般分为多个段,这里我只说两段,第一段为域,第二段为公司名称。域又分为org、com、cn等等许多,其中org为非营利组织,com为商业组织。举个apache公司的tomcat项目例子:这个项目的groupId是org.apache,它的域是org(因为tomcat是非营利项目),公司名称是apache,artigactId是tomcat。
<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.0modelVersion>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.7.2version>
<relativePath/>
parent>
<groupId>com.daigroupId>
<artifactId>springboot-webartifactId>
<version>0.0.1-SNAPSHOTversion>
<name>springboot-webname>
<description>Demo project for Spring Bootdescription>
<properties>
<java.version>1.8java.version>
properties>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-thymeleafartifactId>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.6version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-jdbcartifactId>
dependency>
<dependency>
<groupId>org.apache.logging.log4jgroupId>
<artifactId>log4j-apiartifactId>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-autoconfigureartifactId>
<version>2.2.2version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatis-springartifactId>
<version>2.0.7version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.9version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
plugin>
plugins>
<resources>
<resource>
<directory>src/main/javadirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
includes>
resource>
<resource>
<directory>src/main/resourcesdirectory>
<includes>
<include>**/*.propertiesinclude>
<include>**/*.xmlinclude>
<include>**/*.ymlinclude>
includes>
<filtering>truefiltering>
resource>
resources>
build>
project>
连接数据库
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?userSSL=false&useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/dai/mapper/UserMapper.xml"/>
mappers>
configuration>
将UserMapper.xml配置到mybatis-config.xml文件中
<mappers>
<mapper resource="com/dai/mapper/UserMapper.xml"/>
mappers>
方式一
<mappers>
<mapper resource="com/dai/mapper/UserMapper.xml"/>
mappers>
方式二
<mppers>
<mpper class="com.dai.mapper.UserMapper"/>
mppers>
注意
接口和他的Mapper配置文件必须同名!!
接口和他的Mapper配置文件必须要在同一个包下!!
方式三
<mppers>
<package name="com.dai.mapper"/>
mppers>
接口和他的Mapper配置文件必须同名!!
接口和他的Mapper配置文件必须要在同一个包下!!
从mybatis-config.xml文件中获取数据源,创建sqlSessionFactory中获取sqlSession实例。
package com.dai.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory;
static{
try {
//使用Mybatis第一步获取:sqlSessionFactory对象
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
//既然有了SqlSessionFactory,顾名思义,我们就可以从中获取SqlSession的实例
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
生命周期,和作用域,是至关重要的,因为错误的使用会导致非常严重的并发问题。
SqlSessionFactoryBuilder
一旦创建了SqlSessionFactory,就不需要他了
局部变量
SqlSessionFactory
说白了就是可以想象为:数据库连接池
SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例
因此 SqlSessionFactory 的最佳作用域是应用作用域
最简单的就是使用单例模式或者静态单例模式。
SqlSession
连接到连接池的一个请求
SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。
用完之后要赶紧关闭,否则资源被占用
package com.dai.entity;
public class User {
Integer id;
String name;
String pwd;
public User() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", pwd='" + pwd + '\'' +
'}';
}
}
package com.dai.mapper;
import com.dai.entity.User;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper {
/**
* 根据id查询用户信息
* @param id
* @return
*/
User getUserInfo(int id);
/**
* 新增用户
* @param user
* @return
*/
int save (User user);
/**
* 更新用户信息
* @param user
* @return
*/
int update (User user);
/**
* 根据id删除
* @param id
* @return
*/
int deleteById (int id);
/**
* 查询所有用户信息
* @return
*/
List<User> selectAll ();
/**
* 查询所有用户信息
* @return
*/
List<User> getUserList();
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<-----工作空间------对应的接口类>
<mapper namespace="com.dai.mapper.UserMapper">
<-----接口方法------返回数据类型>
<select id="getUserList" resultType="com.dai.entity.User">
select * from mybatis.user
select>
<select id="getUserById" parameterType="int" resultType="com.dai.entity.User" >
select * from mybatis.user where id = #{id};
select>
<select id="getUserById" parameterType="int" resultType="com.dai.entity.User" >
select * from mybatis.user where id = #{id};
select>
<update id="updateUSer" parameterType="com.dai.entity.User">
update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id};
update>
<delete id="delUser" parameterType="int">
delete from mybatis.user where id = #{id};
delete>
package com.dai;
import com.dai.entity.User;
import com.dai.mapper.UserMapper;
import com.dai.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class MyTest {
@Test
public void test(){
//第一步: 获取SqlSession对象
SqlSession sqlSession = MybatisUtils.getSqlSession();
//方式一:getMapper
UserMapper userDao = sqlSession.getMapper(UserMapper.class);
List<User> userList = userDao.getUserList();
for(User user : userList){
System.out.println(user);
}
//关闭SqlSession
sqlSession.close();
}
}
配置文件没有注册
绑定接口错误
方法名不对
返回类型不对 resultType
Maven导出资源问题
标签不匹配的错误
resource绑定mapper,需要使用路径
程序配置文件必须符合规范!
NullPointerException,没有注册资源 例作用域问题
输出的xml文件中存在中文乱码问题
maven资源没有导出问题!
<resultMap id="UserMap" type="user">
<result column="id" property="id"/>
<result column="name" property="name"/>
<result column="pwd" property="password"/>
resultMap>
<select id="getUserById" parameterType="int" resultMap="UserMap" >
select * from mybatis.user where id = #{id};
select>
resultMap元素是MyBatis中最重要最强大的元素
ResultMap的设计思想是,对于简单的语句根本不需要配置显示的结果映射,而对于复杂一点的语句只需要描述他们的关系就行了
ResultMap 最优秀的地方在于,虽然你已经对他相当了解了,但你根本就不需要显示的用到他们
如果世界总是这么简单就好了
SLEF4
LOG4J 【掌握】
LOG4J2
JDK_LOGGING
COMMONS_LOGGING
STDOUT_LOGGING【掌握】
NO_LOGGING
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
导包
<dependency>
<groupId>log4jgroupId>
<artifactId>log4jartifactId>
<version>1.2.17version>
dependency>
日志格式配置log4j.properties
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger = DEBUG,console ,file
#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.Target = System.out
log4j.appender.console.Threshold = DEBUG
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern = [%c]-%m%n
#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File = ./log/kun.log
log4j.appender.file.MaxFileSize = 10mb
log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = [%p][%d{yy-MM-dd}][%c]%m%n
#日志输出级别
log4j.logger.org.mybatis=DEBUG
log4j.logger.java.sql=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
<settings>
<setting name="logImpl" value="LOG4J"/>
settings>
使用log4j日志
1.在要使用Log4j的类中,导入包import org.apache.log4j.Logger;
2.日志对象,参数为当前类的class
static Logger logger = Logger.getLogger(UserMapper.class);
3.日志级别
logger.info("info:进入了testLog4j");
logger.debug("debug:进入了testLog4j");
logger.error("error:进入了testLog4j");
多个学生,对应老师
对于这边而言,关联。。 多个学生,关联一个老师【多对一】
对于老师而言,集合。。 一个老师,有很多学生 【一对多】
<select id="getStudent" resultMap="StudentTeacher">
select * from student
select>
<resultMap id="StudentTeacher" type="student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<collection property="teacher" column="tid" javaType="teacher" select="getTeacher"/>
resultMap>
<select id="getTeacher" resultType="teacher">
select * from teacher where id = #{id}
select>
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid , s.name sname, t.name tname
from student s,teacher t
where s.tid=t.id
select>
<resultMap id="StudentTeacher2" type="student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="teacher">
<result property="name" column="tname">result>
association>
resultMap>
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from mybatis.teacher where id=#{tid};
select>
<resultMap id="TeacherStudent2" type="Teacher">
<collection property="students" javaType="ArrayList" ofType="Student" select="getStudent" column="id"/>
resultMap>
<select id="getStudent" resultType="Student">
select * from mybatis.student where tid=#{tid};
select>
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name tname, t.id tid
from student s, teacher t
where s.tid = t.id and t.id=#{tid}
select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
collection>
resultMap>
小结:
关联 - association 【多对一】
集合 - collection 【对多】
JavaType & ofType
JavaType 用来指定实体类中属性的类型
ofType 用来指定映射到List或者集合中的pojo类型,泛型中的约束类型
注意点:
尽量保证SQL的可读性,尽量保证通俗易懂
注意一对多、多对一中,属性名和字段问题!!
如果问题不好排除,可以使用日志~ 建议Log4j 【其实默认的也够用了】
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from mybatis.blog where 1=1
<if test="title != null">
and title = #{title}
if>
<if test="author != null">
and author = #{author}
if>
select>
<select id="queryBlogChoose" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<choose>
<when test="title != null">
title = #{title}
when>
<when test="author != null">
and author = #{author}
when>
<otherwise>
and views=#{views}
otherwise>
choose>
where>
select>
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<if test="title != null">
and title = #{title}
if>
<if test="author != null">
and author = #{author}
if>
where>
select>
所谓的动态SQL,本质还是SQL语句,只是我们可以在SQL层面,去执行一个逻辑代码
1.使用SQL标签抽取公共部分
<sql id="sql-if-title-author">
<if test="title != null">
title = #{title}
if>
<if test="author != null">
and author = #{author}
if>
sql>
2.在需要使用的地方使用Include标签引用即可
<select id="queryBlogIF" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<include refid="sql-if-title-author"/>
where>
select>
注意:
最好基于单表定义SQL片段!!
sql标签不要存在where标签 因为他是动态的
select * from user where 1=1 and
<foreach item="id" collection="ids" open="(" separator="or" close=")">
#{id}
foreach>
(id=1 or id=2 or id=3)
<select id="queryBlogForeach" parameterType="map" resultType="blog">
select * from mybatis.blog
<where>
<foreach item="id" collection="ids" open="and (" separator="or" close=")">
id=#{id}
foreach>
where>
select>