转载注明出处
前两天学习了mybatis连接数据库,实现增删查改,和前面的文章JDBC实现增删查改有异曲同工之妙,在此记录,遗忘的时候翻一翻。
首先,还是建项目,什么项目?maven项目,不讲了,去翻前面的文章。
直接贴项目结构
然后是导入jar包
mybatis包是一定要的;mqsql-connector-java也是必须的;junit包就更不用说了;还有1.8的包就不提了,建完项目就有。
这里我使用了mybatis的两种方法,一种就是和JDBC差不多的,利用dao层和它的实现类来完成增删查改。不过多讲解,直接贴代码。
记得先在数据库建表!
一、DAO层实现
User.java
package mybatis.po; import java.sql.Date; /** * Created by Administrator on 2017/07/07. */ public class User { private Integer id; private String username; private Date birthday; private String sex; private String address; public int getId(){return id;} public void setId(Integer id){this.id = id;} public User(Integer id,String username, Date birthday, String sex, String address) { this.id = id; this.username = username; this.birthday = birthday; this.sex = sex; this.address = address; } public User(String username, Date birthday, String sex, String address) { this.username = username; this.birthday = birthday; this.sex = sex; this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
然后是
UserDao.java
package mybatis.po; import java.util.List; /** * Created by Administrator on 2017/07/07. */ public interface UserDao { //根据id查询用户信息 public User findUserById(int id) throws Exception; //根据用户名模糊查询 public List<User> findUserByName(String name) throws Exception; //添加用户信息 public void insertUser(User user) throws Exception; //删除用户信息 public void deleteUser(int id) throws Exception; //更新用户信息 public void updateUser(User user) throws Exception; }
再然后是
UserDaoImpl.java
package mybatis.po; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; /** * Created by Administrator on 2017/07/07. */ public class UserDaoImpl implements UserDao{ private SqlSessionFactory sqlSessionFactory; //需要向dao实现类中注入SqlSessionFactory,由于没和Spring整合,这里通过构造函数注入 public UserDaoImpl(SqlSessionFactory sqlSessionFactory) { this.sqlSessionFactory = sqlSessionFactory; } @Override public User findUserById(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); User user = sqlSession.selectOne("test.findUserById", id); //释放资源 sqlSession.close(); return user; } @Override public List<User> findUserByName(String name) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); List<User> list = sqlSession.selectList("test.findUserByName", name); //释放资源 sqlSession.close(); return list; } @Override public void insertUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.insert("test.insertUser", user); sqlSession.commit();//执行插入要先commit sqlSession.close(); } @Override public void deleteUser(int id) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.delete("test.deleteUser", id); sqlSession.commit();//执行插入要先commit sqlSession.close(); } @Override public void updateUser(User user) throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); sqlSession.update("test.updateUser", user); sqlSession.commit();//执行插入要先commit sqlSession.close(); } }
User.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="test"> <!-- 需求:通过id查询用户 --> <select id="findUserById" parameterType="int" resultType="mybatis.po.User"> select * from user where id = #{id} </select> <!-- 根据用户名称模糊查询用户信息,可能返回多条 --> <select id="findUserByName" parameterType="java.lang.String" resultType="mybatis.po.User"> select * from user where username like '%${value}%' <!-- ${}:表示拼接sql串,将接收到的参数的内容不加任何的修饰拼接在sql中,${}中只能使用value, 但是使用${}来拼接sql,可能会引起sql注入,所以不建议使用这种方法。 --> </select> <!-- 添加用户 --> <insert id="insertUser" parameterType="mybatis.po.User"> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) <!-- 将插入数据的主键返回,返回到user对象中 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select last_insert_id() </selectKey> <!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> select uuid() </selectKey> --> <!-- 1 <insert>标签:用于执行数据库查询的,所有关于查询的都使用该标签。 2 parameterType:要传入一个具体的pojo(包括用户信息) 3 #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值。 4 <selectKey>标签:用来返回插入数据的主键的,实际中如果有获得主键的需要就可以使用它。 5 select last_insert_id():是sql函数,表示得到刚刚insert进去记录的主键值,只适用于自增主键。 6 keyProperty:表示将查询到主键值设置到上面parameterType指定的对象的哪个属性。 7 order:表示select last_insert_id()的执行顺序,是相对于insert语句来说的。 8 resultType:表示select last_insert_id()的结果类型。 --> </insert> <!-- 删除用户 --> <delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id=#{id} </delete> <!-- 更新用户 --> <update id="updateUser" parameterType="mybatis.po.User"> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> </mapper>
SqlMapConfig.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> <typeAliases> </typeAliases> <!-- 和Spring整合后environment配置都会被干掉 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理,目前由mybatis来管理 --> <transactionManager type="JDBC" /> <!-- 数据库连接池,目前由mybatis来管理 --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mybatis" /> <property name="username" value="root" /> <property name="password" value="yubotao9527" /> </dataSource> </environment> </environments> <mappers> <mapper resource="User.xml" /> <mapper resource="UserMapper.xml"/> </mappers> </configuration>
log4j.properties日志生成文件
# Global logging configuration # developer-->DEBUG productor-->INFO or ERROR log4j.rootLogger=DEBUG, stdout # MyBatis logging configuration... log4j.logger.org.mybatis.example.BlogMapper=TRACE # Console output... log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
最后的测试
UserDaoImplTest.java
import mapper.UserMapper; import mybatis.po.User; import mybatis.po.UserDao; import mybatis.po.UserDaoImpl; 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.Before; import org.junit.Test; import java.io.InputStream; import java.util.List; /** * Created by Administrator on 2017/07/07. */ public class UserDaoImplTest { private SqlSessionFactory sqlSessionFactory; @Before public void setUp() throws Exception { //创建sqlSessionFactory String resource = "SqlMapConfig.xml"; //mybatis配置文件 //得到配置文件的流 InputStream inputStream = Resources.getResourceAsStream(resource); //创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流 sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); } @Test public void testFindUserById() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); User user = userMapper.findUserById(1); System.out.println(user); } @Test public void testFindUserByName() throws Exception { SqlSession sqlSession = sqlSessionFactory.openSession(); //创建UserMapper对象,mybatis自动生成mapper代理对象 UserMapper userMapper = sqlSession.getMapper(UserMapper.class); List<User> list = userMapper.findUserByName("倪升武"); sqlSession.close(); System.out.println(list); } }
到此,使用DAO层完成mybatis实现增删查改就完成了
接下来讲第二种方法
二、Mapper
User.java
同上
<?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.UserMapper"> <!-- 需求:通过id查询用户 --> <select id="findUserById" parameterType="int" resultType="mybatis.po.User"> select * from user where id = #{id} </select> <!-- 根据用户名称模糊查询用户信息,可能返回多条 --> <select id="findUserByName" parameterType="java.lang.String" resultType="mybatis.po.User"> select * from user where username like '%${value}%' <!-- ${}:表示拼接sql串,将接收到的参数的内容不加任何的修饰拼接在sql中,${}中只能使用value, 但是使用${}来拼接sql,可能会引起sql注入,所以不建议使用这种方法。 --> </select> <!-- 添加用户 --> <insert id="insertUser" parameterType="mybatis.po.User"> insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address}) <!-- 将插入数据的主键返回,返回到user对象中 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> select last_insert_id() </selectKey> <!-- <selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String"> select uuid() </selectKey> --> <!-- 1 <insert>标签:用于执行数据库查询的,所有关于查询的都使用该标签。 2 parameterType:要传入一个具体的pojo(包括用户信息) 3 #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值。 4 <selectKey>标签:用来返回插入数据的主键的,实际中如果有获得主键的需要就可以使用它。 5 select last_insert_id():是sql函数,表示得到刚刚insert进去记录的主键值,只适用于自增主键。 6 keyProperty:表示将查询到主键值设置到上面parameterType指定的对象的哪个属性。 7 order:表示select last_insert_id()的执行顺序,是相对于insert语句来说的。 8 resultType:表示select last_insert_id()的结果类型。 --> </insert> <!-- 删除用户 --> <delete id="deleteUser" parameterType="java.lang.Integer"> delete from user where id=#{id} </delete> <!-- 更新用户 --> <update id="updateUser" parameterType="mybatis.po.User"> update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id} </update> </mapper>
主配置文件Configure.xml
这里和上面的一样
主配置文件中就不需要UserMapper.xml的关联了。
最后是测试
MybatisFirst.java
import mybatis.po.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; import java.sql.Date; import java.util.List; /** * Created by Administrator on 2017/07/07. */ public class MybatisFirst { //因为接下来的测试代码中,获取sqlSession这部分都相同,所以抽取成一个方法 public SqlSession getSession() throws IOException { String resource = "SqlMapConfig.xml"; //mybatis配置文件 //得到配置文件的流 InputStream inputStream = Resources.getResourceAsStream(resource); //创建会话工厂SqlSessionFactory,要传入mybaits的配置文件的流 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); //通过工厂得到SqlSession SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } //根据id查询用户的信息,得到一条记录的结果 @Test public void findUserById() throws IOException { SqlSession sqlSession = getSession(); //调用上面的方法获取sqlSession //通过SqlSession操作数据库 //第一个参数:映射文件中statement的id,= namespace + statement的id //第二个参数:指定和映射文件中所匹配的parameterType类型的参数 //selectOne表示查询出一条记录进行映射 User user = sqlSession.selectOne("test.findUserById", 1); System.out.println(user); //释放资源,最好放在finally中,这里只是测试程序,就不弄了 sqlSession.close(); } //根据用户名称模糊查询用户列表 @Test public void findUserByName() throws IOException { SqlSession sqlSession = getSession(); //selectList表示查询出一个列表(多条记录)进行映射 List<User> list = sqlSession.selectList("test.findUserByName", "张三"); System.out.println(list); //释放资源,最好放在finally中,这里只是测试程序,就不弄了 sqlSession.close(); } //添加用户信息 @Test public void insertUser() throws IOException { SqlSession sqlSession = getSession(); User user = new User("倪升武", new Date(1995,07,02), "男", "同济大学"); sqlSession.insert("test.insertUser", user); //添加一项 //提交事务 sqlSession.commit(); System.out.println(user.getId()); //获取刚刚添加的id //释放资源,最好放在finally中,这里只是测试程序,就不弄了 sqlSession.close(); } //删除用户信息 @Test public void deleteUser() throws IOException { SqlSession sqlSession = getSession(); //传入id,删除用户 sqlSession.delete("test.deleteUser", 3); //提交事务 sqlSession.commit(); //释放资源,最好放在finally中,这里只是测试程序,就不弄了 sqlSession.close(); } //更新用户信息 @Test public void updateUser() throws IOException { SqlSession sqlSession = getSession(); User user = new User("倪升武", new Date(0,0,0), "男", "同济大学"); user.setId(2); //更新用户 sqlSession.update("test.updateUser", user); //提交事务 sqlSession.commit(); //释放资源,最好放在finally中,这里只是测试程序,就不弄了 sqlSession.close(); } }
最后,完成这些结果后,我们回顾一下
这里面出现了许多没见过的东西,比如:
SqlSession和SqlSessionFactory
这个SQLSession对应一次数据库的对话,也就是说你的增删查改语句都是通过它来传递给数据库的;是不是感觉和前面的PreparedStatement有点像?反正我感觉像!
SqlSessionFactory就是SqlSession的工厂,通过SqlSessionFactory.openSession()方法来创建SqlSession对象。
其他的地方都有相应注解,就不一一解释了。
三、Annotation注解
package dao; import domain.Student; import org.apache.ibatis.annotations.Delete; import org.apache.ibatis.annotations.Insert; import org.apache.ibatis.annotations.Select; import org.apache.ibatis.annotations.Update; /** * Created by Administrator on 2017/07/19. */ public interface Annotation { @Select("select * from businesstable where ID = #{ID}") public Student selectById(Integer ID); @Delete(" delete from businesstable where ID = #{ID}") public void deleteById(Integer ID); @Insert(" insert into businesstable(SName,QQ,Style,Time,School,SNumber,Link,Dream,FBro,YBro,WhereKnow,create_at)\n" + " values(#{SName},#{QQ},#{Style},#{Time},#{School},#{SNumber},#{Link},#{Dream},#{FBro},#{YBro},#{WhereKnow},#{create_at})") public void insertStu(Student stu); @Update("update businesstable set SName=#{SName},QQ=#{QQ},Style=#{Style},Time=#{Time},School=#{School},SNumber=#{SNumber},\n" + " Link=#{Link},Dream=#{Dream},FBro=#{FBro},YBro=#{YBro},WhereKnow=#{WhereKnow},update_at=#{update_at} where ID=#{ID}") public void updateStu(Student stu); }其他就不变,注解的方法就是这个样子
import dao.Annotation; import domain.Student; 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; /** * Created by Administrator on 2017/07/19. */ public class AnnotationTest { public SqlSession getSession() throws IOException { String resource = "Configure.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream); SqlSession sqlSession = sqlSessionFactory.openSession(); return sqlSession; } @Test public void selectStudent() throws IOException { SqlSession sqlSession = getSession(); Annotation ant = sqlSession.getMapper(Annotation.class); Student stu = ant.selectById(2); System.out.println(stu); sqlSession.close(); } @Test public void insertStudent() throws IOException{ SqlSession sqlSession = getSession(); Student stu = new Student("s",22,"dsfa","20170705",null,null, null,null,null,null,null,null,20170707,null); Annotation ant = sqlSession.getMapper(Annotation.class); ant.insertStu(stu); sqlSession.commit(); sqlSession.close(); } @Test public void deleteStudent() throws IOException{ SqlSession sqlSession = getSession(); Annotation ant = sqlSession.getMapper(Annotation.class); ant.deleteById(18); sqlSession.commit(); sqlSession.close(); } @Test public void updateStudent() throws IOException{ SqlSession sqlSession = getSession(); Student stu = new Student("s",22,"dsfa","20170705",null,null, null,null,null,null,null,null,null,20170707); stu.setID(3); Annotation ant = sqlSession.getMapper(Annotation.class); ant.updateStu(stu); sqlSession.commit(); sqlSession.close(); } }
最后总结:mybatis就是讲sql的增删查改语句配置到.xml文件(或注解接口)中,这就是和JDBC比较的优势了,不必在代码实现的时候考虑如何实现这些sql语句,还要考虑连接等等。总的来说,就是简单了,改sql语句直接去配置文件(或注解接口)中改就好了!
log4j.properties文件就是个打日志的,原理我也不是很清楚,百度下把,可能以后会更和它相关的文章。