MyBatis高级(逆向工程及MyBatis注解)
MyBatis高级(逆向工程及MyBatis注解)
一、使用MBG逆向工程生成代码
在企业中为了提高开发效率,有很多通用代码实际上是直接使用代码生成器生成出来的。
官方网址:
http://mybatis.org/generator/
使用步骤:
1、添加插件
<plugins>
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.3.2</version>
<configuration>
<verbose>true</verbose>
<overwrite>true</overwrite>
</configuration>
<dependencies>
<!--加入依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.25</version>
</dependency>
</dependencies>
</plugin>
</plugins>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
2、添加配置文件
配置好maven插件,下面需要配置插件需要天健的配置文件.
在maven项目下的src/main/resources 目录下建立名为maven的项目配置文件存放路径如下图:generatorConfig.xml 和 generator.properties 配置文件。
<generatorConfiguration>
<!--导入属性配置-->
<properties resource="generator.properties"></properties>
<!--指定特定数据库的jdbc驱动jar包的位置-->
<context id="default" targetRuntime="MyBatis3">
<!--optional,旨在创建class时,对注释进行控制-->
<commentGenerator>
<property name="suppressDate" value="true"/>
<property name="suppressAllComments" value="true"/>
</commentGenerator>
<!--jdbc的数据库连接-->
<jdbcConnection
driverClass="${driver}"
connectionURL="${url}"
userId="${username}"
password="${password}">
</jdbcConnection>
<!--非必须,类型处理器,在数据库类型和java类型之间的转换控制-->
<javaTypeResolver>
<property name="forceBigDecimals" value="false"/>
</javaTypeResolver>
<!--Model模型生成器,用来生成含有主键key的类,记录类以及查询Example类
targetPackage:指定生成的model生成所在的包名
targetProject:指定在该项目下所在的路径
-->
<javaModelGenerator targetPackage="com.acoffee.maven.pojo" targetProject="src/main/java">
<!--是否允许子包,即targetPackages,schemaName,tableName-->
<property name="enableSubPackages" value="true"/>
<!--是否对model添加构造函数-->
<property name="constructorBased" value="true"/>
<!--是否对类char类型的列的数据进行trim操作-->
<property name="trimStrings" value="true"/>
<!--建立的model对象是否 不可改变 即生成的Model对象不会有setter方法,只有构造方法-->
<property name="immytable" value="false"/>
</javaModelGenerator>
<!--Mapper映射文件生成所在目录为每一个数据库的表生成对应的SqlMap文件-->
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
<property name="enableSubPackages" value="false"/>
</sqlMapGenerator>
<!--客户端代码,生成易于使用的针对Model对象和XML配置文件的代码
type="ANNOTATEDMAPPER",生成Java Model和基于注解的Mapper对象
type="MIXEDMAPPER",生成基于注解的Java Model和Mapper对象
type="XMLMAPPER",生成SQLMap XML文件和独立的Mapper接口
-->
<javaClientGenerator type="XMLMAPPER" targetPackage="com.acoffee.maven.dao" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<table tableName="dept" domainObjectName="Dept"
enableCountByExample="false" enableUpdateByExample="false"
enableDeleteByExample="false" enableSelectByExample="false"
selectByExampleQueryId="false">
</table>
</context>
</generatorConfiguration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
3、Intellj配置
MyBatis Generator 生成代码的运行方式:命令行,使用Ant,使用Maven、Java编码、我们采用Maven插件mybatis-generator-maven-plugin来运行MyBatis Generator,用的是命令行的方式。
添加运行maven 的配置
执行结果:
将generatorConfig.xml配置文件中的table全部改为true:
<table tableName="dept" domainObjectName="Dept"
enableCountByExample="true" enableUpdateByExample="true"
enableDeleteByExample="true" enableSelectByExample="true"
selectByExampleQueryId="true">
</table>
1
2
3
4
5
执行结果:
里面包含一些条件查询的接口等等
测试文件:
public class AppTest {
@Test
public void shouldAnswerWithTrue() {
SqlSession sqlSession = MyBatisUtil.createSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
DeptExample deptExample = new DeptExample();
DeptExample.Criteria criteria = deptExample.createCriteria();
// criteria.andDeptnoEqualTo(10);//按部门编号查
criteria.andDnameLike("%e%");//模糊查询
List<Dept> deptList = deptMapper.selectByExample(deptExample);
for (Dept dept : deptList) {
System.out.println(dept);
}
MyBatisUtil.closeSession(sqlSession);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
执行结果:
其中还有很多功能:动态sql等等(这个组件算是比较古老的)。
二、MyBatis的注解
注解 功能
@Insert 实现新增
@Update 实现更新
@Delete 实现删除
@Select 实现查询
@Result 实现结果集封装
@Results 可以与@Result 一起使用,封装多个结果集
@ResultMap 实现引用
@Results 定义的封装
@One 实现一对一结果集封装
@Many 实现一对多结果集封装
@SelectProvider 实现动态 SQL 映射
@CacheNamespace 实现注解二级缓存的使用
1、MyBatis的基本注解
注解的方式没有映射文件
实体对象:
@Data
public class Dept {
private byte deptno;
private String dname;
private String loc;
private List<Emp> emps;
}
1
2
3
4
5
6
7
接口:
@Mapper
public interface DeptMapper {
@Insert("insert into dept(dname,loc)values(#{dname},#{loc})")
public void add(Dept dept);
@Delete("delete from dept where deptno=#{deptno}")
public void delete(byte deptno);
@Update("update dept set dname=#{dname},loc=#{loc} where deptno=#{deptno}")
public void update(Dept dept);
@Select("select * from dept where dept=#{dept}")
public Dept selectOne(byte deptno);
@Select("select * from dept")
public List<Dept> selectAll();
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
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>
<settings>
<setting name="logImpl" value="LOG4J"/>
<!--lazyLoadingEnabled是设置值开启延迟加载的,默认是false
表示没有开启延迟加载,这里设置true表示开启延迟加载
-->
<setting name="lazyLoadingEnabled" value="true"></setting>
<!--设置不按需加载,默认按需加载-->
<!--<setting name="aggressiveLazyLoading" value="true"></setting>-->
</settings>
<typeAliases>
<package name="com.acoffee.maven.pojo"></package>
</typeAliases>
<!--evironment表示mybatis的运行环境,这里mybatis可以定义多个环境-->
<environments default="mysql"><!--如果我们想要oracle运行我们这里改成oralce-->
<environment id="mysql">
<!--transactionManager表示事务管理器-->
<transactionManager type="JDBC"></transactionManager>
<!--DataSource表示数据源,type
pooled:使用连接池的数据源
unpooled:不使用连接池的数据源
JNDI:使用JNDI实现的数据源
-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
<property name="url" value="jdbc:mysql://localhost:3306/mydb?useUnicode=true&characterEncoding=UTF-8"/>
<property name="username" value="root"></property>
<property name="password" value="7777"></property>
</dataSource>
</environment>
</environments>
<!--接口路径-->
<mappers>
<mapper class="com.acoffee.maven.mapper.DeptMapper"></mapper>
</mappers>
</configuration>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
测试文件:
查询全部
public class AppTest {
private Logger logger = Logger.getLogger(this.getClass());
@Test
public void testList(){
SqlSession sqlSession = MyBatisUtil.createSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> deptList = deptMapper.selectAll();
for (Dept dept:deptList) {
logger.info(dept);
}
MyBatisUtil.closeSession(sqlSession);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
执行结果:
添加
@Test
public void testAdd(){
SqlSession sqlSession = MyBatisUtil.createSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = new Dept();
dept.setDeptno((byte)50);
dept.setDname("研发部");
dept.setLoc("成都市");
deptMapper.add(dept);
sqlSession.commit();
MyBatisUtil.closeSession(sqlSession);
}
1
2
3
4
5
6
7
8
9
10
11
12
执行结果:
2、MyBatis关联注解
一对多
“一对多” 多的一方写@Many
实体对象:
Dept 类:
@Data
public class Dept {
private byte deptno;
private String dname;
private String loc;
private List<Emp> emps;
}
1
2
3
4
5
6
7
Emp类
@Data
public class Emp {
private short empno;
private String ename;
private String job;
private short mgr;
private Date hiredate;
private double sal;
private double comm;
}
1
2
3
4
5
6
7
8
9
10
11
接口:
DeptMapper
@Mapper
public interface DeptMapper {
@Results({
@Result(property = "deptno", column = "deptno"),
@Result(property = "dname", column = "dname"),
@Result(property = "loc", column = "loc"),
@Result(property = "emps", column = "deptno", many = @Many(select = "com.acoffee.maven.mapper.EmpMapper.slectEmpsByDeptno", fetchType = FetchType.EAGER))
})
@Select("select * from dept where deptno=#{deptno}")
public Dept selectOne(byte deptno);
}
1
2
3
4
5
6
7
8
9
10
11
EmpMapper
@Mapper
public interface EmpMapper {
@Select("select * from emp where deptno=#{deptno}")
public List<Emp> slectEmpsByDeptno(byte deptno);
}
1
2
3
4
5
6
测试文件:
@Test
public void testOneToMany() {
SqlSession sqlSession = MyBatisUtil.createSession();
DeptMapper deptMapper = sqlSession.getMapper(DeptMapper.class);
Dept dept = deptMapper.selectOne((byte) 10);
logger.info(dept);
MyBatisUtil.closeSession(sqlSession);
}
1
2
3
4
5
6
7
8
执行结果:
多对一
“多对一” 一的一方写@One
实体对象
Dept 类:
@Data
public class Dept {
private byte deptno;
private String dname;
private String loc;
private List<Emp> emps;
}
1
2
3
4
5
6
7
Emp 类:
@Data
public class Emp {
private short empno;
private String ename;
private String job;
private short mgr;
private Date hiredate;
private double sal;
private double comm;
private Dept depts;
}
1
2
3
4
5
6
7
8
9
10
11
12
接口:
EmpMapper
@Mapper
public interface EmpMapper {
@Results({
@Result(property = "empno",column = "empno"),
@Result(property = "ename",column = "ename"),
@Result(property = "job",column = "job"),
@Result(property = "mgr",column = "mgr"),
@Result(property = "hiredate",column = "hiredate"),
@Result(property = "sal",column = "sal"),
@Result(property = "comm",column = "comm"),
@Result(property = "depts",column = "deptno", one = @One(select = "com.acoffee.maven.mapper.DeptMapper.selectDeptByDeptnoWithStep",fetchType = FetchType.LAZY))
})
@Select("select * from emp where empno=#{empno}")
public Emp selectEmpByEmpno(Short empno);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
@Mapper
public interface DeptMapper {
@Select("select * from dept where deptno=#{deptno}")
public Dept selectDeptByDeptnoWithStep(@Param("deptno")byte deptno);
}
1
2
3
4
5
测试文件:
@Test
public void testManyToOne() {
SqlSession sqlSession = MyBatisUtil.createSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp empno = empMapper.selectEmpByEmpno((short) 7369);
logger.info(empno);
MyBatisUtil.closeSession(sqlSession);
}
1
2
3
4
5
6
7
8
执行结果:
我们这里emps返回的null,如果我们想它继续返回部门的员工信息,可以直接将selectDeptByDeptnoWithStep改成一对多种的selectone的形式即可。
三、MyBatis动态SQL和缓存注解
MyBatis动态SQL
使用 @SelectProvider 注解,type 参数是提供构建 SQL 的类,method 是构建 SQL 的方法。
接口:
@Mapper
public interface EmpMapper {
@SelectProvider(type = EmpDynamicSqlProvider.class,method = "select")
public List<Emp> selectEmpsByMap( String ename, Double sal);
}
1
2
3
4
5
EmpDynamicSqlProvider 方法:
public class EmpDynamicSqlProvider {
public String select(final String ename, final Double sal) {
String result = new SQL() {
{
SELECT("*");
FROM("emp");
StringBuilder sb = new StringBuilder();
if (ename != null && !"".equals(ename)) {
sb.append("AND ename Like");
sb.append("'%");
sb.append(ename);
sb.append("%'");
}
if (sal != null && sal != 0.0) {
sb.append("AND sal>");
sb.append(sal);
}
if (!"".equals(sb.toString())) {
WHERE(sb.toString().replaceFirst("AND", ""));
}
}
}.toString();
return result;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
测试代码:
@Test
public void testDynamic() {
SqlSession sqlSession = MyBatisUtil.createSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> emps = empMapper.selectEmpsByMap("s", 0.0);
for (Emp emp : emps) {
logger.info(emp);
}
MyBatisUtil.closeSession(sqlSession);
}
1
2
3
4
5
6
7
8
9
10
11
12
执行结果:
缓存注解
接口
@Mapper
@CacheNamespace//缓存配置
public interface EmpMapper {
.....
1
2
3
4
当然如果我们想去改变缓存的一些参数可以直接在@CacheNamespace后面写即可,不设置就全是默认设置。
@CacheNamespace(eviction=LruCache.class flushInterval=60000 readOnly=true size=512)
1
序列化
@Data
public class Dept implements Serializable {
.....
1
2
3
@Data
public class Emp implements Serializable {
......
1
2
3
由于我们是关联查询所以连个都需要序列化。
测试代码:
@Test
public void testCache() {
SqlSession sqlSession = MyBatisUtil.createSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
Emp emp = empMapper.selectEmpByEmpno((short) 7369);
logger.info(emp);
MyBatisUtil.closeSession(sqlSession);
SqlSession sqlSession2 = MyBatisUtil.createSession();
EmpMapper empMapper2 = sqlSession2.getMapper(EmpMapper.class);
Emp emp1 = empMapper2.selectEmpByEmpno((short) 7369);
logger.info(emp1);
MyBatisUtil.closeSession(sqlSession2);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
————————————————
版权声明:本文为CSDN博主「vid。」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/weixin_44742328/article/details/115823435