Mybatis——进阶
目录
1、环境搭建
2、parameterType
1.1、传入多个参数
1.2、解决方式1
1.3、解决方式2
3、#与$的区别
3.1、#的用法
3.2、$的用法
3.3、#和$的区别
4、resultMap用法
5、sql片段
5.1、用法1
5.2、用法2
前言:请先行观看之前文章Mybatis——快速入门篇后再看该篇文章,方便理解
1、环境搭建
数据库
CREATE TABLE `t_user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(20) DEFAULT NULL,
`password` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` char(1) DEFAULT NULL,
`email` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8;
pom.xml文件
<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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.itssl</groupId>
<artifactId>mybatis_day02</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.18</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
</dependencies>
</project>
User实体类
@Data
public class User {
private int id;
private String username;
private String password;
private int age;
private String sex;
private String email;
}
jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql:///数据库名
username=root
password=你的数据库密码
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>
<!--引入properties文件,此时就可以${属性名}的方式访问属性值-->
<properties resource="jdbc.properties"></properties>
<typeAliases>
<package name="cn.itssl.pojo"/>
</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 resource="mapper/UserMapper.xml"/>
</mappers>
</configuration>
2、parameterType
1.1、传入多个参数
UserMapper接口
public interface UserMapper {
/**
* @description:用户登录
**/
User loginUser(String username,String password);
}
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">
<mapper namespace="cn.itssl.mapper.UserMapper">
<!--用户登录-->
<select id="loginUser" resultType="User">
select *
from t_user
where username = #{username}
and password = #{password}
</select>
</mapper>
选中UserMapper接口,点击右键,选中Go To,选择Test
选择setUp/@Before,在下面选中方法,因为我这里idea出问题了,没有提示出来,所以没有显示
idea会自动生成一个测试类存放在test包下
编写代码
public class UserMapperTest {
private SqlSession sqlSession;
private UserMapper userMapper;
@Before
public void setUp() throws Exception {
//获取核心配置文件
String resource = "mybatis-config.xml";
//加载配置文件
InputStream inputStream = Resources.getResourceAsStream(resource);
//构建SqlSessionFactory对象
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//构建Sqlsession对象
sqlSession = sqlSessionFactory.openSession(true);
//把sqlSession对象传递至dao层
// userDao = new UserDaoImpl(sqlSession);
//使用动态代理
userMapper = sqlSession.getMapper(UserMapper.class);
}
@Test
public void login(){
User user = userMapper.loginUser("jack", "1234");
System.out.println(user);
}
}
运行login方法
发现出现了异常,那么肯定是我们代码有地方书写的有问题,因为Mybatis在多参数传递时,需要进行解决异常,那么下面提供两种解决方式
1.2、解决方式1
在mapper.xml中使用 0,1这样的序号去,0表示第一个参数,1表示第二个参数。(从0开始数)
<!--登录-->
<select id="loginUser" resultType="User">
select * from t_user where username = #{arg0} and password = #{arg1}
</select>
或者 用param1 param2 这个时就是从1开始
<!--登录-->
<select id="loginUser" resultType="User">
select * from t_user where username = #{param1} and password = #{param2}
</select>
1.3、解决方式2
需要在UserMapper接口的方法中加入@Param注解,这种方式也是最推荐使用的
public interface UserMapper {
/**
* @description:用户登录
* @author: Shenshuanglong
* @date: 2022/10/17 0017 19:05
* @param: [username, password]
* @return: void
**/
User loginUser(@Param("username") String username,@Param("password") String password);
}
注意事项:@Param注解里面的名称可以随便起,但要注意映射文件中的sql语句的参数,就得写@Param注解里面的名称
3、#与$的区别
1、$字符串拼接,# 参数站位相当于?
2、$不能够防止sql注入,#可以防止sql注入的
3、$要考虑参类型 ,#不用考虑参数类型
4、$可以替换sql语句任何一个内容,#只能替换参数
3.1、#的用法
#不用考虑参数类型
#可以防止sql注入
<!--登录-->
<select id="login" resultType="User">
<!--使用#-->
select * from t_user where username = #{name} and password = #{password}
</select>
/**
* 登录
*/
public User login(@Param("name") String name ,@Param("password") String password);
@Test
public void testLogin(){
User u = userMapper.login("jack", "123");//#不用考虑参数类型
User u = userMapper.login("' or '1' = '1", "' or '1' = '1");//#防止sql注入
System.out.println(u);
}
3.2、$的用法
用于字符串拼接
/**
* 根据表名来查询
* @param name
*/
public List<User> queryByTableName(String name);
<!--根据表名来查询-->
<select id="queryByTableName" resultType="User">
select * from ${name}
</select>
@Test
public void testqueryByTableName(){
List<User> list = this.userMapper.queryByTableName("t_user");
for(User user : list){
System.out.println(user);
}
}
$ 需要考虑参数类型
$不防止sql注入
<!--登录-->
<select id="login" resultType="User">
<!--使用$ 需要考虑参数类型-->
select * from t_user where username = '${name}' and password = '${password}'
</select>
/**
* 登录
*/
public User login(@Param("name") String name ,@Param("password") String password);
@Test
public void testLogin(){
User u = userMapper.login("jack", "123");//$考虑参数类型
User u = userMapper.login("' or '1' = '1", "' or '1' = '1");//$不能防止sql注入
System.out.println(u);
}
3.3、#和$的区别
$可以代替所有#
如果传入的数据,不是sql中的字段的时候,就不能够使用#.通常使用#。
选择获取参数的时候,首要选择的# 的方式
(1、可以防止sql注入,2、可以不用考虑数据类型,简化书写,3、sql是参数的话的sql,预编译的sql,速度会块一些)
当#用不了的时候,去选择$例如 ,sql需要改变是表名的情况,就可使用$的方式。总结:能用# 就不选择$
4、resultMap用法
ResultMap 是Mybatis中最为重要的元素,使用ResultMap 可以解决两大问题:
1、pojo属性名与数据库字段名不一致问题
2、完成高级查询,一对一,一对多, 多对多(后面讲)
<!--查询所有映射-->
<!--
id:resultMap的标识
type:映射的类型
autoMapping:true(默认) 支持 属性名与字段名自动映射 false:只针对resultMap定义的属性映射
-->
<resultMap id="userResultMap" type="User" autoMapping="true">
<!--id一般作为主键,它有自己的标签,实现属性名与字段名一一映射-->
<id column="id" property="id"/>
<!--除了id以外的字段,用result标签实现属性名与字段名一一映射-->
<result column="user_name" property="userName"/>
<!--如果,属性名与字段一致,可以省略不写-->
<result column="sex" property="sex"/>
</resultMap>
<!--查询所有-->
<select id="queryAllUser" resultMap="userResultMap">
select * from t_user
</select>
5、sql片段
5.1、用法1
<!--抽取sql-->
<sql id="userColumn">
id ,user_name ,password , sex
</sql>
<!--查询所有-->
<select id="queryAllUser" resultMap="userResultMap">
select <include refid="userColumn"/> from t_user
</select>
5.2、用法2
以下用法1抽取的sql只能在本xml中使用,那如何这个抽取的sql其他xml也想使用怎么办呢?用法2就是可以将sql单独抽取到一个文件中,这样其他的xml就可以直接使用
单独创建一个UserSQLMapper.xml文件
<mapper namespace="abc">
<!--抽取sql-->
<sql id="userColumn">
id ,user_name ,passworld , sex
</sql>
</mapper>
<!--查询所有-->
<select id="queryAllUser" resultMap="userResultMap">
select <include refid="abc.userColumn"/> from t_user
</select>
<!--注意别忘了:mybatis-config.xml 引入-->
<mapper resource="UserSQLMapper.xml"/>
未完待续....