目录
2、解决方法二:根据结果集的映射,手动指定数据库字段和实体类中属性的匹配方式
一、通过包的形式指定Mapper文件
将dao层改为mapper层,接口命名为XxxxMapper
package:通过包指定mapper文件的位置;
XML文件名字和接口名字保持一致
XML文件的层级目录要和接口保持一致
<mappers>
<package name="com.mybatis.mapper"/>
</mappers>
1、代码演示
(1)准备数据库
CREATE DATABASE mybatisdatabase;
USE mybatisdatabase;
CREATE TABLE IF NOT EXISTS `admin`(
`uid` INT PRIMARY KEY AUTO_INCREMENT,
`username` VARCHAR(20),
`upassword` VARCHAR(20) NOT NULL,
`address` VARCHAR(10) NOT NULL
);
INSERT INTO `admin`(`username`,`upassword`,`address`) VALUES
('张三','123456','安徽合肥包河区'),
('李四','456789','安徽合肥高新区');
(2)创建module,创建maven工程、完善工程目录
(3)在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>com.mybatis</groupId>
<artifactId>mybatis03</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>mybatis03</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.48</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
</dependencies>
</project>
(4)搭建MVC架构,创建实体类以及mapper层级下的接口
package com.mybatis.entity;
import lombok.Data;
@Data
public class Admin {
private long uid;
private String username;
private String upassword;
private String address;
}
package com.mybatis.mapper;
import com.mybatis.entity.Admin;
import java.util.List;
public interface AdminMapper {
public List<Admin> selectAll();
}
(5)在resources目录下新建文件夹Directory,用来放置mybatis全局配置文件
<?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"/>
<!-- 开启日志打印-->
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<package name="com.mybatis.entity"/>
<package name="com.mybatis.dao"/>
</typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatisdatabase"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.mybatis.mapper.AdminMapper"/>
</mappers>
</configuration>
(6)在resources目录下新建Directory放置mapper映射文件,包名和mapper接口相同
<?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="com.mybatis.mapper.AdminMapper">
<select id="selectAll" resultType="admin">
select * from admin
</select>
</mapper>
(7)在resources目录下添加log4j.properties配置文件
#打印日志的级别:可控制打印信息,哪些打印,哪些不打印
#Console:打印窗口
log4j.rootLogger=DEBUG,Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
#设置打印格式
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
#设置打印信息
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
#打印日志级别:设置打印级别只要不是ERROR级别就不打印
log4j.logger.org.apache=ERROR
log4j.logger.org.mybatis=ERROR
log4j.logger.org.springframework=ERROR
#这个需要
log4j.logger.log4jdbc.debug=ERROR
log4j.logger.com.gk.mapper=ERROR
log4j.logger.jdbc.audit=ERROR
log4j.logger.jdbc.resultset=ERROR
#这个打印SQL语句非常重要
log4j.logger.jdbc.sqlonly=DEBUG
log4j.logger.jdbc.sqltiming=ERROR
log4j.logger.jdbc.connection=FATAL
(8)代码测试
package com.mybatis.mapper;
import com.mybatis.entity.Admin;
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.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import static org.junit.Assert.*;
public class AdminMapperTest {
//创建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init(){
System.out.println("init()");
InputStream resourceAsStream;
try {
resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");
} catch (IOException e) {
throw new RuntimeException(e);
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
}
@Test
public void selectAll() {
//创建SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取AdminMapper接口动态代理对象
AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class);
//通过接口调用方法
List<Admin> adminList = adminMapper.selectAll();
//输出
for (Admin admin:adminList){
System.out.println("admin = " + admin);
}
//关闭资源
sqlSession.close();
}
}
二、通过配置文件配置mybatis全局配置参数
1、配置properties文件
在resources目录下的config中新建Resource Bundle
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatisdatabase jdbc.username=root jdbc.password=123456
2、在mybqtis全局配置文件引入外部数据源
在mybatis全局配置文件中的<configuration>标签中使用<properties>标签引入外部数据源
<?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="config/jdbc.properties"></properties>
<settings>
<!-- 开启驼峰映射-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启日志打印-->
<setting name="logImpl" value="LOG4J"/>
</settings>
<typeAliases>
<package name="com.mybatis.entity"/>
</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>
<package name="com.mybatis.mapper"/>
</mappers>
</configuration>
三、处理实体类属性名与数据库字段名不一致返回结果集问题
当实体类的属性与数据库字段名不一致时,无法获取数据库中的数据,那如何解决呢?
1、解决方法一:给表字段名起别名
select查询的结果是一张表,但这张表不是真实存在的,我们在代码中拿到的数据是这张表的数据,我们可以通过给数据库字段名起别名来获取数据
<?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="com.mybatis.mapper.AdminMapper">
<select id="selectAll" resultType="admin">
select uid,username AS uname,upassword,address from admin
</select>
</mapper>
2、解决方法二:根据结果集的映射,手动指定数据库字段和实体类中属性的匹配方式
在mapper文件中,使用resultMap标签设置数据库字段对应的实体类属性
--->id:映射名称
--->type:映射结果集的类型
id标签:数据库表的主键
result标签:结果
--->column:数据库字段名
--->property:实体类属性
<?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="com.mybatis.mapper.AdminMapper">
<resultMap id="adminMap" type="admin">
<id column="uid" property="uid"></id>
<result column="username" property="uname"></result>
<result column="upassword" property="upassword"></result>
<result column="address" property="address"></result>
</resultMap>
<select id="selectAll" resultMap="adminMap">
select * from admin
</select>
</mapper>
三、MyBatis对参数的处理
一般在传参时,都是根据属性名传参
1、单个参数的传递方式
当只传递一个参数时,SQL语句取值时标识符可任意(违背了见名知意的规则,一般不使用)
2、多个参数的传递方式
在MyBatis中传递多个参数时,传统的传递参数方式不适用
在MyBatis中传递多个参数时使用param标识符
<?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="com.mybatis.mapper.AdminMapper">
<resultMap id="adminMap" type="admin">
<id column="uid" property="uid"></id>
<result column="username" property="uname"></result>
<result column="upassword" property="upassword"></result>
<result column="address" property="address"></result>
</resultMap>
<select id="selectAll" resultMap="adminMap">
select * from admin
</select>
<select id="selectByUidAdmin" resultMap="adminMap">
select * from admin where uid = #{a}
</select>
<select id="selectBYUnameByUpassword" resultMap="adminMap">
select * from admin where username = #{param1} and upassword = #{param2}
</select>
</mapper>
package com.mybatis.mapper;
import com.mybatis.entity.Admin;
import java.util.List;
public interface AdminMapper {
List<Admin> selectAll();
Admin selectByUidAdmin( int uid);
Admin selectBYUnameByUpassword(String uname,String upassword);
}
package com.mybatis.mapper;
import com.mybatis.entity.Admin;
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.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import static org.junit.Assert.*;
public class AdminMapperTest {
//创建SqlSessionFactory工厂对象
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init(){
System.out.println("init()");
InputStream resourceAsStream;
try {
resourceAsStream = Resources.getResourceAsStream("config/mybatis-config.xml");
} catch (IOException e) {
throw new RuntimeException(e);
}
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
}
@Test
public void selectAll() {
//创建SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取AdminMapper接口动态代理对象
AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class);
//通过接口调用方法
List<Admin> adminList = adminMapper.selectAll();
//输出
for (Admin admin:adminList){
System.out.println("admin = " + admin);
}
//关闭资源
sqlSession.close();
}
@Test
public void selectByUidAdmin() {
//创建SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取AdminMapper的动态代理对象
AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class);
//通过接口调用方法
Admin admin = adminMapper.selectByUidAdmin(2);
System.out.println("admin = " + admin);
//关闭资源
sqlSession.close();
}
@Test
public void selectBYUnameByUpassword() {
//创建SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取AdminMapper的动态代理对象
AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class);
//通过接口调用方法
Admin admin = adminMapper.selectBYUnameByUpassword("张三", "123456");
System.out.println("admin = " + admin);
//关闭资源
sqlSession.close();
}
}
SQL语句中的username是数据库的字段名
3、使用@Param注解
给传递的参数名使用@Param注解
@Param:参数的标识符注解,后续在SQL语句中取值时,可以使用注解中配置的标识
4、通过实体类对象实现参数的传递
传递给SQL语句的参数是一个实体类对象,底层通过调用实体类的get()方法获取属性值
//通过实体类对象传参
Admin selectAdmin(Admin admin);
<select id="selectAdmin" resultMap="adminMap" parameterType="admin">
select * from admin where username = #{uname} and upassword = #{upassword}
</select>
@Test
public void selectAdmin() {
//创建SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取AdminMapper的动态代理对象
AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class);
//创建实体类对象
Admin admin = new Admin();
admin.setUname("李四");
admin.setUpassword("456789");
System.out.println("admin = " + admin);
//通过接口调用方法
Admin admin1 = adminMapper.selectAdmin(admin);
System.out.println("admin1 = " + admin1);
//关闭资源
sqlSession.close();
}
5、通过Map集合传递参数
将需要传递的参数封装成一个Map集合,根据key获取对应的参数(标识符要和key保持一致)
//通过map集合传递参数
Admin selectByMap(Map<String,Object> map);
<select id="selectByMap" resultMap="adminMap" parameterType="map">
select * from admin where username = #{uname} and upassword = #{upassword}
</select>
@Test
public void selectByMap() {
//创建SqlSession会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//获取AdminMapper的动态代理对象
AdminMapper adminMapper = sqlSession.getMapper(AdminMapper.class);
//创建Map集合
HashMap<String, Object> map = new HashMap<>();
map.put("uname","张三");
map.put("upassword","123456");
//通过接口调用方法
Admin admin = adminMapper.selectByMap(map);
System.out.println("admin = " + admin);
//关闭资源
sqlSession.close();
}
四、取值标识符的区别
1、#{ }
(1)采用sql语句预编译的方式实现数据库的操作
(2)防止sql语句的注入
(3)效率较高
(4)字符串会自动添加单引号
2、${ }
(1)采用SQL语句的拼接
(2)容易出现SQL注入问题
(3)效率较低
(4)字符串不会自动添加单引号
<select id="selectBYUnameByUpassword" resultMap="adminMap">
select * from admin where username = '${uname}' and upassword = '${upassword}'
</select>