1.如何构建MyBatis
1-1.导入坐标
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.15</version>
</dependency>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
1-2.创建mybatis配置文件
1-2-1.mybatic-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>
<properties resource="jdbc.properties"/>
<settings>
<!--将表中字段的下划线自动转换为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<typeAliases>
<!-- 类型别名 与实际项目为主 需要填-->
<package name="com.prettyspider.domain"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- mapper文件包名,需要填-->
<!--
以包为单位,将包下所有的映射文件引入核心配置文件
注意:此方式必须保证mapper接口和mapper映射文件必须在相同的包下
-->
<package name="com.prettyspider.mapper"/>
</mappers>
</configuration>
1-2-2.jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/对应的数据库
jdbc.username=root
jdbc.password=12345678
1-3.创建Mybatis mapper接口
public interface UserMapper {
/**
* 添加用户信息
* @return
*/
int insertUser();
LoginUser findLoginUserBuId(@Param("LoginUser") LoginUser loginUser);
}
1-4.创建MyBatis的映射文件
基于ORM对象关系映射
对象:Java的实体类对象
关系:关系型数据库
映射:二者之间的对应关系
映射文件的路径要和对应的接口的路径一样,这样配置文件中的mappers中的package才能生效
映射文件的命名规则: 表对应的实体类的类名 + Mapper.xml
1-5.核心文件详解
<?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文件,此时就可以${属性名}的方式访问属性值-->
<properties resource="jdbc.properties"></properties>
<settings>
<!--将表中字段的下划线自动转换为驼峰-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
</settings>
<typeAliases>
<!--
typeAlias:设置某个具体的类型的别名
属性:
type:需要设置别名的类型的全类名
alias:设置此类型的别名,若不设置此属性,该类型拥有默认的别名,即类名且不区分大小
写
若设置此属性,此时该类型的别名只能使用alias所设置的值
-->
<!--<typeAlias type="com.atguigu.mybatis.bean.User"></typeAlias>-->
<!--<typeAlias type="com.atguigu.mybatis.bean.User" alias="abc">
</typeAlias>-->
<!--以包为单位,设置改包下所有的类型都拥有默认的别名,即类名且不区分大小写-->
<package name="com.atguigu.mybatis.bean"/>
</typeAliases>
<!--
environments:设置多个连接数据库的环境
属性:
default:设置默认使用的环境的id
-->
<environments default="mysql_test">
<!--
environment:设置具体的连接数据库的环境信息
属性:
id:设置环境的唯一标识,可通过environments标签中的default设置某一个环境的id,
表示默认使用的环境
-->
<environment id="mysql_test">
<!--
transactionManager:设置事务管理方式
属性:
type:设置事务管理方式,type="JDBC|MANAGED"
type="JDBC":设置当前环境的事务管理都必须手动处理
type="MANAGED":设置事务被管理,例如spring中的AOP
-->
<transactionManager type="JDBC"/>
<!--
dataSource:设置数据源
属性:
type:设置数据源的类型,type="POOLED|UNPOOLED|JNDI"
type="POOLED":使用数据库连接池,即会将创建的连接进行缓存,下次使用可以从
缓存中直接获取,不需要重新创建
type="UNPOOLED":不使用数据库连接池,即每次使用连接都需要重新创建
type="JNDI":调用上下文中的数据源
-->
<dataSource type="POOLED">
<!--设置驱动类的全类名-->
<property name="driver" value="${jdbc.driver}"/>
<!--设置连接数据库的连接地址-->
<property name="url" value="${jdbc.url}"/>
<!--设置连接数据库的用户名-->
<property name="username" value="${jdbc.username}"/>
<!--设置连接数据库的密码-->
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--引入映射文件-->
<mappers>
<mapper resource="UserMapper.xml"/>
<!--
以包为单位,将包下所有的映射文件引入核心配置文件
注意:此方式必须保证mapper接口和mapper映射文件必须在相同的包下
-->
<package name="com.atguigu.mybatis.mapper"/>
</mappers>
</configuration>
2.对应的sql基本操作
2-1.如何运行
在对应的映射文件中的mapper标签的namespace 指向对应的接口,对应的sql操作标签的id指向对应的抽象方法
2-2.对应的增删改查
2-2-1.不传递参数或者传递非对象类型参数
2-2-1-1.接口
使用@Param标识参数
@Param中的值作为键,对应的参数为值
/**
* 添加用户信息
* @return
*/
int insertUser();
/**
* 根据id删除对应的数据
* @param id
* @return
*/
int deleteUserById(@Param("id") Integer id);
/**
* 根据id修改对应的行的数据
* @param id
* @param name
* @return
*/
int updateUser(@Param("id") Integer id,@Param("name") String name);
/**
* 根据id查找对应的数据
* @param id
* @return
*/
LoginUser findUserByid(@Param("id") Integer id);
2-2-1-2.映射文件
<!-- int insertUser();-->
<insert id="insertUser">
insert into loginuser values(null,'ts','123')
</insert>
<!-- int deleteUserById(@Param("id") Integer id);-->
<delete id="deleteUserById">
delete from loginuser where id = #{id}
</delete>
<!-- int updateUser(@Param("id") Integer id,@Param("name") String name);-->
<update id="updateUser">
update loginuser set name = #{name} where id = #{id}
</update>
<!-- int findUserByid(@Param("id") Integer id);-->
<select id="findUserByid" resultType="loginuser">
select * from loginuser where id = #{id}
</select>
2-2-1-3.测试类
// 获取对应的配置问价
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// 获取对应的SqlSessionFactoryBuilder对象
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 根据对应的工厂建立对象建立工厂
SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);
// 获取对应的SqlLSession对象
SqlSession session = sqlSessionFactory.openSession(true);
// 添加数据
UserMapper mapper = session.getMapper(UserMapper.class);
int i = mapper.insertUser();
// 删除数据
int i1 = mapper.deleteUserById(5);
System.out.println(i1);
// 修改数据
int i2 = mapper.updateUser(6, "lisi");
System.out.println(i2);
// 查找数据
LoginUser loginUserBuId = mapper.findUserByid(6);
System.out.println(loginUserBuId);
2-2-2.传递对象类型的参数
2-2-2-1.接口
int insertUserByObj(@Param("LoginUser") LoginUser loginUser);
int deleteUserByObj(@Param("LoginUser") LoginUser loginUser);
int updateUserByObj(@Param("LoginUser") LoginUser loginUser);
LoginUser findLoginUserBuId(@Param("LoginUser") LoginUser loginUser);
2-2-2-2.映射文件
对应的paramterType对应的数据传输的对象参数的类型地址
<!-- int insertUserByObj(@Param("LoginUser") LoginUser loginUser);-->
<insert id="insertUserByObj" parameterType="com.prettyspider.domain.LoginUser">
insert into loginuser values(#{LoginUser.id},#{LoginUser.name},#{LoginUser.password})
</insert>
<!-- int deleteUserByObj(@Param("LoginUser") LoginUser loginUser);-->
<delete id="deleteUserByObj" parameterType="com.prettyspider.domain.LoginUser">
delete from loginuser where id = #{LoginUser.id}
</delete>
<!-- int updateUserByObj(@Param("LoginUser") LoginUser loginUser);-->
<update id="updateUserByObj" parameterType="com.prettyspider.domain.LoginUser">
update loginuser set name = #{LoginUser.name} where id = #{LoginUser.id}
</update>
<!-- LoginUser findLoginUserBuId(@Param("id") Integer id);-->
<select id="findLoginUserBuId" resultType="loginuser" parameterType="com.prettyspider.domain.LoginUser">
select * from loginuser where id = #{LoginUser.id}
</select>
2-2-2-3.测试类
LoginUser user = new LoginUser(100, "lisi", "1234");
int i3 = mapper.insertUserByObj(user);
System.out.println(i3);
int i5 = mapper.updateUserByObj(user);
System.out.println(i5);
LoginUser loginUser = mapper.findLoginUserBuId(user);
System.out.println(loginUser);
int i4 = mapper.deleteUserByObj(user);
System.out.println(i4);
不管是哪种类型,对应的select标签中一定要设置对应的resultType或者是resultMap
2-3.获取参数的两种方式 #{} ${}
2-3-1.两者的区别
#{}本质上是占位符拼接,${}本质上是字符串拼接
#{}会自动添加引号,${}不会自动添加引号
${}会发生sql注入,导致sql语句出错
一般尽量使用#{}
2-3-2.不同的情况下
当传递多个参数时,MyBatis会将对应的值放入到一个map集合,默认可以通过键arg0,arg1或者是param1,param2获取,也可以使用字面量直接获取
2-3-2-1.单个字面量类型的参数
两者都可以用任意的名称获取,这里的任意是以上蓝色字体中的名称,不能超过,否则会报错
org.apache.ibatis.binding.BindingException: Parameter 'ids' not found. Available parameters are [id, param1]
2-3-2-2.多个字面量类型的参数
同以上蓝色字体内容
2-3-2-3.实体类类型的参数
在2-2-2中,传递的参数是实体类,对应的sql语句中是直接获取对应的数据,这是不符合JavaBean的定义的,对应的属性是私有的,是不能被获取的,这里为什么可以用对应的属性直接获取对应的属性值呢
MyBatis中参数为实体类时,会利用反射机制实现,通过反射,直接将对应的实体类对象的属性映射到sql语句的参数中,这里直接用属性获取属性值和对应的getter方法后驱属性值是一样的
2-3-2-4.使用@Param标识参数
可以通过@Param注解标识mapper接口中的方法参数,以@Param注解的value属性值为键获取对应的值