文章目录
一、课程目标
【掌握】MyBatis注解开发
【了解】MyBatis逆向工程
二、注解开发
2.1 概念
与servlet一样在最开始时为了框架的灵活性,使用的xml配置文件的方式进行框架的搭建,但是xml文件的书写任然很繁琐,为了简化开发针对于繁琐的配置推出了相对应的注解进行功能的替换,简化一些简单的配置操作,但是对于mybatis的核心配置文件建议不要使用注解进行配置,一般使用注解的都是mapper的配置文件,但是会降低灵活性,所以目前的开发都是将注解与配置组合使用
2.2 常用注解
2.2.1 @Param()参数注解
在mapper接口与xml配置时,接口中的方法名与对应的id匹配,但是参数一般使用一个参数,并且mybatis拥有类型解析器,会自动获取对应的参数数据(mapper接口参数列表的变量与xml中实际获取的变量名没有关联),是由对应的解析器进行解析获取,如果获取不到,也会在错误信息中提示可以使用的参数名列表,如果想传递多个不同类型的参数并指定传递的变量名,那么就必须使用@Param()参数注解
Parameter 'paraasdsad' not found. Available parameters are [asdasd, param1]
在使用@Param注解前如果没有找到会提示
Parameter 'asdsad' not found. Available parameters are [arg0, arg1, param1, param2]
在使用@Param注解在对应的接口中设置绑定的变量名时会将指定名加入参数列表
//根据id修改名字
//@Param参数绑定 为指定的参数 绑定一个名字 可以在对应的mapper.xml中直接使用名字获取对应的值
int updateAnameByAid(@Param("aname") String aname, @Param("aid") int aid);
Parameter 'asdsad' not found. Available parameters are [aname, aid, param1, param2]
2.2.2 @Select()查询注解
语法:@Select(value=“查询语句”)可以简写为@Select(“查询语句”)
等价于mapper.xml中的
如果没有设置参数与返回值类型,默认使用当前的方法参数与返回值作为使用
//查询所有数据
@Select("select * from author")
ArrayList<Author> selectAll();
//等价于
<select id="selectAll" resultType="com.yunhe.vo.Author">
select *
from author
</select>
//根据id查询
@Select("select * from author where aid= #{aid}")
Author selectByAid(@Param("aid") int aid);
2.2.3 @Insert()添加注解
语法:@Insert(value=“添加语句”)可以简写为@Insert(“添加语句”)
等价于mapper.xml中的
注意:在进行赋值时#{属性}是参数的属性 需要提供getter方法才能获取
如果没有设置参数,默认使用当前的方法参数作为使用
//添加
@Insert("insert into author (aname,aage,atel,aaddress)values(#{aname},#{aage},#{atel},#{aaddress})")
int insert(Author author);
2.2.4 @Update()修改注解
语法:@Update(value=“修改语句”)可以简写为@Update(“修改语句”)
等价于mapper.xml中的
如果没有设置参数,默认使用当前的方法参数作为使用
//根据id修改名字
@Update("update author set aname=#{aname} where aid = #{aid}")
int updateAnameByAid(@Param("aname") String aname, @Param("aid") int aid);
2.2.5 @Delete()删除注解
语法:@Delete(value=“删除语句”)可以简写为@Select(“删除语句”)
等价于mapper.xml中的
如果没有设置参数,默认使用当前的方法参数作为使用
//根据id删除
@Delete("delete from author where aid=#{aid}")
int delete(@Param("aid") int id);
2.2.6 动态sql注解
在对应的标签中使用{}将带有动态sql语句包裹并在语句前后使用进行标识
由于动态sql书写复杂,所以一般使用xml配置形式进行实现
数组批量删除
xml配置形式
<delete id="deleteByArray">
delete from author where aid in
<foreach item="i" collection="arr" open="(" close=")" separator=",">
#{i}
</foreach>
</delete>
注解形式
//动态sql批量删除
@Delete({"<script>delete from author where aid in\n" +
" <foreach item=\"i\" collection=\"arr\" open=\"(\" close=\")\" separator=\",\">\n" +
" #{i}\n" +
" </foreach></script>"})
int deleteByArray(@Param("arr") int [] arr);
集合批量注册
xml配置形式
<insert id="inserColleaction">
insert into author (aname,aage,atel,aaddress) values
<foreach collection="a" item="i" separator="," >
(#{i.aname},#{i.aage},#{i.atel},#{i.aaddress})
</foreach>
</insert>
注解形式
//动态sql批量注册
@Insert({"<script> insert into author (aname,aage,atel,aaddress) values\n" +
" <foreach collection=\"a\" item=\"i\" separator=\",\" >\n" +
" (#{i.aname},#{i.aage},#{i.atel},#{i.aaddress})\n" +
" </foreach></script>"})
int inserColleaction(@Param("a") ArrayList<Author> alist);
2.2.7 @Results()、@Result()、@resultMap()结果映射注解
@Results()
语法:@Results(id=“唯一标识”,value={result标签数组})
等价于mapper.xml中的
当返回结果字段与实体类字段不匹配时
@Result()
语法:@Result(id=“true/false是否为主键”,column=“数据库列”,property=“属性名”)
等价于mapper.xml中的与
@resultMap()
语法:@resultMap(value=“返回结果集映射id”)可以简写为@resultMap(“返回结果集映射id”)
等价于mapper.xml中的resultMap属性
查询所有数据
xml配置形式
<resultMap id="t_user" type="com.yunhe.vo.T_User">
<id property="id" column="uid"/>
<result property="username" column="uusername"/>
<result property="password" column="upassword"/>
</resultMap>
<select id="selectAll" resultMap="t_user">
select *
from user
</select>
注解形式
@Results( id = "aaa" ,value = {
@Result(id = true ,property = "id",column = "uid"),
@Result(property = "username",column = "uusername"),
@Result(property = "password",column = "upassword")
})
@Select("select * from user")
ArrayList<T_User> selectAll();
/* @ResultMap("aaa") 重用别的方法设置好的resultMap*/
@Select("select * from user")
@ResultMap("aaa")
ArrayList<T_User> selectAll1();
注解在当前方法会直接生效所以第一个书写@Results标签的方法无需设置@ResultMap注解可以直接使用,在当前方法中的其他方法如果想重复使用需要使用@ResultMap(“id”)注解
2.2.8 @One()结果映射一对一注解
语法:@One(select=“执行方法”,fetchType=“加载方式(FetchType.LAZY深入懒加载)”)
one是@Result标签的一个属性,添加后相当于将result标签转换为mapper.xml中的
xml配置形式
<resultMap id="user" type="com.yunhe.vo.User">
<id property="uid" column="uid"/>
<result property="uusername" column="uusername"/>
<result property="upassword" column="upassword"/>
<association property="role" column="uid" select="com.yunhe.mapper.RoleMapper.selectByUid" fetchType="lazy"/>
</resultMap>
<select id="selectAll" resultMap="user">
select * from user
</select>
注解形式
@Results( id = "user" ,value = {
@Result(id = true,property = "uid",column = "uid"),
@Result(property = "uusername",column = "uusername"),
@Result(property = "upassword",column = "upassword"),
@Result(property = "role" ,column = "uid",one =@One(select = "com.yunhe.mapper.RoleMapper.selectByUid",fetchType = FetchType.LAZY))
})
@Select("select * from user")
ArrayList<User> selectAllAndRole();
2.2.9 @Many()注解结果映射一对多注解
语法:@Many(select=“执行方法”,fetchType=“加载方式(FetchType.LAZY深入懒加载)”)
Many是@Result标签的一个属性,添加后相当于将result标签转换为mapper.xml中的
@Results( id = "users" ,value = {
@Result(id = true,property = "uid",column = "uid"),
@Result(property = "uusername",column = "uusername"),
@Result(property = "upassword",column = "upassword"),
@Result(property = "role" ,column = "uid",many =@Many(select = "com.yunhe.mapper.RoleMapper.selectByUids",fetchType = FetchType.LAZY))
})
@Select("select * from user")
ArrayList<Users> selectAllAndRoles();
三、逆向工程
3.1 概念
mybatis可以根据已有的数据库表进行相应的代码生成,为项目的创建书写提供便利,会根据数据库表字段创建对应的实体类,与通用mapper接口以及对应的实现配置,额外提供了对于单表操作动态拼写的相应配置.
3.2 逆向工程创建
(1)创建项目
(2)导入逆向工程jar包与mysql连接jar包
(3)编写生成配置文件
<?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>
<context id="testTables" targetRuntime="MyBatis3">
<commentGenerator>
<!-- 是否去除自动生成的注释 true:是 : false:否 -->
<property name="suppressAllComments" value="true" />
</commentGenerator>
<!--数据库连接的信息:驱动类、连接地址、用户名、密码 -->
<jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/mydb" userId="root"
password="root">
</jdbcConnection>
<!-- targetProject:生成PO类的位置 -->
<javaModelGenerator targetPackage="com.yunhe.pojo"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
<!-- 从数据库返回的值被清理前后的空格 -->
<property name="trimStrings" value="true" />
</javaModelGenerator>
<!-- targetProject:mapper映射文件生成的位置 -->
<sqlMapGenerator targetPackage="com.yunhe.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</sqlMapGenerator>
<!-- targetPackage:mapper接口生成的位置 -->
<javaClientGenerator type="XMLMAPPER"
targetPackage="com.yunhe.mapper"
targetProject="./src">
<!-- enableSubPackages:是否让schema作为包的后缀 -->
<property name="enableSubPackages" value="false" />
</javaClientGenerator>
<!-- 指定数据库表 -->
<table tableName="author"></table>
<table tableName="commodity"></table>
<table tableName="order"></table>
<table tableName="role"></table>
<table tableName="user"></table>
</context>
</generatorConfiguration>
(4)创建类读取配置文件生成代码
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
public class Test {
public static void main(String[] args) throws Exception{
List<String> warnings = new ArrayList<String>();
boolean overwrite = true;
//加载逆向生成配置文件信息
//加载src下的配置文件
InputStream resourceAsStream = Test.class.getClassLoader().getResourceAsStream("gen.xml");
ConfigurationParser cp = new ConfigurationParser(warnings);
//如果加载绝对路径下的配置文件可以将resourceAsStream改为new File(url);
Configuration config = cp.parseConfiguration(resourceAsStream);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);
}
}
3.3 生成代码基本使用
mybatis生成实体类只会生成对应的属性以及gettter与setter方法,构造方法、序列化、toString方法根据实际使用添加
3.3.1 添加
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//添加
User user=new User("新增","1234576");
//insert into user (uid, uusername, upassword ) values (?, ?, ? )
mapper.insert(user);
//insert into user ( uusername, upassword ) values ( ?, ? )
mapper.insertSelective(user);
DEBUG [main] - ==> Preparing: insert into user (uid, uusername, upassword ) values (?, ?, ? )
DEBUG [main] - ==> Parameters: null, 新增(String), 1234576(String)
DEBUG [main] - <== Updates: 1
DEBUG [main] - ==> Preparing: insert into user ( uusername, upassword ) values ( ?, ? )
DEBUG [main] - ==> Parameters: 新增(String), 1234576(String)
DEBUG [main] - <== Updates: 1
3.3.2 修改
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//修改
User user=new User(8,null,"1234576");
//update user set uusername = ?, upassword = ? where uid = ?
mapper.updateByPrimaryKey(user);
//update user SET upassword = ? where uid = ?
mapper.updateByPrimaryKeySelective(user);
DEBUG [main] - ==> Preparing: update user set uusername = ?, upassword = ? where uid = ?
DEBUG [main] - ==> Parameters: null, 1234576(String), 8(Integer)
DEBUG [main] - <== Updates: 1
DEBUG [main] - ==> Preparing: update user SET upassword = ? where uid = ?
DEBUG [main] - ==> Parameters: 1234576(String), 8(Integer)
DEBUG [main] - <== Updates: 1
3.3.3 删除
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//删除
//delete from user where uid = ?
mapper.deleteByPrimaryKey(8);
DEBUG [main] - ==> Preparing: delete from user where uid = ?
DEBUG [main] - ==> Parameters: 8(Integer)
DEBUG [main] - <== Updates: 1
3.3.4 查询
SqlSessionFactory sqlSessionFactory = MyBatisUtil.getSqlSessionFactory();
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//查询
//select uid, uusername, upassword from user where uid = ?
User user = mapper.selectByPrimaryKey(1);
System.out.println(user);
DEBUG [main] - ==> Preparing: select uid, uusername, upassword from user where uid = ?
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <== Total: 1
User{uid=1, uusername='zhangsan', upassword='sadsadsad'}