上一节中主要介绍了mybatis的工作流程,并且完成了一个简单的实践。这一节将系统的介绍下持久层框架的基础操作:增删改+基础查询两部分内容。
开发目录:
表设计:
一、mybatis中与数据库交互的原理
在软件开发中,抛开边边框框的修饰,最核心的东西就是用户与数据库。
这里只介绍最基础的增删改查,满足入门级需求。反复练习掌握基础的增删改查是后续复杂操作的基础。
二、增删改操作
1.增:添加一条数据
代码:(map映射文件中:user.xml)
<!-- 插入一条数据 -->
<insert id="insertUser" parameterType="User"
statementType="PREPARED" keyProperty="pid" useGeneratedKeys="true">
insert into Person(Name,Pass) values(#{username,jdbcType=VARCHAR},#{password,jdbcType=VARCHAR})
</insert>
测试代码:(test1.java)
public static void main(String[] args) {
String resource = "book/map/mybatisconfig.xml"; //基本配置文件的路径
Reader reader = null;//建立输入流
try {
reader = Resources.getResourceAsReader(resource);//mybatis自带的API方法
} catch (IOException e) {
e.printStackTrace();
}
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);//通过读取流从而读取基本配置文件
SqlSession session = sqlMapper.openSession();//通过SqlSessionFactory对象创建SqlSession对象
try {
//添加一条数据
User user = new User();
user.setPassword("333");
user.setUsername("DK_3");
session.insert("insertUser", user);
session.commit(); //这句话要加上
} catch (Exception e) {
e.printStackTrace();
}finally {
session.close();
}
}
上面代码简单介绍:
1)id--是这条sql语句的唯一标识符,在java代码中通过索引这个id找到这条sql语句;
2)parameterType--传入参数。在添加数据中,通常是添加一个实体类对象,这里本来应该写的是完整路径,即包括包名,类名...但这里简写为User是因为在mybatisconfig.xml里配置了别名,具体可参照:
3)statementType--这里的值是PREPARED,表示预编译,简单讲就是这里要传入参数,还不知道传什么,就先占个位置。这个属性可以不写;
4)keyProperty--设置主键,这里的'pid'是数据库中表的主键名;
5)useGeneratedKeys--与上一个一起出现,值为'true'表示主键自增,这两个属性通常也不写,因为在设计表中通常都已经设置主键自增了;
6)insert into Person(Name,Pass)--这里的Person是数据库中的表名,Name和Pass是表中的字段名,这里用的是mysql数据库,对大小写没要求;
7)#{username,jdbcType=VARCHAR}--这里的username是传入参数的那个实体类中的属性名,#{}这个符号相当于一个占位符,里面放上传参的具体属性
jdbcType=VARCHAR--这句话意思是数据库表中字段的数据类型,由于username在实体类中是String类型,所以到表中定义为VARCHAR类型,通常不写。
常见问题总结:
1)在eclipse里提交,log4j也把sql语句打印出来都正确,但数据库里并未更新数据。
解决方法:session没有提交,添加session.commit();
2)运行报错时,往两个方面检查。一是map映射文件写的有没有问题,例如:要传入参数,但statementType设置的值是STATEMENT;二是数据库表设计的问题,如:主键是否设置了自增。
2.删:删除一条数据
代码:(map映射文件中:user.xml)
<delete id="deleteUser" parameterType="int">
delete from person where pid=#{id}
</delete>
测试代码:(test.java) 在try..catch中写这段代码
session.delete("deleteUser", 3);
session.commit(); //这句话要加上
上面代码简单介绍:
1)删除一条数据,通常也需要传入参数,参数类型是个int类型的主键居多;
2)user.xml中pid=#{id}这里的id可以任意写,因为此处表达的意思就是一个占位的作用,具体的值的类型是int类型,值是测试代码中session.delete("deleteUser",3);中的3,只是mybatis自带的api写法。
3.改:更改一条数据
代码:(map映射文件中:user.xml)
<!-- 更新一条数据 -->
<update id="updateUser" parameterType="User">
update person set name=#{username},pass=#{password} where pid=#{id}
</update>
测试代码:(test.java) 在try..catch中写这段代码
User user2 = new User();
user2.setId(5);
user2.setUsername("DK_5");
user2.setPassword("555");
session.update("updateUser", user2);
session.commit(); //这句话要加上
多练习几遍熟练步骤。不知道你有没有运行成功,反正我是成功了~~~~
三、基础查询
为什么将查询与上面三个分为两部分讲解,原因如下:
1)前面三个增删改只需要传入参数,而查询语句最终是要返回参数的;
2) 前面三个比较单一,而查询语句相对来说更加复杂,如返回一个对象,返回一个集合,对数据进行分页再返回等等。
1.返回一条数据
代码:(map映射文件中:user.xml)
<!-- 查询一条数据 -->
<select id="selectById" parameterType="int" resultType="User">
select * from person where id=#{id}
</select>
测试代码:(test.java) 在try..catch中写这段代码
//查询一条语句
User user3 = session.selectOne("selectById", 4);
System.out.println(user3.toString());
session.commit(); //这句话要加上
上面代码简单介绍:
1)这里是通过id来查询一条数据,查完后自然要返回一个对象,所以在测试代码中需要new一个对象去接收它;
2)查询一条数据用到的api方法是:selectOne(String,Object);
3)在测试的过程中,你可能会发现toString()并不能把对象的属性名给打印出来?
原因:
resultType=“User”--这句话的意思是返回参数是User实体类,这就要求当数据库中字段名和实体类中属性名一一对应时才有返回值。也就是数据库中主键字段是pid,那么实体类中那个属性名也要改成pid,数据库中字段是username,实体类中也要是username,只有这样,才有返回值,toString才能打印出来东西。
当然,这是最基本的查询,你可能觉得实际工程中不可能每一个实体类都和表一一对应,简单的联表查询时怎么办,这时只需要将resultType改成resultMap,再进行相应的属性配置即可解决,这个在后面会一起讨论。
2.返回一个集合
代码:(map映射文件中:user.xml)
<!-- 查询一个集合 -->
<select id="selectList" resultType="User">
select * from person
</select>
测试代码:(test.java) 在try..catch中写这段代码
//查询一个集合
List<User> list = session.selectList("selectList");
for(User user4:list){
System.out.println(user4.toString());
}
session.commit(); //这句话要加上
上面代码简单介绍:
1)查询集合的api方法是:selectList(String);
2)跟查询一条数据一样,简单查询需要表中字段和实体类中属性名一一对应,复杂查询在后面会介绍到。