1、一个实体类对象对应一个表中的一条数据
2、这种不能用
2、MyBatis操作数据库步骤
(1)读取mybatis配置文件mybatis-config.xml
(2)加载映射文件Mapper.xml
(3)构建会话工厂
(4)创建SqlSession对象
3、执行流程
建数据库
(1)创建实体
(2)创建mybatis-config.xml核心配置文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 设置数据库字段与实体类的属性映射-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/db_mybatis"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!--映入映射文件-->
<mappers>
<mapper resource="com/qf/mapper/UserMapper.xml" />
</mappers>
</configuration>
(3)创建相关的接口
1)用配置实现(多)
package com.qf.mapper;
import org.apache.ibatis.annotations.Insert;
public interface UserMapper {
Integer insert();
}
2)注解实现(简单sql语句,少用)
package com.qf.mapper;
import org.apache.ibatis.annotations.Insert;
public interface UserMapper {
@Insert("insert into tb_user(username,password)values('小刘','789')")
Integer insert();
}
(4)mybatis-config.xml核心配置文件里面映入映射文件
(5)创建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 namespace="com.qf.mapper.UserMapper">
<!--绑定方法-->
<insert id="insert">
insert into tb_user(username,password)values('小明','123')
</insert>
</mapper>
注意:有注解实现的话就不用insert这里了
(6)利用代理模式去运行
package com.qf;
import com.qf.mapper.UserMapper;
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 org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
public class MyBatisDemo {
@Test
public void test() throws IOException {
//读取mybatis核心配置文件
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
//创建sqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
//开启事务,设置为自动提交
SqlSession sqlSession = sqlSessionFactory.openSession(true);
//获取mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//测试功能
Integer num = userMapper.insert();
// Assert.assertEquals(1,num);
System.out.println(num);
//手动提交
// sqlSession.commit();
}
}
4、执行流程(新)
(1)导入依赖
(2)创建SQLSessionFactory对象
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
//1 通过mybatis的核心配置文件创建SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
(3)写mybatis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<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://10.3.142.206:3316/mybatis_example?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=Asia/Shanghai"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/SysUserMapper.xml"/>
</mappers>
</configuration>
(3)创建Mapper接口文件
/**
* 一个mapper就是一个表的操作
*/
public interface SysUserMapper {
SysUser selectById();
}
(4)创建mapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace 关联接口类的全路径-->
<mapper namespace="com.qf.mybatis.mapper.SysUserMapper">
<select id="selectById" resultType="com.qf.mybatis.entity.SysUser">
SELECT *
FROM sys_user
WHERE user_id = 1
</select>
</mapper>
(5)在mybatis-config.xml文件中注册 mapper.xml文件
<mappers>
<mapper resource="mapper/SysUserMapper.xml"/>
</mappers>
(6)创建Mapper代理对象
SysUserMapper sysUserMapper = sqlSession.getMapper(SysUserMapper.class);
SysUser sysUser = sysUserMapper.selectById();
4、配置文件
5、可以创建properties去替代核心配置文件的信息
db.driver=com.mysql.cj.jdbc.Driver
db.url=jdbc:mysql://localhost:3306/db_mybatis
db.username=root
db.password=root
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<-- 加载外部配置--!>
<properties resource="jdbc.properties"></properties>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${db.driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
</environments>
<!--映入映射文件-->
<mappers>
<!-- <mapper resource="com/qf/mapper/UserMapper.xml"/>-->
<!-- 以包为单位,就必须保证路径和名称一致-->
<package name="com.qf.mapper"/>
</mappers>
</configuration>
5、select的时候,需要加resultType属性,设置映射关系
resultMap=""设置自定义映射关系
<!-- resultType=""设置映射关系 -->
<!-- resultMap=""设置自定义映射关系 -->
<select id="select" resultType="com.qf.entity.User">
select * from tb_user where id=7
</select>
6、select一般用xml形式
7、MyBatis传递参数
(1)${} 字符串拼接(存在sql注入风险、考虑数据类型问题,比如string+‘’)
(2)#{}占位字符串,预编译的做法,用于某个参数值,相当于prepareStatement(多)
@Select("select * from ${table} where id=#{id}")
User selectByIdAndTable(
@Param("table") String table,
@Param("id") Integer id
);
注意:表名只能用字符串拼接
8、单参数的传递
(1)利用注解重新赋值(多)
@Select("select * from ${table} where id=#{id}")
User selectByIdAndTable(
@Param("table") String table,
@Param("id") Integer id
);
@Test
public void selectByIdAndTableTest(){
//获取sql会话对象
SqlSession sqlSession = MyBatisDemo.getSqlSession();
//获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//调用方法测试
User user = mapper.selectByIdAndTable("tb_user",1);
System.out.println(user);
}
(2)不用注解的话参数的话只能用arg1, arg0, param1, param2这些形参
9、map形式传递多参
/**
* 通过map查询用户
* @return
*/
@Select("select * from tb_user where username=#{username} and password=#{password}")
User selectByUsernameAndPassword(Map<String, Object> map);
手动将数据写入到map中
@Test
public void selectByUsernameAndPassword(){
//获取sql会话对象
SqlSession sqlSession = MyBatisDemo.getSqlSession();
//获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> map = new HashMap<>();
map.put("username","tom");
map.put("password","123");
//调用方法测试
User user = mapper.selectByUsernameAndPassword(map);
System.out.println(user);
}
10、通过实体对象传递参数
/**
* 通过User实体类 新增数据
* @param user
* @return
*/
@Insert("insert into tb_user(username,password) values(#{username},#{password})")
Integer insertToUser(User user);
@Test
public void insertToUserTest(){
//获取sql会话对象
SqlSession sqlSession = MyBatisDemo.getSqlSession();
//获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User(null, "赵六", "111");
//调用方法测试
Integer num = mapper.insertToUser(user);
System.out.println(num);
}
11、查询单条数据,将数据转为map接收
@Select("select * from tb_user where id=#{id}")
Map<String,Object> findUserToMap(Integer id);
@Test
public void findUserToMapTest(){
//获取sql会话对象
SqlSession sqlSession = MyBatisDemo.getSqlSession();
//获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//直接返回
Map<String, Object> user = mapper.findUserToMap(1);
System.out.println(user);
}
注意:他可以去自动映射到map里面去
或者使用xml形式
<!-- Map<String,Object> findUserToMap(Integer id);-->
<select id="findUserToMap" resultType="map">
select * from tb_user where id=#{id}
</select>
12、查询多条数据
(1)转为一个个map,并用list整合
@Select("select * from tb_user")
List<Map<String,Object>> findUserAllToMap();
@Test
public void findAllUserToMapTest(){
//获取sql会话对象
SqlSession sqlSession = MyBatisDemo.getSqlSession();
//获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<Map<String, Object>> userAllToMap = mapper.findUserAllToMap();
userAllToMap.forEach(System.out::println);
}
(2)转为一个个map(只能通过xml方式),MapKey标识不同的记录
@MapKey("id")
Map<String,Object> findUserAllToMap();
<!-- Map<String,Object> findUserAllToMap();-->
<select id="findUserAllToMap" resultType="map">
select * from tb_user
</select>
@Test
public void findAllUserToMapTest(){
//获取sql会话对象
SqlSession sqlSession = MyBatisDemo.getSqlSession();
//获取mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, Object> users = mapper.findUserAllToMap();
System.out.println(users);
}
13、UNIQUE KEY设置唯一约束索引
14、COMMENT '主键',添加备注
15、驼峰命名(设置数据库字段与实体类的属性映射)
<!-- 设置数据库字段与实体类的属性映射-->
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
16、resultType设置映射(少用)
17、建表的时候设置,默认为指定数,now(0)表示只要年月日时分秒
18、标准的建表语句格式
19、数据库表生成之后,快速生成对应的实体类
20、时间对应的包
22、<typeAliases> <package name="com.qf.mybatis.entity">T</typeAliases>
用于定义别名,以便在映射文件中更方便地引用Java类型
23、typeAliases定义别名
在mybatis核心文件设置别名映射的时候,为指定的包下的所有类定义别名,以便在MyBatis的映射文件中更方便地引用这些类
type那里就可以不用写那么多了
注意:resultType也适用
24、resultMap定义如何将数据库查询的结果集映射到Java对象(映射)
id | resultMap的名称 |
type | resultMap对应的实体类(设别名后可直接写类名) |
extends | resultMap的继承 |
association | 一对一标签 |
collection | 一对多标签 |
子标签的id | 表示主键 |
property | 关联对象的属性名 |
column | 数据库字段名 |
结果集映射(列名与属性名不一致情况),多表查询、type简化
注意:extends可继承
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.qf.ssm.mapper.UserMapper">
<resultMap id="BaseResultMap" type="User">
<id property="userId" column="user_id"/>
<result property="username" column="username"/>
<result property="password" column="password"/>
<result property="phone" column="phone"/>
<result property="delStatus" column="del_status"/>
<result property="createDate" column="create_date"/>
</resultMap>
<resultMap id="SysUserDetailResultMap" type="UserDetail">
<id property="userDetailId" column="user_detail_id"/>
<result property="userId" column="user_id"/>
<result property="city" column="city"/>
<result property="birthday" column="birthday"/>
<result property="createTime" column="create_time"/>
<result property="delStatus" column="del_status"/>
</resultMap>
<!-- association一对一标签-->
<!-- property 关联对象的属性名称-->
<!-- resultMap 对应子表的ResultMap-->
<resultMap id="SysUSerAndDetailREsultMap" type="User" extends="BaseResultMap">
<association property="sysUserDetail" resultMap="SysUserDetailResultMap"/>
</resultMap>
<select id="selectByName" resultMap="SysUSerAndDetailREsultMap">
SELECT u.user_id, u.username, u.password, u.phone,
u.del_status, u.create_date,ud.user_detail_id,
ud.user_id, ud.city, ud.birthday,u.user_id,ud.create_time, ud.del_status
FROM sys_user u
INNER JOIN sys_user_detail ud
on u.user_id=ud.user_detail_id
WHERE u.username=#{username}
</select>
</mapper>
一对多
注意:写resultMap的时候必须先关联上他的select语句才有提示
25、Qo传递的是 controller Vo是结果的内人内容
27、关联查询的时候
(1)一对一:将从表的外键字段设置成唯一约束
(2)多对多:将主表主键作为从表字段
比如用户表和收货地址表 一对多的
28、主键 业务字段
29、把它的实体类当作另一个的属性
30、索引适合:字段不长,查多写少不容易修改的
31、子查询里面。in 单列多行 from 多多 select 单行多列 where 单行单列
32、写多表查询的时候,多的话就 ,在写inner join
33、inner join on的时候,如果字段都一样 ,可以用
34、数据库的连接
jdbc:mysql://localhost:3306/mybatis?characterEncoding=UTF-8&useSSL=false&useUnicode=true&serverTimezone=Asia/Shanghai&allowPublicKeyRetrieval=true
jdbc.username=root
jdbc.password=root
maxActive=20
35、<mapper namespace="com.qf.ssm.mapper.BrandMapper">,声明关联的接口类的全路径
36、select
属性
id | 对应mapper接口的方法名称 |
resultType(禁用) | 对应持久化类(entity) |
resultMap(多) | 对应定义的resultMap标签 |
37、查询禁止使用select *
38、表尽量使用别名
39、关于方法
id | 对应接口中方法的名称 |
keyproperty | 指定将数据库生成的键值赋给哪个Java对象的属性(属性通常用于定义或标识主键),告诉MyBatis在执行插入操作后是否检索数据库生成的键 |
useGeneratedKeys | 用于在执行插入操作后检索数据库生成的键(通常是自增主键) |
keyColumn | 用于指定数据库表中生成主键值的列名 |
40、获取自增主键id
给值、获取
<insert id="insert" keyProperty="brand.brandId" useGeneratedKeys="true">
40、resultMap
名称 | 正解 |
id | 给查询标签使用 |
type | 对应的持久化框架 |
extends | 表示继承其他的resultMap(可以是其他的mapper.xml中的resultMap) |
41、参数注解param
从mapper接口中传递参数到SQL中
46、查看表与表之间的关系
47、用不同的xml的时候,不同的xml类,在拼接的时候属性的resultMap需要写全路径(配了别名也不行)
48、创建索引
49、有多个的时候也是直接inner join就行,不用逗号
50、PO 是持久化对象 (entity)数据层入参,数据层返回值
DTO QO 请求参数对象,控制层(Controller)业务的入参