1、JDBC
JDBC是一种基准,是java连接各大厂商的关系型数据库的接口规范。
/**
*
* @description: JDBC连接MySQL数据库进行CRUD操作
*
* 步骤:
* 1、加载驱动和注册数据库信息。
* 2、打开Connection,获取PreparedStatement对象。
* 3、通过PreparedStatement执行SQL,返回结果到ResultSet对象。
* 4、使用ResultSet读取数据,然后通过代码转换为具体的POJO对象。
* 5、关闭数据库相关资源,先开的后关,后开的先关。
*
*
*/
public class JdbcTest {
private Logger logger = LoggerFactory.getLogger(getClass());
private static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";
private static final String URL = "jdbc://mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8";
private static final String USERNAME = "root";
private static final String PASSWORD = "root";
private Connection getConnection() {
Connection conn = null;
try {
// 加载驱动和注册数据库信息
Class.forName(JDBC_DRIVER);
DriverManager.getConnection(URL, USERNAME, PASSWORD);
} catch (ClassNotFoundException | SQLException e) {
logger.info("Class={JdbcTest.class.getName()} not found", JdbcTest.class.getName(), e);
}
return conn;
}
/**
*
* @description: 保存用户信息
* @param user
* @return
*/
public int save(User user) {
Connection conn = getConnection();
int row = 0;
// 5个问号(占位符)代表5个字段预先要保留的值
String sql = "insert into tb_user (username,password,name,sex,email,tel) values(?,?,?,?,?,?)";
PreparedStatement ps = null;
try {
/**
* 使用PreparedStatement的优点:
* 1、具有预编译功能,相同的SQL语句只需要编译一次,提高执行效率。
* 2、可以防止SQL语句注入,提高安全性
*/
// 使用PreparedStatement对象里来构建并执行SQL语句
ps = conn.prepareStatement(sql);
// 通过PreparedStatement对象里的set方法设置要插入的值
ps.setString(1, user.getUsername());
ps.setString(2, user.getPassword());
ps.setString(3, user.getName());
ps.setInt(4, user.getSex());
ps.setString(5, user.getEmail());
ps.setString(6, user.getTel());
// 返回影响行数
row = ps.executeUpdate();
} catch (SQLException e) {
logger.info("Bad SQL Grammer", e);
} finally {
close(null, ps, conn);
}
return row;
}
/**
*
* @description: 释放资源,注意:先开的后关,后开的先关
* @param rs
* @param ps
* @param conn
*/
public void close(ResultSet rs, PreparedStatement ps, Connection conn) {
try {
if (rs != null && rs.isClosed()) {
rs.close();
}
} catch (SQLException e1) {
e1.printStackTrace();
}
try {
if (ps != null && ps.isClosed()) {
ps.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (conn != null && conn.isClosed()) {
conn.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
JDBC需要自己维护connection,ResultSet,SQL,底层事务;频繁的连接和断开数据库,性能开销还是很大的。
2、hibernate
public class ActivityCouponDao extends GenericDaoHibernate<CouponPool, Long> {
public ActivityCouponDao() {
super(CouponPool.class);
}
/**
* @Author mayutao
* @CreatedDate 2019/8/29
* @Description 根据id进行模糊查询
* @Param id
* @Return List<Map>
*/
public List<Map> queryCouponList(Long id) {
StringBuilder sql = new StringBuilder("select id, coupon_name as name, subhead ");
sql.append(" from coupon_pool ");
sql.append(" where id like :id ");
sql.append(" AND status = 1 ");
sql.append(" AND type_id = 1 ");
sql.append(" order by update_time desc ");
Query query = getReadSession().createSQLQuery(sql.toString()).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
query.setString("id", id.toString() + "%");
return (List<Map>) query.list();
}
/**
* @Author mayutao
* @CreatedDate 2020/1/15
* @Description 模糊查询,分页获取红包数据
* @Param pageable
* @Return Page<CouponPool>
*/
public Page<CouponPool> queryCouponPage(Long couponId, Pageable pageable){
Criteria criteria = getReadSession().createCriteria(CouponPool.class);
if(couponId != null){
criteria.add(Restrictions.eq("id", couponId));
}
criteria.add(Restrictions.eq("isDeleted", false));
criteria.add(Restrictions.eq("status", 1));
criteria.add(Restrictions.eq("typeId", CouponTypeEnum.POLICY_HB.getTypeId()));
Long rowCount = (Long) criteria.setProjection(
Projections.rowCount()).uniqueResult();
criteria.setProjection(null);
criteria.addOrder(Order.desc("updateTime"));
criteria.setFirstResult(pageable.getOffset());
criteria.setMaxResults(pageable.getPageSize());
List data = criteria.list();
return new PageImpl(data, pageable, rowCount == null ? 0 : rowCount);
}
}
hibernate是ORM框架,ORM框架是使得数据库的访问转变成对对象的访问,将关注点转向业务,简化SQL编写。
hibernate的优势,对JDBC的代码进行了封装,使我们的编程更简便了,不用写SQL语句,提高了开发效率。消除了代码的映射规则,也无需在管理数据库连接,全部被分离到了XML或注解里面去配置。一个会话中,不需要操作多个对象,只要操作Session即可,关闭资源也只要关闭一个Session即可,不用频繁开启关闭数据库连接。当然在Spring的集成使用下这些都会交由Spring来管理,使用更加方便。
hibernate的优势, 当我们更新时将发送所有的字段,而当我们查询时它也会将我们不想要查询的字段也查询出来(部分查询方式),这即是全表映射所带来的麻烦。hibernate并不能很好的支持存储过程,一大遗憾。对多表关联和复杂SQL查询支持稍差,还是要自己写SQL语句,返回的结果,需要自己组装为POJO。虽然hibernate使用的是HQL语言查询,但是性能不高。而当我们的数据量很大或是大型系统时,必定需要优化SQL语句。由于hibernate的高门槛,要完全掌握并不简单,所以对于一个开始并不熟悉hibernate开发的人,学习时间稍长,开发速度稍慢。
3、MyBatis
mybatis是一个半自动化的框架,何谓半自动,因为它需要手工编写POJO、SQL和映射关系。
public interface UserMapper {
/**
* 新增用戶
* @param user
* @return
* @throws Exception
*/
public int insertUser(UserBean user) throws Exception;
/**
* 修改用戶
* @param user
* @param id
* @return
* @throws Exception
*/
public int updateUser (UserBean user,int id) throws Exception;
/**
* 刪除用戶
* @param id
* @return
* @throws Exception
*/
public int deleteUser(int id) throws Exception;
/**
* 根据id查询用户信息
* @param id
* @return
* @throws Exception
*/
public UserBean selectUserById(int id) throws Exception;
/**
* 查询所有的用户信息
* @return
* @throws Exception
*/
public List<UserBean> selectAllUser() throws Exception;
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.cy.mybatis.mapper.UserMapper">
<!-- 自定义返回结果集 -->
<resultMap id="userMap" type="UserBean">
<id property="id" column="id" javaType="java.lang.Integer"></id>
<result property="username" column="username" javaType="java.lang.String"></result>
<result property="password" column="password" javaType="java.lang.String"></result>
<result property="account" column="account" javaType="java.lang.Double"></result>
</resultMap>
<!-- 在各种标签中的id属性必须和接口中的方法名相同 , id属性值必须是唯一的,不能够重复使用。parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型-->
<!-- useGeneratedKeys:( 仅 对 insert 有 用 ) 这 会 告 诉 MyBatis 使 用 JDBC 的getGeneratedKeys
方法来取出由数据(比如:像 MySQL 和 SQLServer 这样的数据库管理系统的自动递增字段)内部生成的主键。默认值: false。 -->
<!--keyProperty: (仅对 insert有用)标记一个属性, MyBatis 会通过 getGeneratedKeys或者通过 insert 语句的 selectKey 子元素设置它的值。默认:不设置。 -->
<!--#{}中的内容,为占位符,当参数为某个JavaBean时,表示放置该Bean对象的属性值 -->
<insert id="insertUser" useGeneratedKeys="true" keyProperty="id">
insert into t_user (username,password,account) values (#{username},#{password},#{account})
</insert>
<update id="updateUser" >
update t_user set username=#{username},password=#{password},account=#{account} where id=#{id}
</update>
<delete id="deleteUser" parameterType="int">
delete from t_user where id=#{id}
</delete>
<select id="selectUserById" parameterType="int" resultMap="userMap">
select * from t_user where id=#{id}
</select>
<select id="selectAllUser" resultMap="userMap">
select * from t_user
</select>
</mapper>
MyBatis可以自定义一些复杂的SQL和自定对象,对于大厂对SQL管理严格的项目,Mybatis比较合适。