MyBatis
第一章
1.三层架构
界面层:和用户打交道的,接收用户的请求参数,显示处理结果(jsp,html,servlet)
业务逻辑层:接受了界面层传递的数据,计算逻辑,调用数据库,获取数据
数据访问层:就是访问数据库,执行对数据的查询,修改,删除等等
三层所对应的包
界面层:controller包(servlet)
业务逻辑层:service包(XXXService类)
数据访问层:dao包(XXXDao类)
三层中类的交互
用户使用界面层---->业务逻辑层---->数据访问层(持久层)---->数据库(mysql)
三层对应的处理框架
页面层-----servlet------springmvc(框架)
业务逻辑层-----service类-----spring(框架)
数据访问层----dao类----mybatis(框架)
2.框架
2.1.什么是框架?
框架是一个模块
1.框架中定义好了一些功能,这些功能是可用的
2.可以加入项目中自己的功能,这些功能可以利用框架中写好的功能
框架是一个软件,半成品的软件,定义好了一些基础功能,需要加入我们自己的功能,这样才是完整的
2.2.框架的特点
- 框架一般不是全能的,不能做所有事情
- 框架针对的是某一个领域有效,特长在某一个方面,比如mybatis做数据库操作能力强,但是不能做其他的事情
2,3.传统jdbc缺陷
- 代码量多,开发效率低
- 需要关注Connection,Statement,ResultSet对象的创建和销毁
- 对ResultSet查询的结果,需要自己封装成List
- 重复的代码比较多
- 业务代码和数据库的操作混在一起
2.4.mybatis框架
一个框架,早期叫做ibatis,代码在github上开源
mybaits是MyBatis SQL Mapper Framework for Java(sql映射框架)
(1)sql mapper:sql映射
可以把数据库表中的一行数据,映射为一个java对象
一行数据可以看作是一个java对象,操作这个对象,就相当于操作数据库表中的数据
(2)Data Access Object(DAOs):数据访问,对数据库执行增删改查
mybatis提供了哪些功能:
1.提供了创建Connection,Statement,ResultSet的能力,不用开发人员创建这些对象了
2.提供了执行sql语句的能力,不用你执行sql
3.提供了循环sql,把sql的查询结果转为java对象,List集合的能力
4.提供了关闭资源的能力,不用手动关闭Connection,Statement,ResultSet
开发人员要做的是:提供sql语句
最后是:开发人员提供sql语句----mybatis处理sql----开发人员得到List集合或者java对象(表中的数据)
总结:
mybatis是一个sql映射框架,提供对数据进行操作的能力,增强的jdbc,使用mybatis让开发人员集中精力写sql就可以了,不用关系Connection,Statement,ResultSet的创建和销毁
2.5.开发一个mybatis入门案例–连接数据库,查询数据
实现步骤:
-
新建一张表
-
加入maven的mybatis坐标,mysql驱动坐标
<?xml version="1.0" encoding="UTF-8"?> <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.lkw</groupId> <artifactId>mybatis01</artifactId> <version>1.0</version> <name>mybatis01</name> <!-- FIXME change it to the project's website --> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.8</maven.compiler.source> <maven.compiler.target>1.8</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <!--mybatis的依赖--> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.9</version> </dependency> <!--mysql驱动--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.25</version> </dependency> </dependencies> <build> <resources> <resource> <directory>src/main/resources</directory> <includes> <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> <resource> <directory>src/main/java</directory> <includes > <include>**/*.properties</include> <include>**/*.xml</include> </includes> <filtering>true</filtering> </resource> </resources> </build> </project>
-
创建实体类
public class Player { private Integer number; private String name; private String team; private String position; private Double salary; public Integer getNumber() { return number; } public void setNumber(Integer number) { this.number = number; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getTeam() { return team; } public void setTeam(String team) { this.team = team; } public String getPosition() { return position; } public void setPosition(String position) { this.position = position; } public Double getSalary() { return salary; } public void setSalary(Double salary) { this.salary = salary; } @Override public String toString() { return "Player{" + "number=" + number + ", name='" + name + '\'' + ", team='" + team + '\'' + ", position='" + position + '\'' + ", salary=" + salary + '}'; } }
-
创建持久层的dao接口,定义操作数据库的方法
public interface PlayerDao { //查询所有球员的信息 List<Player> selectPlayers(); }
-
创建一个mybatis使用的映射文件:叫做sql映射文件,写sql语句的,一般一张表一个sql映射文件,这个文件是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指的是映射的接口名称--> <mapper namespace="com.lkw.dao.PlayerDao"> <!--select:表示查询操作 id:你要执行的sql语句的唯一标识,mybatis会使用这个id的值来找到要执行的sql语句 可以自定义,但是要求使用接口方法中的方法名称 resultType:表示结果类型,是sql语句执行后得到的ResultSet,遍历这个ResutSet就能得到java对象的类型,值写的是类型的全限定名 --> <select id="selectPlayers" resultType="com.lkw.entity.Player"> select number,name,team,position,salary from player </select> </mapper> <!-- sql映射文件:写SQL语句的,mybatis会执行这些sql 1.指定约束文件 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> mybatis-3-mapper.dtd是约束文件的名称,扩展名是dtd的 2.约束文件的作用:限制,检查在当前文件中出现的标签,属性必须符合mybatis的规定 3.mapper:是当前文件的根标签,是必须的 namespace:叫做命名空间,唯一值的,可以是自定义的,但是最好写你使用的dao接口的全限定名称 4.在当前文件中,可以使用特定的标签,表示数据库的特定sql语句 <select>:表示查询,标签里面写select语句 <update>:表示更新数据 <insert>:表示插入数据 <delete>:表示删除 -->
-
创建mybatis的主配置文件,一个项目就一个主配置文件,主配置文件提供了数据库的连接信息和sql映射文件的位置信息
<?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> <!--mybatis.xml文件加入日志配置,可以在控制台输出执行的sql语句和参数--> <settings> <setting name="logImpl" value="STDOUT_LOGGING"></setting> </settings> <!--环境配置:数据库的连接信息 default:必须和某个environment的id值一样 告诉mybatis使用哪个数据库的连接信息,也就是访问哪个数据库,一个environments中可以出现多个environment 每个environment可以配置一个数据库的信息,然后environments后面的default跟的是哪个environment的id 表示的就是访问的是哪个数据库 --> <environments default="development"> <!--environment:一个数据库的配置信息 id:一个唯一值,自定义,表示环境的名称 --> <environment id="development"> <!-- transactionManager:mybatis的事务类型 type:JDBC(表示使用jdbc中的Connection对象的commit,rollback做事务处理) --> <transactionManager type="JDBC"/> <!--dataSource:表示数据源,连接数据库的 type:表示数据源的类型,POOLED表示数据库连接池 --> <dataSource type="POOLED"> <!-- 一下表示的是数据库的连接信息:其中name的值:driver,url,username,password都是mybatis规定好的,不能更改 value值是根据实际情况来写的 --> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--sql mapper(sql映射文件)的位置--> <mappers> <!-- 一个mapper标签指定一个文件的位置,从类路径开始的路径信息,target/classes(类路径) --> <mapper resource="com/lkw/dao/PlayerDao.xml"/> </mappers> </configuration> <!--mybatis的主配置文件:主要定义了数据库的配置信息,sql映射文件的位置 1.约束文件:<?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"> mybatis-3-config.dtd:约束文件的名称 2.configuration:根标签 -->
-
创建mybatis类,通过mybatis访问数据库
public class MyApp { public static void main(String[] args) throws IOException { //访问mybatis读取student的数据 //1.定义mybatis主配置文件的名称,从类路径的根开始(target/classes) String config = "mybatis.xml"; //2.读取这个config表示的文件 InputStream in = Resources.getResourceAsStream(config); //3.创建了SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); //4.创建SqlSessionFactory对象 SqlSessionFactory factory = builder.build(in); //5.【重要】获取sqlSession对象,从SqlSessionFactory中获取SqlSession SqlSession sqlSession = factory.openSession(); //6.[重要]指定要执行的sql语句的标识,sql映射文件中的namespace+"."+标签的id值 String sqlId = "com.lkw.dao.PlayerDao"+"."+"selectPlayers"; //7.执行sql语句,通过sqlId找到语句 List<Player> playerList = sqlSession.selectList(sqlId); //8.输出结果 for (Player player : playerList) { System.out.println(player); } //9.关闭SqlSession对象 sqlSession.close(); } }
第二章
1.主要类的使用
(1)Resources:mybatis中的一个类,负责读取主配置文件
InputStream in = Resources.getResourcesAsStream("mybatis.xml");
(2)SqlSessionFactoryBuilder:创建SqlSessionFactory对象
//创建SqlSessionFactoryBuider对象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//创建SqlSessionFactory对象
SqlSessionFactory factory = builder.build(in);
(3)SqlSessionFactory:重量级对象,程序创建一个对象耗时比较长,使用资源比较多,在整个项目中,有一个就够用了
SqlSessionFactory接口,实现类:DefaultSqlSessionFactory
SqlSessionFactory作用:获取SqlSession对象
SqlSession sqlSession = factory.openSession();
openSession()方法说明:
1.openSession():无参数的,获取是非自动提交事务的SqlSession对象
2.openSqlSession(boolean):参数为true表示获取自动提交事务的SqlSession对象,参数为false为获取非自动提交事务的SqlSession对象
(4)SqlSession:
SqlSession接口:定义了操作数据的方法,例如selectOne(),selectList(),insert(),update(),delete(),commit(),rollback()
SqlSession接口实现类DefaultSqlSession
使用要求:SqlSession对象不是线程安全的,需要在方法内部使用,在执行sql语句之前,使用openSession()获取SqlSession对象
在执行完sql语句之后,需要关闭它,执行SqlSession.close(),这样能保证它使用起来是线程安全的
第三章:
使用传统dao方式连接数据库查询数据库的缺点
不足之处:
-
需要创建接口的实现类来调用方法
public class PlayerDaoImpl implements PlayerDao { @Override public List<Player> selectPlayers() { //创建SqlSession对象 SqlSession sqlSession = MyBatisUtils.getSqlSession(); //sqlId String sqlId = "com.lkw.dao.PlayerDao.selectPlayers"; List<Player> players = sqlSession.selectList(sqlId); if (players != null) { return players; } return null; } @Override public int insertPlayer(Player player) { //获取SqlSession对象 SqlSession sqlSession = MyBatisUtils.getSqlSession(); //sqlid String sqlId = "com.lkw.dao.PlayerDao.insertPlayer"; //执行插入操作 int number = sqlSession.insert(sqlId, player); //手动提交事务 sqlSession.commit(); return number; } }
-
实现类中的sqlId不是动态的
使用动态代理机制创建接口的实现类并调用相关的方法操作数据库
测试类使用动态代理机制
public class TestPlayerDao {
@Test
public void testSelectPlayers(){
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//通过反射机制动态代理接口的实现类
PlayerDao mapper = sqlSession.getMapper(PlayerDao.class);//核心代码,创建PlayerDao的实现类
List<Player> players = mapper.selectPlayers();//调用接口层中的方法
for (Player player : players) {
System.out.println(player);
}
}
}
以上动态代理机制可以动态创建接口的实现类对象,并且动态调用接口中的方法,省去了很多重复的代码
动态代理:使用SqlSession.getMapper(dao接口.class)获取这个dao接口的实现类的对象
传入参数
从java代码中把数据传入到mapper文件的sql语句中
(1)parameterType:写在mapper文件中的一个属性,表示dao接口中方法的参数的数据类型
parameterType的值是java的数据类型的全限定名称或者是mybatis定义的别名,例如:
parameterType="java.lang.Integer"或者parameterType=“int”,这里之所以可以写成int,是因为这是在mybatis中规定好的,可以查看文档了解其他参数的对应关系
注意:parameterType不是强制的,mybatis通过反射机制能够自动检查到接口参数中的数据类型,所以可以没有
(2)传入一个简单数据类型的参数:
简单类型:mybatis把java中的基本数据类型和String都叫做简单数据类型,在mapper文件中获取简单数据类型的一个参数值,使用
#{任意字符}//任意字符指的是这里面的形参名字任意
接口:public Player selectPlayerById(Integer id)
mapper:select id,name,email,age from player where id=#{studentId}
使用#{}之后,mybatis执行sql是使用的jdbc中的PreparedStatement对象,由mybatis执行下面的代码:
1.mybatis创建Connection,PreparedStatement对象
String sql = "select number,name,team,position,salary from player where number=?";
PrepareStatement pst = conn.getPreparedStatement(sql);
//然后给sql语句中的占位符替换成number属性的值
(3)多个参数,使用@Param命名参数
接口public List selectMultiParam(@Param(“mynumber”)Integer number,@Param(“myname”) String name)
使用@Param(“参数名”) String name
使用mapper文件:
<select>
select * from player where number=#{mynumber} or name=#{myname}
</select>
多个参数,使用java对象作为接口中的方法的参数
接口中的方法是这样定义的:
List<Player> selectPlayers(Player player);//将对象作为方法的参数传值
实体类对象是这样定义的:
private Integer number;
private String name;
public Integer getNumber() {
return number;
}
public void setNumber(Integer number) {
this.number = number;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
在测试类中调用方法是这样的:
public void testSelectPlayers(){
SqlSession sqlSession = MyBatisUtils.getSqSession();
PlayerDao playerDao = sqlSession.getMapper(PlayerDao.class);
//创建球员对象
Player player = new Player();
player.setNumber(10);
player.setName("Garland");
//将球员对象作为参数传递到mapper接口的方法中
List<Player> players = playerDao.selectPlayers(player);
//遍历集合,输出对象里面的内容
………………
}
PlayerDao.xml:
<select>
select * from player where number=#{number} or name=#{name}
//以上代码是将mapper文件中的number和Player对象的number对应起来了,之所以能对应起来是因为有get和set方法
</select>
多个参数,使用位置作为参数值
多个参数,使用map作为参数值
上面这两种方式都可以进行对多个参数值的传递,但是都不推荐使用
(4)#和$的区别
select number,name,team,position,salary from player where number=#{number}
# 的结果:select number,name,team,position,salary from player where number=?
select number.name,team,position,salary from player where number=${number}
$ 的结果:select number,name,team,position,salary from player where number=30
String sql = "select number,name,team,position,salary from player where number="+"30";
$使用的Statement对象执行sql,效率比PreparedStatement低
`# 和$的区别:
- `#使用?在sql语句中作占位符,使用PreparedStatement执行sql,效率高,能够避免sql注入,安全性更高
- ` 不 使 用 占 位 符 , 是 字 符 串 连 接 方 式 , 使 用 S t a t e m e n t 对 象 执 行 s q l , 效 率 低 , 有 s q l 注 入 的 风 险 , 不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低,有sql注入的风险, 不使用占位符,是字符串连接方式,使用Statement对象执行sql,效率低,有sql注入的风险,可以替换表名或者列名
定义别名
第一种方式:
<typeAliases>
<!--
可以指定一个自定义别名
type:自定义类型的全限定名称
alias:别名(短小,容易记忆的)
-->
<!--定义多个别名-->
<typeAlias type="com.lkw.entity.Player" alias="player"></typeAlias>
<typeAlias type="com.lkw.entity.Student" alias="student"></typeAlias>
</typeAliases>
第二种方式:
<!--
第二种方式:就是给一个包起一个别名,然后类名就是别名
<package> name是包名,这个包中的所有类,类名就是别名(类名不区分大小写)
-->
<package name="com.lkw.entity"/>
以上的这种方式可以明显减少代码量,但是有一个缺点就是如果两个包中都有一个叫做Player的类,那么mybatis就无法识别具体是哪一个包名下面的类
综上所述:如果所要使用的类不多的情况下,还是建议使用全限定名称,不使用起别名的方式
当列名和属性名不一样的解决方案
(1)resultMap:结果映射,指定列名和java对象的属性的对应关系:
- 你自定义的列值赋值给哪个属性
- 当你的列名和属性名不一样的时候,一定使用resultMap
<!--resultMap
id:自定义名称,表示你定义的这个resultMap
type:java类型的全限定名称
-->
<resultMap id="playerMap" type="com.lkw.entity.Player">
<!--列名和java属性的关系-->
<!--
主键列:使用id标签
column:列名
property:java类型的属性名
-->
<!--当数据库中的列名和java对象中的属性名一致的时候-->
<id column="number" property="number">
<!--非主键列,使用result标签-->
<result column="name" property="name"/>
<result column="team" property="team"/>
<result column="position" property="position"/>
<!--当数据库中的列名和java对象的属性名不一致的时候-->
<id column="number" property="pnumber">
<!--非主键列,使用result标签-->
<result column="name" property="pname"/>
<result column="team" property="pteam"/>
<result column="position" property="pposition"/>
</resultMap>
<!--resultMap的使用-->
<select id="selectPlayerList" resultMap="playerMap">
select number,name,team,position from player
</select>
(2)依然使用resultType,但是在使用sql语句的时候稍稍做一些改进
<select id="selectPlayerList" resultType="com.lkw.entity.Player">
select number as pnumber,name as pname,team as pteam,position as pposition from player
</select>
总结:因为mybatis是将数据从数据库中查询出来之后,然后将数据库表中的列名和java对象的属性名做对应,如果列名和属性名一致的话,那么就会自动将从数据库中查出来的数据注入到与之对应的属性名上,因此想要保证取出来的数据能够绑定到java对象上,必须保证列名和属性名保持一致,一般情况下,遇到列名和属性名不一致的时候,使用的都是resultMap,很少使用第二种方式
mybatis中的模糊查询
mapper文件中的内容:
<!--第一种like,java代码指定like的内容-->
<select id="selectLikeOne" resultType="com.lkw.entity.Player">
select number,name,team,position salary from player where name like #{name}
</select>
<!--第二种方式:在mapper文件中拼接like的内容-->
<select id="selectLikeTwo" resultType="com.lkw.entity.Player">
select number,name,team,position salary from player where name like "%" #{name} "%"
</select>
java代码:
//第一种方式
public void testSelectLikeOne(){
String name="%S%"
selectLikeOne(name);
}
//第二种方式
public void testSelectLikeTwo(){
String name="S"
selectLikeOne(name);
}
第四章.动态sql
1.if标签
对于该标签的执行,当test的值为true的时候,会将其包含的SQL片段拼接到其所在的SQL语句的后面
<if test="判断条件">
sql语句的部分
</if>
mapper:
<select id="selectPlayerIf" resultType="com.lkw.entity.Player">
select number,name,team,position,salary from player
where 1=1<!--这里加上1=1是为了防止第一个if的值为false,那就会把第二个sql片段拼接到主sql之后,那么就会出现语法错误-->
<if test="name != '' and name != null">
<!--当判断条件为true的时候,将一下的sql片段拼接到主sql语句之后-->
and name=#{name}
</if>
<if test="salary == 6000">
<!--当判断条件为true的时候,将一下的sql片段拼接到主sql语句之后-->
and salary>#{salary}
</if>
</select>
2.where标签
<select id="selectPlayerIf" resultType="com.lkw.entity.Player">
select number,name,team,position,salary from player
<where>
<if test="name != '' and name != null">
<!--当判断条件为true的时候,将一下的sql片段拼接到主sql语句之后-->
and name=#{name}
</if>
<if test="salary == 6000">
<!--当判断条件为true的时候,将一下的sql片段拼接到主sql语句之后-->
and salary>#{salary}
</if>
</where>
</select>
总结:where标签就相当于对where做了改进,在执行sql语句的时候,会自动转换为where,写在where标签里面的if标签,只有在值为true的时候才会拼接到主sql语句的后面,并且会自动去除不合法的多余字符,就比如说,当第一个if的值为false的时候,不会把第二个and拼接到主sql之后,会自动去除,然后如果where中的所有if标签都不成立,那么就相当于是没有where条件,对这张表进行全查
3.foreach标签
<foreach collection="" item="" open="" close="" separator="">
</foreach>
collection:表示接口中的方法参数的类型,如果是数组,使用array,如果是list集合使用list
item:自定义的,表示数组和集合成员的变量
open:循环开始时的字符
close:循环结束时的字符
separator:集合成员之间的分隔符
foreach标签主要用于in中
<!--参数是普通数据类型的情况-->
<select id="selectForeachOne" resultType="com.lkw.entity.Student">
select * from player where number in
<foreach collection="list" item="number" open="(" close=")" separator=",">
#{number}
</foreach>
</select>
<!--要遍历的集合是抽象数据类型的时候-->
<select id="selectForeachTwo" resultType="com.lkw.entity.Student">
select * from player where number in
<foreach collection="list" item="player" open="(" close=")" separator=",">
#{player.number}<!--通过对象.属性来获取属性值-->
</foreach>
</select>
4.sql片段
<!--创建sql片段 id:片段的自定义名称-->
<sql id="playerSql">
select number,name,team,position,salary from player
</sql>
<!----使用定义好的sql片段>
<select id="selectForeachOne" resultType="com.lkw.entity.Student">
<include refid="playerSql"><!--这里写前面定义好的sql片段的id-->
<foreach collection="list" item="number" open="(" close=")" separator=",">
#{number}
</foreach>
</select>
总结:sql片段的主要作用是复用部分重复使用的代码sql代码片段,这里的sql片段可以是任意一段重复的代码片段,可以不是完整的sql语句
第五章.mybatis配置文件
transactionManager:mybatis提交事务,回滚事务的方式
type:事务的处理类型
(1)JDBC:表示mybatis底层调用的是JDBC中的Connection对象的,comiit,rollback
(2)MANAGED:把mybatis的事务处理委托给其他容器(一个服务器软件,一个框架(spring))
datasource:表示数据源,java体系中,规定实现了javax.sql.DataSource接口的都是数据源,数据源表示连接Connection对象的
type:指定数据源的类型
(1)POOLED:使用数据库连接池,mybatis会创建PooledDatasource类,数据库连接池就是在项目启动的时候预先创建多个Connection对象,在使用的时候不用再创建,直接使用即可
(2)UNPOOLED:不使用连接池,每次执行sql语句先创建连接,执行sql,再关闭连接,mybatis会创建一个UnPooledDataSource来管理Conection对象的使用
(3)JNDI:java命名和目录服务
1.数据的属性配置文件
把数据库连接信息放到一个单独的文件中,和mybatis主配置文件分开,目的是便于修改,保存,处理多个数据库的信息
(1)在resources目录中定义一个属性配置文件,xxx.properties,例如jdbc.properties
在属性配置文件中,定义数据,格式是key=value
key:一般使用"."作为多级目录
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=123456
(2)在mybatis的主配置文件,使用指定文件的位置,在需要使用的地方,${key}
<?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>
<!--指定属性配置文件的位置,mybatis会从resource的根路径下照这个配置文件,刚好这个配置文件就在resource的下一级目录中-->
<properties resource="jdbc.properties">
<!--mybatis.xml文件加入日志配置,可以在控制台输出执行的sql语句和参数-->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"></setting>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<!--使用jdbc.properties中的内容对数据库的连接信息进行替换-->
<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>
2.mapper文件,使用package指定路径
<mappers>
<!--方法一:
一个mapper标签指定一个文件的位置,从类路径开始的路径信息,target/classes(类路径),一个mapper标签只能指定一个 xml文件
-->
<mapper resource="com/lkw/dao/PlayerDao.xml"/>
<!--<mapper resource="com/lkw/dao/StudentDao.xml"/>-->
<!--方法二:使用包名
name:xml文件(mapper文件)所在的包名,这个包中所有的xml文件一次都能加载给mybatis,使用package的要求
1.mapper文件名称需要和接口名称一样,区分大小写的一样
2.mapper文件的dao接口需要在同一级目录下
-->
<package name="com.lkw.dao"/><!--这样就表示将com.lkw.dao包下面的所有xml文件都加载给mybatis进行管理-->
</mappers>
3.使用pageHelper插件实现分页功能
第一步:下载pageHelper依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
第二步:在mybatis的主配置文件中加上相应的配置信息
<!--配置pageHelper插件-->
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
<!--以上插件的配置要写在environments标签的上面-->
第三步使用pageHelper实现分页功能
public class TestPlayerDao {
@Test
public void testSelectPlayers(){
//获取SqlSession对象
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//通过反射机制动态代理接口的实现类
PlayerDao mapper = sqlSession.getMapper(PlayerDao.class);
//对数据进行分页操作
PageHelper.startPage(1,3);
List<Player> players = mapper.selectPlayers();
for (Player player : players) {
System.out.println(player);
}
}
}