ctrl + alt + T 是try,catch的快捷键
alt+insert 快捷键
alt+enter
搭建MyBatis框架
6 开发环境和准备工作
IDE:idea 2019.2
构建工具:maven 3.5.4
MySQL版本:MySQL 8
MyBatis版本:MyBatis 3.5.7
MySQL不同版本的注意事项
1、驱动类driver-class-name
MySQL 5版本使用jdbc5驱动,驱动类使用:com.mysql.jdbc.Driver
MySQL 8版本使用jdbc8驱动,驱动类使用:com.mysql.cj.jdbc.Driver
2、连接地址url
MySQL 5版本的url: jdbc:mysql://localhost:3306/ssm
MySQL 8版本的url: jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC
否则运行测试用例报告如下错误: java.sql.SQLException: The server time zone value 'Öйú±ê׼ʱ¼ä' is unrecognized or represents more
导入依赖
<dependencies> <!-- Mybatis核心 --> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.5.7</version> </dependency> <!-- junit测试 --> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> <scope>test</scope> </dependency> <!-- MySQL驱动 --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.16</version> </dependency> </dependencies>
实体类创建
快捷键alt+insert
有参构造,无参构造,tostring
package com.mybatis.pojo; public class User { private Integer id; private String username; private String password; private Integer age; private String gender; private String email; public User(Integer id, String username, String password, Integer age, String gender, String email) { this.id = id; this.username = username; this.password = password; this.age = age; this.gender = gender; this.email = email; } public Integer getId() { return id; } public User setId(Integer id) { this.id = id; return this; } public String getUsername() { return username; } public User setUsername(String username) { this.username = username; return this; } public String getPassword() { return password; } public User setPassword(String password) { this.password = password; return this; } public Integer getAge() { return age; } public User setAge(Integer age) { this.age = age; return this; } public String getGender() { return gender; } public User setGender(String gender) { this.gender = gender; return this; } public String getEmail() { return email; } public User setEmail(String email) { this.email = email; return this; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", age=" + age + ", gender='" + gender + '\'' + ", email='" + email + '\'' + '}'; } }
7 创建MyBatis核心配置文件
核心配置文件
<?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> <!--设置连接数据库的环境--> <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://localhost:3306/ssm? serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments> <!--引入映射文件--> <mappers> <package name="mappers/UserMapper.xml"/> </mappers> </configuration>
8 创建Mapper接口和映射文件
Usermapper.java
package com.mybatis.mapper; public interface UserMapper { int insertUser(); }
usermapper.xml
<mapper namespace="com.mybatis.mapper.UserMapper">是上面的全类名
<?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.UserMapper"> <!--int insertUser();--> <insert id="insertUser"> insert into t_user values(null,'admin','123456',23,'男','12345@qq.com') </insert> </mapper>
mybatis-config.xml
<!--引入映射文件--> <mappers> <package name="mappers/UserMapper.xml"/> </mappers>
两个一致
mapper接口的全类名和映射文件的namespace一致
mapper接口中的方法的方法名要和映射文件中的sql的id保持一致
9 测试添加用户功能
MybatisTest
package com.mybatis.test; import com.mybatis.mapper.UserMapper; import com.mybatis.pojo.User; 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 MyBatisTest { @Test public void testInsert() throws IOException { //获取核心配置文件的输入流 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //获取SQL session Factory对象 SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder(); //获取SqlSessionFactory对象 SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is); //获取sql会话对象SqlSession,是Mybatis提供的操作数据库的对象 SqlSession sqlSession=sqlSessionFactory.openSession(); //获取UserMapper的代理实现类对象 UserMapper mapper = sqlSession.getMapper(UserMapper.class); //User user = sqlSession.getMapper(User.class); //调用mapper接口中的方法,实现添加用户信息的功能 int result=mapper.insertUser(); System.out.println("结果:"+result); //提交事务 sqlSession.commit(); //关闭sqlsession sqlSession.close(); } }
10 优化功能
核心配置文件,配置连接数据库的环境mybatis-config.xml
引入映射文件
mapper接口(保持两个一致)
用的少:(了解)
int result = sqlSession.insert(UserMapper.insertUser);
11 源码验证和日志级别--log4j
日志的级别
FATAL(致命)>ERROR(错误)>WARN(警告)>INFO(信息)>DEBUG(调试)
从左到右打印的内容越来越详细
log4j.properties
log4j.rootLogger=debug, stdout, R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout # Pattern to output the caller's file name and line number. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] (%F:%L) - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=example.log log4j.appender.R.MaxFileSize=100KB # Keep one backup file log4j.appender.R.MaxBackupIndex=5 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
log4j.xml
<?xml version="1.0" encoding="GB2312" ?> <!DOCTYPE log4j:configuration SYSTEM "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd"> <log4j:configuration debug="true"> <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender"> <param name="Encoding" value="UTF-8" /> <layout class="org.apache.log4j.PatternLayout"> <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" /> </layout> </appender> <logger name="java.sql"> <level value="debug" /> </logger> <logger name="org.apache.ibatis"> <level value="info" /> </logger> <root> <level value="debug" /> <appender-ref ref="STDOUT" /> </root> </log4j:configuration>
12 测试修改和删除用户的功能
SqlSessionUtil.java
新建一个工具类,封装到这里
com.mybatis.utils
package com.mybatis.utils; 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 java.io.IOException; import java.io.InputStream; public class SqlSessionUtil { public static SqlSession getSqlSession(){ SqlSession sqlSession=null; try { //获取核心配置文件的输入流 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); //获取SqlSessionFactoryBuilder SqlSessionFactoryBuilder sqlSessionFactoryBuilder=new SqlSessionFactoryBuilder(); //获取SqlSessionFactory SqlSessionFactory sqlSessionFactory=sqlSessionFactoryBuilder.build(is); //获取sqlSession对象 sqlSession=sqlSessionFactory.openSession(true); } catch (IOException e) { e.printStackTrace(); } return sqlSession; } }
UserMapper.xml
<!-- void updateUser(); --> <update id="updateUser"> update t_user set username="root",password="123" where id=3 </update> <!-- void deletdeUser(); --> <delete id="deleteUser"> delete from t_user where id=3 </delete>
UserMapper.java
package com.mybatis.mapper; public interface UserMapper { int insertUser(); void updateUser(); void deleteUser(); }
Test.java
@Test public void testUpdate(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.updateUser(); sqlSession.close(); } @Test public void testDelete(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); mapper.deleteUser(); sqlSession.close(); }
13 测试查询功能
UserMapper.java
package com.mybatis.mapper; import com.mybatis.pojo.User; import java.util.List; public interface UserMapper { int insertUser(); void updateUser(); void deleteUser(); User getUserById(); List<User> getAllUser(); }
较上节课新增的有(查询)
User getUserById(); List<User> getAllUser();
UserMapper.xml
<!-- resultType : 设置结果类型,即查询的数据要转换为的Java类型 resultMap : 自定义映射,处理多对一或一对多的映射关系 --> <select id="getUserById" resultType="com.mybatis.pojo.User"> select * from t_user where id=1 </select> <!-- List<User> getAllUser --> <select id="getAllUser" resultType="com.mybatis.pojo.User"> select * from t_user </select>
Test.java
@Test public void testGetUserById(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user=mapper.getUserById(); System.out.println(user); } @Test public void testGetAllUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> list=mapper.getAllUser(); // list.forEach(System.out::println); //最后一句不好使,不能运行 }
Mybatis核心配置文件
14 environments
<!-- environments:配置连接数据库的环境 属性: default:设置默认使用的环境id --> <environments default="development"> <!-- environment:设置一个具体的连接数据库环境 属性: id:设置环境的唯一标识,不能重复 --> <environment id="development"> <!-- transactionManager:设置事务管理器 属性: type:设置事务管理的方式 type="JDBC/MANAGED" JDBC:表示使用JDBC中原生的事务管理方式 MANAGED:被管理,例如Spring --> <transactionManager type="JDBC"/> <!-- dataSource:设置数据源 属性: type="POOLED/UNPOOLED/JNDI" POOLED:表示使用数据库连接池 UNPOOLED:表示不使用数据库连接池 JNDI:表示使用上下文中的数据源 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.cj.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/ssm? serverTimezone=UTC"/> <property name="username" value="root"/> <property name="password" value="123456"/> </dataSource> </environment> </environments>
1 . default:设置默认的id
<environment id="development">
上面有标注
15 properties
jdbc.properties(新建的文件)
jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC jdbc.username=root jdbc.password=123456
mybatis-config.xml
<!--引入properties文件,此后就可以在当前文件中使用 ${key} 的方式访问value --> <properties resource="jdbc.properties"></properties>
<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>
16 typeAliases类型别名
配置顺序
Mybatis核心配置文件中的标签必须要按照指定的顺序配置 properties?,settings?,typeAliases?,typeHandlers?, objectFactory?,objectWrapperFactory?,reflectorFactory?, plugins?,environments?,databaseIdProvider?,mappers?
mybatis-config.xml
<!-- typeAlias:设置类型别名,即为某个具体的类型设置一个别名 在Mybatis范围内,就可以使用别名表示一个具体的类型 --> <typeAliases> <!-- type:设置需要起别名的类型 alias:设置某个类型的别名 --> <!--<typeAlias type="com.mybatis.pojo.User" alias="abc"></typeAlias>--> <!--若不设置alias,当前的类型拥有默认的别名,即类名且不区分大小写 --> <!--<typeAlias type="com.mybatis.pojo.User"></typeAlias>--> <!--通过包设置类型别名,指定包下所有的类型将全部拥有默认的别名,即类名且不区分大小写--> <package name="com.mybatis.pojo"/> </typeAliases>
UserMapper.xml
resultType="com.mybatis.pojo.User"
可以写为resultType="User
<select id="getUserById" resultType="User"> select * from t_user where id=1 </select>
17 mappers
<mappers> <!--<mapper resource="mappers/UserMapper.xml"></mapper>--> <!-- 以包的方式引入映射文件,但是必须满足两个条件: 1、mapper接口和映射文件所在的包必须一致 2、mapper接口的名字和映射文件的名字必须一致 --> <package name="com.mybatis.mapper"/> </mappers>
resources目录下新建文件com/mybatis/mapper
【图】
18 在idea中能够创建mybatis核心配置文件和映射文件的模板
mybatis-config
<?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核心配置文件中的标签必须要按照指定的顺序配置 properties?,settings?,typeAliases?,typeHandlers?, objectFactory?,objectWrapperFactory?,reflectorFactory?, plugins?,environments?,databaseIdProvider?,mappers? --> <properties resource="jdbc.properties"></properties> <typeAliases> <package name=""/> </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=""/> </mappers> </configuration>
mybatis-mapper
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <mapper namespace=""> </mapper>
Settings
19 使用模板搭建Mybatis框架
1、导入log4j.xml
jdbc.properties
2、mybatis-config.xml(模板)
3、接口
4、对应的映射文件
Mybatis获取参数值
20 两种方式
MyBatis获取参数值的两种方式:${}和#{}
${}的本质就是字符串拼接,#{}的本质就是占位符赋值
${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单 引 号;
但是#{}使用占位符赋值的方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时, 可以自 动添加单引号
21 情况(1)
单个字面量类型的参数
若mapper接口中的方法参数为单个的字面量类型
此时可以使用${}和#{}以任意的名称获取参数的值,注意${}需要手动加单引号
Mybatis 3.5
UserMapper.java
User getUserByUsername(String username);
UserMapper.xml
<!--User getUserByUsername(String username); --> <select id="getUserByUsername" resultType="com.atguigu.mybatis.pogo.User"> select * from t_user where username =#{username} <!-- '${username}' --> </select>
ParameterTest.java
@Test public void testGetUserByUsername(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.getUserByUsername("admin"); System.out.println(user); }
22 情况(2)
多个字面量类型的参数
若mapper接口中的方法参数为多个时 此时MyBatis会自动将这些参数放在一个map集合中,以arg0,arg1...为键,以参数为值;
以 param1,param2...为键,以参数为值;
因此只需要通过${}和#{}访问map集合的键就可以获取相 对应的 值,注意${}需要手动加单引号
UserMapper.java
/*验证登录*/ User checkLogin(String username,String password);
UserMapper.xml
<!--User checkLogin(String username,String password);--> <select id="checkLogin" resultType="com.atguigu.mybatis.pogo.User"> select *from t_user where username= #{param1} and password= #{param2} /*select *from t_user where username= '${arg0}' and password= '${arg1}'*/ </select>
ParameterTest.java
@Test public void testCheckLogin(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.checkLogin("admin", "123456"); System.out.println(user); }
23 情况(3)
map集合类型的参数
若mapper接口中的方法需要的参数为多个时,此时可以手动创建map集合,将这些数据放在 map中 只需要通过${}和#{}访问map集合的键就可以获取相对应的值,注意${}需要手动加单引号
UserMapper.java
/*验证登录(以map集合作为参数)*/ User checkLoginByMap(Map<String,Object> map);
UserMapper.xml
<!--User checkLoginByMap(Map<String,Object> map);--> <select id="checkLoginByMap" resultType="com.atguigu.mybatis.pogo.User"> select * from t_user where username=#{username} and password = #{password} </select>
ParameterTest.java
@Test public void testCheckLoginByMap(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); Map<String ,Object> map=new HashMap<String, Object>(); map.put("username","admin"); map.put("password","123456"); User user = mapper.checkLoginByMap(map); System.out.println(user); }
24 情况(4)
实体类类型的参数
若mapper接口中的方法参数为实体类对象时 此时可以使用${}和#{},通过访问实体类对象中的属性名获取属性值,注意${}需要手动加单引号
UserMapper.java
/*添加用户信息*/ void insertUser(User user);
UserMapper.xml
<!--void insertUser(User user);--> <insert id="insertUser"> insert into t_user values (null,#{username},#{password},#{age},#{gender},#{email}) </insert>
ParameterTest.java
@Test public void testInsertUser() { SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User(null, "root", "123456", 33, "女", "123@qq.com"); mapper.insertUser(user); }
25 情况(5)
使用@Param标识参数
可以通过@Param注解标识mapper接口中的方法参数
此时,会将这些参数放在map集合中,以@Param注解的value属性值为键,以参数为值;
以 param1,param2...为键,以参数为值;
只需要通过${}和#{}访问map集合的键就可以获取相对应 的值,
注意${}需要手动加单引号
UserMapper.java
/*验证登录(使用Param)*/ User checkLoginByParam(@Param("username") String username,@Param("password") String password);
UserMapper.xml
<!--User checkLoginByParam(@Param("username") String username,@Param("password") String password);--> <select id="checkLoginByParam" resultType="com.atguigu.mybatis.pogo.User"> select *from t_user where username=#{username} and password=#{password} </select>
ParameterTest.java
@Test public void testCheckLoginByParam(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.checkLoginByParam("admin", "123456"); System.out.println(user); }
Mybatis的各种查询功能
26 功能(1)
若sql语句查询结果为多条时,一定不能以实体类类型作为方法的返回值
否则会抛出异常TooManyResultsException
若sql语句查询的结果为1条时,此时可以使用实体类类型或list集合类型作为方法的返回值
SelectMapper.java
public interface SelectMapper { User getUserById(@Param("id") Integer id); List<User> getAllUser(); }
SelectMapper.xml
<!--User getUserById(@Param("id") int id);--> <select id="getUserById" resultType="com.atguigu.mybatis.pogo.User"> select * from t_user where id=#{id} </select> <!--List<User> getAllUser();--> <select id="getAllUser" resultType="com.atguigu.mybatis.pogo.User"> select * from t_user </select>
SelectMapperTest.java
@Test public void testGetUserById(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); User user = mapper.getUserById(1); System.out.println(user); } /*@Test public void testGetAllUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); List<User> list = mapper.getAllUser(); list.forEach(System.out); }*/ @Test public void testGetAllUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); List<User> list = mapper.getAllUser(); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } }
27 功能(2)
SelectMapper.java
/*查询用户的总数量*/ Integer getCount();
SelectMapper.xml
<!--Integer getCount();--> <select id="getCount" resultType="java.lang.Integer"> select count(*) from t_user </select>
SelectMapperTest.java
@Test public void testGetCount(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); Integer count = mapper.getCount(); System.out.println(count); }
28 功能(3)
SelectMapper.java
/*根据id查询用户信息为map集合*/ Map<String,Object> getUserByIdToMap(@Param("id") Integer id);
SelectMapper.xml
<!--Map<String,Object> getUserByIdToMap(@Param("id") Integer id);--> <select id="getUserByIdToMap" resultType="map"> select * from t_user where id= #{id} </select>
SelectMapperTest.java
@Test public void testGetUserByIdToMap(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); Map<String, Object> map = mapper.getUserByIdToMap(1); //{password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin} //数据为null则不会被放到map集合中 //{password=123, gender=男, id=2, age=19} System.out.println(map); }
29 功能(4)
/* * 若数据有多条时,并且要将每条数据转换为Map集合 * 此时有两种解决方案: * 1、将mapper接口方法的返回值设置为泛型是map的list集合 * List<Map<String,Object> >getAllUserToMap(); *结果:{password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin}, {password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root} *2、 * 可以将每条数据转换的map集合放在一个大的map中,但是必须通过@MapKey注解 * 将查询的某个字段作为大的map键 @MapKey("id") Map<String,Object> getAllUserToMap(); 结果: * */ /*{1={password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin}, 2={password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}} */
List常用
SelectMapper.java
List<Map<String,Object> >getAllUserToMap();
SelectMapper.xml
<!--List<Map<String,Object> >getAllUserToMap();--> <select id="getAllUserToMap" resultType="map"> select *from t_user </select>
SelectMapperTest.java
public void testGetAllUserToMap(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); /*Map<String, Object> map = mapper.getAllUserToMap(); System.out.println(map);*/ /*{1={password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin}, 2={password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}} */ List<Map<String, Object>> list = mapper.getAllUserToMap(); System.out.println(list); /*[{password=123456, gender=男, id=1, age=23, email=123546@qq.com, username=admin}, {password=123456, gender=女, id=2, age=33, email=123@qq.com, username=root}]*/ }
Map
SelectMapper.java
/*查询所有用户信息为map集合*/ @MapKey("id") Map<String,Object> getAllUserToMap();
SelectMapper.xml
<!--List<Map<String,Object> >getAllUserToMap();--> <select id="getAllUserToMap" resultType="map"> select *from t_user </select>
SelectMapperTest.java
public void testGetAllUserToMap(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SelectMapper mapper = sqlSession.getMapper(SelectMapper.class); Map<String, Object> map = mapper.getAllUserToMap(); System.out.println(map); }
特殊SQL的执行
30 处理模糊查询(1)
SpecialSQLMapper.java
/** * 测试模糊查询 * 通过用户名模糊查询用户信息 * * @param mohu * @return * */ //List<User> getUserByLike(@Param("mohu") String mohu); List<User> getUserByLike(@Param("mohu") String mohu);
SpecialSQLMapper.xml
<!--List<User> getUserByLike(@Param("mohu") String mohu);--> <select id="getUserByLike" resultType="User"> <!--select * from t_user where username like '%${mohu}%'--> <!--select * from t_user where username like concat('%',#{mohu},'%')--> select * from t_user where username like "%"#{mohu}"%" </select>
SpecialSQLMapper.java
@Test public void testgetUserByLike(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class); List<User> list = mapper.getUserByLike("a"); //list.forEach(System.out::println); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } }
31 处理模糊查询(2)
<!--List<User> testMohu(@Param("mohu") String mohu);--> <select id="testMohu" resultType="User"> <!--select * from t_user where username like '%${mohu}%'--> <!--select * from t_user where username like concat('%',#{mohu},'%')--> select * from t_user where username like "%"#{mohu}"%" </select>
32 Mybatis批量处理删除
注意:xml中要使用${ids}
#{ids}不行
SpecialSQLMapper.java
/*批量删除*/ void deleteMoreUser(@Param("ids") String ids);
SpecialSQLMapper.xml
<!--void deleteMoreUser(@Param("ids") String ids);--> <delete id="deleteMoreUser"> delete from t_user where id in(${ids}) </delete>
SpecialSQLMapper.java
@Test public void testDeleteMoreUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class); mapper.deleteMoreUser("7,8"); }
33 Mybatis处理动态设置表名
注意:${tableName}
SpecialSQLMapper.java
/*处理动态设置表名*/ List<User> getUserList(@Param("tableName") String tableName);
SpecialSQLMapper.xml
<!--List<User> getUserList(@Param("tableName") String tableName);--> <select id="getUserList" resultType="user"> select * from ${tableName} </select>
SpecialSQLMapper.java
@Test public void testGetUserList(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class); List<User> list = mapper.getUserList("t_user"); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } }
34 Mybatis获取自增的主键
SpecialSQLMapper.java
/*添加用户信息并获取自增的主键*/ void insertUser(User user);
SpecialSQLMapper.xml
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id"> insert into t_user VALUES (null,#{username},#{password},#{age},#{gender},#{email}) </insert>
SpecialSQLMapper.java
@Test public void testInsertUser(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); SpecialSQLMapper mapper = sqlSession.getMapper(SpecialSQLMapper.class); User user=new User(null,"xiaoming","123456",10,"女","123456@qq.com"); mapper.insertUser(user); System.out.println(user); }
public void testJDBC(){ try { Class.forName(""); Connection connection= DriverManager.getConnection("","",""); String sql="insert into t_user values()"; PreparedStatement ps=connection.prepareStatement(sql,Statement.RETURN_GENERATED_KEYS); ps.executeUpdate(); ResultSet resultSet = ps.getGeneratedKeys(); resultSet.next(); int id=resultSet.getInt(1); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); } }
自定义映射ResultMap
35 搭建Mybatis框架
若字段名和实体类中的属性名不一致,则可以通过resultMap设置自定义映射
ResultMap:设置自定义映射 属性: id:设置自定义映射的唯一标识 type:查询的数据要映射的实体类的类型 子标签: id:表示主键的映射关系 result:设置普通字段的映射关系 association:设置多对一的映射关系 collection:设置一对多的映射关系
36 使用全局配置处理字段和属性名不一致的情况
EmpMapper.java
/*根据id查询员工信息*/ Emp getEmpByEmpId(@Param("empId") Integer empId);
EmpMapper.xml
<!--Emp getEmpByEmpId(@Param("empId") Integer empId);--> <select id="getEmpByEmpId" resultType="com.atguigu.mybatis.pogo.Emp"> select * from t_emp where emp_id=#{empId} </select>
ResultMapTest.java
@Test public void testGetEmpByEmpId(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.getEmpByEmpId(1); System.out.println(emp); }
37 使用resultType处理字段名和属性名不一致的情况
ResultMap:设置自定义映射 属性: id:设置自定义映射的唯一标识//唯一标识 type:查询的数据要映射的实体类的类型//处理映射关系的实体类类型 子标签: id:表示主键的映射关系//处理主键和实体类中属性的映射关系 result:设置普通字段的映射关系//处理普通字段和实体类中属性的映射关系 column:设置映射关系中的字段名,必须是sql查询出的某个字段 property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名 association:设置多对一的映射关系 collection:设置一对多的映射关系
EmpMapper.java
/*根据id查询员工信息*/ Emp getEmpByEmpId(@Param("empId") Integer empId);
EmpMapper.xml
<resultMap id="empResultMap" type="com.atguigu.mybatis.pogo.Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="gender" property="gender"></result> </resultMap> <select id="getEmpByEmpId" resultMap="empResultMap" > select * from t_emp where emp_id=#{empId} </select>
ResultMapTest.java
@Test public void testGetEmpByEmpId(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.getEmpByEmpId(1); System.out.println(emp); }
38 处理多对一映射关系功能分析
EmpMapper.java
/*获取员工及所对应的部门信息*/ Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);
EmpMapper.xml
<!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);--> <select id="getEmpAndDeptByEmpId" resultType="com.atguigu.mybatis.pogo.Emp"> select t_emp.*,t_dept.* from t_emp left join t_dept on t_emp.dept_id=t_dept.dept_id where t_emp.emp_id=#{empId} </select>
ResultMapTest.java
@Test public void testGetEmpAndDeptByEmpId(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); EmpMapper mapper = sqlSession.getMapper(EmpMapper.class); Emp emp = mapper.getEmpAndDeptByEmpId(1); System.out.println(emp); }
39-44(4)
39 使用级联处理多对一的映射关系
property="dept.deptName"爆红,但是可以运行
EmpMapper.xml
<resultMap id="empAndDeptResultMap" type="com.atguigu.mybatis.pogo.Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="gender" property="gender"></result> <result column="dept_id" property="dept.deptId"></result> <result column="dept_name" property="dept.deptName"></result> </resultMap> <!--Emp getEmpAndDeptByEmpId(@Param("empId") Integer empId);--> <select id="getEmpAndDeptByEmpId" resultMap="empAndDeptResultMap"> select t_emp.*,t_dept.* from t_emp left join t_dept on t_emp.dept_id=t_dept.dept_id where t_emp.emp_id=#{empId} </select>
40 使用association处理多对一的映射关系
比上一种好用,层次更加清晰
EmpMapper.xml
<!-- association:处理多对一的映射关系(处理实体类类型的属性) property:设置需要处理映射关系的属性和属性名 javaType:设置要处理的属性的类型 --> <resultMap id="empAndDeptResultMap" type="com.atguigu.mybatis.pogo.Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="gender" property="gender"></result> <association property="dept" javaType="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> </association> </resultMap>
41 使用分布查询处理多对一的映射关系
EmpMapper.xml
<resultMap id="empAndDeptByStepResultMap" type="com.atguigu.mybatis.pogo.Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="age" property="age"></result> <result column="gender" property="gender"></result> <association property="dept" select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptBySteptTwo" column="dept_id"> </association> </resultMap> <!--Emp getEmpAndDeptByStep(@Param("empId") Integer empId);--> <select id="getEmpAndDeptByStep" resultMap="empAndDeptByStepResultMap"> select * from t_emp where emp_id =#{empId} </select>
42 延迟加载
mubatis-config.xml
<settings> <!--将下划线映射为驼峰--> <setting name="mapUnderscoreToCamelCase" value="true"/> <!--开启延迟加载--> <setting name="lazyLoadingEnabled" value="true"/> <!--按需加载--> </settings>
EmpMapper.xml
<!-- fetchType:在开启了延迟加载的环境中,通过该属性设置当前的分步查询是否使用延迟加载 fetchType="lazy" 延迟加载 fetchType="eager" 立即加载 --> <association property="dept" fetchType="lazy" select="com.atguigu.mybatis.mapper.DeptMapper.getEmpAndDeptBySteptTwo" column="dept_id"> </association>
43 通过collection处理多对一的映射关系
常用:
resultMap:设置自定义的映射关系 id:唯一标识 type:处理映射关系的实体类的类型 常用的标签: id:处理主键和实体类中属性的映射关系 association:处理多对一的映射关系(处理实体类类型的属性) result:处理普通字段和实体类中属性的映射关系 collection:处理一对多的映射关系(处理集合类型的属性) column:设置映射关系中的字段名,必须是sql查询出的某个字段 property:设置映射关系中的属性的属性名,必须是处理的实体类类型中的属性名
ofType="com.atguigu.mybatis.pogo.Emp"
<collection property="emps" ofType="com.atguigu.mybatis.pogo.Emp">
EmpMapper.xml
<resultMap id="deptAndEmpResultMap" type="com.atguigu.mybatis.pogo.Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> <collection property="emps" ofType="com.atguigu.mybatis.pogo.Emp"> <id column="emp_id" property="empId"></id> <id column="emp_name" property="empName"></id> <id column="age" property="age"></id> <id column="gender" property="gender"></id> </collection> </resultMap> <!--Dept getDeptAndEmpByDeptId(@Param("deptId") Integer deptId);--> <select id="getDeptAndEmpByDeptId" resultMap="deptAndEmpResultMap"> select * from t_dept left join t_emp on t_dept.dept_id=t_emp.dept_id where t_dept.dept_id=#{deptId} </select>
44通过分布查询处理多对一的映射关系
EmpMapper.xml
<resultMap id="deptAndEmpResultMapByStep" type="com.atguigu.mybatis.pogo.Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> <collection property="emps" select="com.atguigu.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo" column="dept_id"></collection> </resultMap> <!--Dept getDeptAndEmpByStepOne(@Param("deptId") Integer deptId);--> <select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMapByStep"> select * from t_dept where dept_id=#{deptId} </select>
动态SQL
45-51(3)
Mybatis动态标签
45 动态SQL简介
Myabtis框架的动态SQL技术是一种根据特定条件动态拼装SQl语句的功能,它存在的意义是为了解决拼接SQL语句字符串时的痛点问题
if:通过test属性中的表达式判断标签中的内容是否有效(是否会拼接到sql中) where: a.若where标签中有条件成立,会自动生成where关键字 b.会自动将where标签中内容前多余的and去掉 c.若where标签中没有任何一个条件成立,则where没有任何功能 trim: prefix
46 if标签
if标签可通过test属性的表达式进行判断,若表达式的结果为true,则标签中的内容会执行; 反之 标签中的内容不会执行
DynamicSQLMapper.java
/*根据条件查询员工信息*/ List<Emp> getEmpByCondition(Emp emp);
DynamicSQLMapper.xml
<!--List<Emp> getEmpByCondition(Emp emp);--> <select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp"> select * from t_emp where <if test="empName!=null and empName!=''"> emp_name=#{empName} </if> <if test="age !=null and age !=''"> and age = #{age} </if> <if test="gender !=null and gender !=''"> and gender = #{gender} </if> </select>
DynamicMapperTest.java
@Test public void DynamicMapperTest(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class); Emp emp=new Emp(null,"张三",21,"男"); List<Emp> list = mapper.getEmpByCondition(emp); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } }
47 where标签
where和if一般结合使用: a>若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字 b>若where标签中的if条件满足,则where标签会自动添加where关键字,并将条件最前方多余的 and去掉 ,但是内容后的and去不掉 注意:where标签不能去掉条件最后多余的and
第一种方法
where 1=1
DynamicSQLMapper.xml
<!--List<Emp> getEmpByCondition(Emp emp);--> <select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp"> select * from t_emp where 1=1 <if test="empName!=null and empName!=''"> and emp_name=#{empName} </if> <if test="age !=null and age !=''"> and age = #{age} </if> <if test="gender !=null and gender !=''"> and gender = #{gender} </if> </select>
第二种方法
DynamicSQLMapper.java
/*根据条件查询员工信息*/ List<Emp> getEmpByCondition(Emp emp);
DynamicSQLMapper.xml(只改变了这部分)
<select id="getEmpByCondition" resultType="com.atguigu.mybatis.pojo.Emp"> select * from t_emp <where> <if test="empName!=null and empName!=''"> emp_name=#{empName} </if> <if test="age !=null and age !=''"> and age = #{age} </if> <if test="gender !=null and gender !=''"> and gender = #{gender} </if> </where> </select>
DynamicMapperTest.java
@Test public void DynamicMapperTest(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class); Emp emp=new Emp(null,"",null,""); List<Emp> list = mapper.getEmpByCondition(emp); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } }
48 trim标签
trim用于去掉或添加标签中的内容 常用属性: prefix:在trim标签中的内容的前面添加某些内容 prefixOverrides:在trim标签中的内容的前面去掉某些内容 suffix:在trim标签中的内容的后面添加某些内容 suffixOverrides:在trim标签中的内容的后面去掉某些内容
DynamicSQLMapper.java
DynamicSQLMapper.xml
DynamicMapperTest.java
49 choose、when标签 otherwise
choose、when,otherwise
相当于
if,else if,else
DynamicSQLMapper.java
/*使用choose查询员工信息*/ List<Emp> getEmpByChoose(Emp emp);
DynamicSQLMapper.xml
<!--List<Emp> getEmpByChoose(Emp emp);--> <select id="getEmpByChoose" resultType="com.atguigu.mybatis.pojo.Emp"> select * from t_emp <where> <choose> <when test="empName != null and empName !=''"> emp_name=#{empName} </when> </choose> <choose> <when test="age != null and age!=''"> age=#{age} </when> </choose> <choose> <when test="gender != null and gender!=''"> gender=#{gender} </when> </choose> </where> </select>
DynamicMapperTest.java
@Test public void getEmpMapperTest(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class); Emp emp=new Emp(null,"",null,""); List<Emp> list = mapper.getEmpByChoose(emp); for(int i=0;i<list.size();i++){ System.out.println(list.get(i)); } }
50 foreach标签(重要)批量添加
collection:设置要循环的数组或集合 item:用一个字符串表示数组或集合中的每一个数据 separator:设置每次循环的数据之间的分隔符 open:循环的所有内容以什么开始 close:循环的所有内容以什么结束
DynamicSQLMapper.java
/*批量添加员工信息*/ void insertMoreEmp(@Param("emps") List<Emp> emps);
DynamicSQLMapper.xml
<!--void insertMoreEmp(List<Emp> emps);--> <insert id="insertMoreEmp"> insert into t_emp values /*separator:分隔符*/ <foreach collection="emps" item="emp" separator=","> (null,#{emp.empName},#{emp.age},#{emp.gender},null) </foreach> </insert>
DynamicMapperTest.java
@Test public void getInsertMoreEmp(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class); Emp emp1=new Emp(null,"小明1",20,"男"); Emp emp2=new Emp(null,"小明2",20,"男"); Emp emp3=new Emp(null,"小明3",20,"男"); List<Emp> list = Arrays.asList(emp1, emp2, emp3); mapper.insertMoreEmp(list); }
51 foreach标签 批量删除
DynamicSQLMapper.java
/*批量删除*/ void deleteMoreEmp(@Param("empIds") Integer[] empIds);
DynamicSQLMapper.xml
<!--void deleteMoreEmp(@Param("empIds") Integer[] empIds);--> <delete id="deleteMoreEmp"> delete from t_emp where emp_id in ( <foreach collection="empIds" item="empId" separator=","> #{empId} </foreach> ) </delete>
DynamicMapperTest.java
@Test public void getDeleteMoreEmp(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class); Integer[] empIds=new Integer[]{6,7}; mapper.deleteMoreEmp(empIds); }
第一种
DynamicSQLMapper.xml
<delete id="deleteMoreEmp"> delete from t_emp where emp_id in ( <foreach collection="empIds" item="empId" separator=","> #{empId} </foreach> ) </delete>
第二种
open="(" close=")"
DynamicSQLMapper.xml
<delete id="deleteMoreEmp"> delete from t_emp where emp_id in <foreach collection="empIds" item="empId" separator="," open="(" close=")"> #{empId} </foreach> </delete>
第三种
DynamicSQLMapper.xml
delete from t_emp where <foreach collection="empIds" item="empId" separator="or"> emp_id=#{empId} </foreach>
52-58(2)
52 Mybatis动态SQL之sql标签
sql片段: 可以记录一段sql,在需要用的地方使用include标签进行引用
DynamicSQLMapper.xml
<sql id="empColumns"> emp_id,emp_name,age,gender,dept_id </sql> <include refid="empColumns"></include>
Mybatis的缓存
53 Mybatis的一级缓存
一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就 会从缓存中直接获取,不会从数据库重新访问
/* 一级缓存测试 *两次查询只执行了一次sql * */ @Test public void testGetEmpByIdtest1(){ SqlSession sqlSession = SqlSessionUtil.getSqlSession(); CacheMapper mapper = sqlSession.getMapper(CacheMapper.class); Emp emp1 = mapper.getEmpById(1); System.out.println(emp1); Emp emp2 = mapper.getEmpById(1); System.out.println(emp2); }
54 使一级缓存失效的四种情况
使一级缓存失效的四种情况:
-
不同的SqlSession对应不同的一级缓存
-
同一个SqlSession但是查询条件不同
-
同一个SqlSession两次查询期间执行了任何一次增删改操作
-
同一个SqlSession两次查询期间手动清空了缓存
清空一级缓存: sqlSession.clearCache();
55 Mybatis的二级缓存
二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果会被 缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
/* 二级缓存 */ @Test public void testCache() throws IOException { InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(is); SqlSession sqlSession = sqlSessionFactory.openSession(true); CacheMapper mapper = sqlSession.getMapper(CacheMapper.class); Emp emp =mapper.getEmpById(1); System.out.println(emp); sqlSession.close(); SqlSession sqlSession1 = sqlSessionFactory.openSession(true); CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class); Emp emp1 =mapper1.getEmpById(1); System.out.println(emp1); sqlSession1.close(); }
二级缓存开启的条件:
a>在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
b>在映射文件中设置标签
c>二级缓存必须在SqlSession关闭或提交之后有效
d>查询的数据所转换的实体类类型必须实现序列化的接口
public class Emp implements Serializable { }
使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
56 Mybatis二级缓存相关的配置和缓存
在mapper配置文件中添加的cache标签可以设置一些属性:
①eviction属性:缓存回收策略,默认的是 LRU。
LRU(Least Recently Used) – 最近最少使用的:移除最长时间不被使用的对象。
FIFO(First in First out) – 先进先出:按对象进入缓存的顺序来移除它们。
SOFT – 软引用:移除基于垃圾回收器状态和软引用规则的对象。
WEAK – 弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。
②flushInterval属性:刷新间隔,单位毫秒
默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新
③size属性:引用数目,正整数
代表缓存最多可以存储多少个对象,太大容易导致内存溢出
④readOnly属性:只读, true/false
true:只读缓存;会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了 很重 要的性能优势。
false:读写缓存;会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是 false。
Mybatis缓存的查询顺序
先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
如果二级缓存没有命中,再查询一级缓存
如果一级缓存也没有命中,则查询数据库
SqlSession关闭之后,一级缓存中的数据会写入二级缓存
57 Mybatis整合第三方缓存
针对二级缓存(了解)
58 Mybatis逆向工程之清晰简洁版
正向工程:先创建Java实体类,由框架负责根据实体类生成数据库表。 Hibernate是支持正向工 程的。
逆向工程:先创建数据库表,由框架负责根据数据库表,反向生成如下资源:
Java实体类 Mapper接口 Mapper映射文件
59 Mybatis逆向工程之奢华尊享版
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration> <!-- targetRuntime: 执行生成的逆向工程的版本 MyBatis3Simple: 生成基本的CRUD(清新简洁版) MyBatis3: 生成带条件的CRUD(奢华尊享版) --> <context id="DB2Tables" targetRuntime="MyBatis3"> <!-- 数据库的连接信息 --> <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver" connectionURL="jdbc:mysql://localhost:3306/ssm?serverTimezone=UTC" userId="root" password="123456"> </jdbcConnection> <!-- javaBean的生成策略--> <javaModelGenerator targetPackage="com.atguigu.mybatis.pojo" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> <property name="trimStrings" value="true" /> </javaModelGenerator> <!-- SQL映射文件的生成策略 --> <sqlMapGenerator targetPackage="com.atguigu.mybatis.mapper" targetProject=".\src\main\resources"> <property name="enableSubPackages" value="true" /> </sqlMapGenerator> <!-- Mapper接口的生成策略 --> <javaClientGenerator type="XMLMAPPER" targetPackage="com.atguigu.mybatis.mapper" targetProject=".\src\main\java"> <property name="enableSubPackages" value="true" /> </javaClientGenerator> <!-- 逆向分析的表 --> <!-- tableName设置为*号,可以对应所有表,此时不写domainObjectName --> <!-- domainObjectName属性指定生成出来的实体类的类名 --> <table tableName="t_emp" domainObjectName="Emp"/> <table tableName="t_dept" domainObjectName="Dept"/> </context> </generatorConfiguration>
60 分页功能分析
limit index,pageSize pageSize:每页显示的条数 pageNum:当前页的页码 index:当前页的起始索引,index=(pageNum-1)*pageSize count:总记录数 totalPage:总页数 totalPage = count / pageSize; if(count % pageSize != 0){ totalPage += 1; } pageSize=4,pageNum=1,index=0 limit 0,4 pageSize=4,pageNum=3,index=8 limit 8,4 pageSize=4,pageNum=6,index=20 limit 8,4 首页 上一页 2 3 4 5 6 下一页 末页
61 分页插件的使用
添加依赖pom.xml
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>
配置分页插件
<plugins> <!--设置分页插件--> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
62 通过分页插件获取分页相关数据
a>在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能 pageNum:当前页的页码 pageSize:每页显示的条数 b>在查询获取list集合之后,使用PageInfo<T> pageInfo = new PageInfo<>(List<T> list, int navigatePages)获取分页相关数据 list:分页之后的数据 navigatePages:导航分页的页码数 c>分页相关数据 PageInfo{ pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8, list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30, pages=8, reasonable=false, pageSizeZero=false}, prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true, hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8, navigatepageNums=[4, 5, 6, 7, 8] } pageNum:当前页的页码 pageSize:每页显示的条数 size:当前页显示的真实条数 total:总记录数 pages:总页数 prePage:上一页的页码 nextPage:下一页的页码 isFirstPage/isLastPage:是否为第一页/最后一页 hasPreviousPage/hasNextPage:是否存在上一页/下一页 navigatePages:导航分页的页码数 navigatepageNums:导航分页的页码,[1,2,3,4,5]